diff --git a/0001-Sw64-Port-add-configure-support-for-sw64.patch b/0001-Sw64-Port-add-configure-support-for-sw64.patch new file mode 100644 index 0000000000000000000000000000000000000000..a2e9f8638cec5d99d63b70d4955a795ba3986505 --- /dev/null +++ b/0001-Sw64-Port-add-configure-support-for-sw64.patch @@ -0,0 +1,703 @@ +From 64050ef082f7f3af78cc136c17c995d62cec14b5 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:25:58 +0800 +Subject: [PATCH 01/16] Sw64 Port: add configure support for sw64 + +--- + Makefile.in | 1 + + Makefile.tpl | 1 + + config.guess | 12 ++++ + config.sub | 1 + + config/intdiv0.m4 | 2 +- + config/mt-sw_64ieee | 3 + + config/tcl.m4 | 6 ++ + configure | 16 ++++- + configure.ac | 19 +++++- + contrib/config-list.mk | 1 + + gcc/config.gcc | 35 +++++++++++ + gcc/config.host | 8 +++ + gcc/config.in | 17 +++++ + gcc/config/host-linux.cc | 2 + + gcc/configure | 131 ++++++++++++++++++++++++++++++++++++++- + gcc/configure.ac | 84 ++++++++++++++++++++++++- + gcc/doc/install.texi | 9 +++ + 17 files changed, 342 insertions(+), 6 deletions(-) + create mode 100644 config/mt-sw_64ieee + +diff --git a/Makefile.in b/Makefile.in +index 7785b3d9a..283c16c4e 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -707,6 +707,7 @@ all: + @target_makefile_frag@ + @alphaieee_frag@ + @ospace_frag@ ++@sw_64ieee_frag@ + @host_makefile_frag@ + ### + +diff --git a/Makefile.tpl b/Makefile.tpl +index ef58fac2b..d629bca8b 100644 +--- a/Makefile.tpl ++++ b/Makefile.tpl +@@ -630,6 +630,7 @@ all: + @target_makefile_frag@ + @alphaieee_frag@ + @ospace_frag@ ++@sw_64ieee_frag@ + @host_makefile_frag@ + ### + +diff --git a/config.guess b/config.guess +index 1972fda8e..0275a0ef8 100755 +--- a/config.guess ++++ b/config.guess +@@ -1101,6 +1101,18 @@ EOF + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ SW6) UNAME_MACHINE=sw_64sw6 ;; ++ SW6A) UNAME_MACHINE=sw_64sw6a ;; ++ SW6B) UNAME_MACHINE=sw_64sw6b ;; ++ SW8A) UNAME_MACHINE=sw_64sw8a ;; ++ SW) UNAME_MACHINE=sw_64 ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; +diff --git a/config.sub b/config.sub +index 38f3d037a..70ff2e6e4 100755 +--- a/config.sub ++++ b/config.sub +@@ -1262,6 +1262,7 @@ case $cpu-$vendor in + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ ++ | sw_64 | sw_64sw6a | sw_64sw6b | sw_64sw8a \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ +diff --git a/config/intdiv0.m4 b/config/intdiv0.m4 +index 55dddcf1c..bfe1bdcdf 100644 +--- a/config/intdiv0.m4 ++++ b/config/intdiv0.m4 +@@ -56,7 +56,7 @@ int main () + [ + # Guess based on the CPU. + case "$host_cpu" in +- alpha* | i[34567]86 | m68k | s390*) ++ alpha* | i[34567]86 | m68k | s390* | sw_64*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; +diff --git a/config/mt-sw_64ieee b/config/mt-sw_64ieee +new file mode 100644 +index 000000000..80c17cdc6 +--- /dev/null ++++ b/config/mt-sw_64ieee +@@ -0,0 +1,3 @@ ++CFLAGS_FOR_TARGET += -mieee ++CXXFLAGS_FOR_TARGET += -mieee ++GOCFLAGS_FOR_TARGET += -mieee +diff --git a/config/tcl.m4 b/config/tcl.m4 +index 4542a4b23..c58bf5343 100644 +--- a/config/tcl.m4 ++++ b/config/tcl.m4 +@@ -1368,6 +1368,9 @@ dnl AC_CHECK_TOOL(AR, ar) + if test "`uname -m`" = "alpha" ; then + CFLAGS="$CFLAGS -mieee" + fi ++ if test "`uname -m`" = "sw_64" ; then ++ CFLAGS="$CFLAGS -mieee" ++ fi + if test $do64bit = yes; then + AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ + hold_cflags=$CFLAGS +@@ -1418,6 +1421,9 @@ dnl AC_CHECK_TOOL(AR, ar) + if test "`uname -m`" = "alpha" ; then + CFLAGS="$CFLAGS -mieee" + fi ++ if test "`uname -m`" = "sw_64" ; then ++ CFLAGS="$CFLAGS -mieee" ++ fi + ;; + Lynx*) + SHLIB_CFLAGS="-fPIC" +diff --git a/configure b/configure +index aff62c464..1b7c11292 100755 +--- a/configure ++++ b/configure +@@ -789,6 +789,7 @@ ac_subst_files='serialization_dependencies + host_makefile_frag + target_makefile_frag + alphaieee_frag ++sw_64ieee_frag + ospace_frag' + ac_user_opts=' + enable_option_checking +@@ -4016,6 +4017,10 @@ case "${target}" in + use_gnu_ld=no + fi + ;; ++ sw_64*-*-*) ++ # newlib is not 64 bit ready ++ noconfigdirs="$noconfigdirs target-newlib target-libgloss" ++ ;; + tic6x-*-*) + noconfigdirs="$noconfigdirs sim" + ;; +@@ -9584,6 +9589,15 @@ case $target in + ;; + esac + ++sw_64ieee_frag=/dev/null ++case $target in ++ sw_64*-*-*) ++ # This just makes sure to use the -mieee option to build target libs. ++ # This should probably be set individually by each library. ++ sw_64ieee_frag="config/mt-sw_64ieee" ++ ;; ++esac ++ + # If --enable-target-optspace always use -Os instead of -O2 to build + # the target libraries, similarly if it is not specified, use -Os + # on selected platforms. +@@ -10299,7 +10313,7 @@ case "${target}" in + esac + + # Makefile fragments. +-for frag in host_makefile_frag target_makefile_frag alphaieee_frag ospace_frag; ++for frag in host_makefile_frag target_makefile_frag alphaieee_frag sw_64ieee_frag ospace_frag; + do + eval fragval=\$$frag + if test $fragval != /dev/null; then +diff --git a/configure.ac b/configure.ac +index f310d75ca..c4a65a49d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1271,6 +1271,10 @@ case "${target}" in + use_gnu_ld=no + fi + ;; ++ sw_64*-*-*) ++ # newlib is not 64 bit ready ++ noconfigdirs="$noconfigdirs target-newlib target-libgloss" ++ ;; + tic6x-*-*) + noconfigdirs="$noconfigdirs sim" + ;; +@@ -1335,6 +1339,9 @@ case "${host}" in + rs6000-*-aix*) + host_makefile_frag="config/mh-ppc-aix" + ;; ++ sw_64*-linux*) ++ host_makefile_frag="config/mh-sw_64-linux" ++ ;; + esac + fi + +@@ -2765,6 +2772,15 @@ case $target in + ;; + esac + ++sw_64ieee_frag=/dev/null ++case $target in ++ sw_64*-*-*) ++ # This just makes sure to use the -mieee option to build target libs. ++ # This should probably be set individually by each library. ++ sw_64ieee_frag="config/mt-sw_64ieee" ++ ;; ++esac ++ + # If --enable-target-optspace always use -Os instead of -O2 to build + # the target libraries, similarly if it is not specified, use -Os + # on selected platforms. +@@ -3475,7 +3491,7 @@ case "${target}" in + esac + + # Makefile fragments. +-for frag in host_makefile_frag target_makefile_frag alphaieee_frag ospace_frag; ++for frag in host_makefile_frag target_makefile_frag alphaieee_frag ospace_frag sw_64ieee_frag; + do + eval fragval=\$$frag + if test $fragval != /dev/null; then +@@ -3486,6 +3502,7 @@ AC_SUBST_FILE(host_makefile_frag) + AC_SUBST_FILE(target_makefile_frag) + AC_SUBST_FILE(alphaieee_frag) + AC_SUBST_FILE(ospace_frag) ++AC_SUBST_FILE(sw_64ieee_frag) + + # Miscellanea: directories, flags, etc. + AC_SUBST(RPATH_ENVVAR) +diff --git a/contrib/config-list.mk b/contrib/config-list.mk +index e04210556..730a49e64 100644 +--- a/contrib/config-list.mk ++++ b/contrib/config-list.mk +@@ -96,6 +96,7 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \ + sparc64-sun-solaris2.11OPT-with-gnu-ldOPT-with-gnu-asOPT-enable-threads=posix \ + sparc-wrs-vxworks sparc64-elf sparc64-rtems sparc64-linux sparc64-freebsd6 \ + sparc64-netbsd sparc64-openbsd \ ++ sw_64-linux-gnu sw_64-netbsd sw_64-openbsd \ + tilegx-linux-gnuOPT-enable-obsolete tilegxbe-linux-gnuOPT-enable-obsolete \ + tilepro-linux-gnuOPT-enable-obsolete \ + v850e1-elf v850e-elf v850-elf v850-rtems vax-linux-gnu \ +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 23c5bee2b..d55645381 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -547,6 +547,10 @@ sh[123456789lbe]*-*-* | sh-*-*) + extra_options="${extra_options} fused-madd.opt" + extra_objs="${extra_objs} sh_treg_combine.o sh-mem.o sh_optimize_sett_clrt.o" + ;; ++sw_64*-*-*) ++ cpu_type=sw_64 ++ extra_options="${extra_options} g.opt" ++ ;; + v850*-*-*) + cpu_type=v850 + ;; +@@ -3471,6 +3475,11 @@ sparc64-*-openbsd*) + with_cpu=ultrasparc + tmake_file="${tmake_file} sparc/t-sparc" + ;; ++sw_64*-*-linux*) ++ tm_file="elfos.h ${tm_file} sw_64/gnu-user.h sw_64/elf.h sw_64/linux.h sw_64/linux-elf.h glibc-stdint.h" ++ tmake_file="${tmake_file} sw_64/t-linux sw_64/t-sw_64" ++ extra_options="${extra_options} sw_64/elf.opt" ++ ;; + tic6x-*-elf) + tm_file="elfos.h ${tm_file} c6x/elf-common.h c6x/elf.h" + tm_file="${tm_file} tm-dwarf2.h newlib-stdint.h" +@@ -3999,6 +4008,15 @@ if test x$with_cpu = x ; then + ;; + esac + ;; ++ sw_64sw6a*-*-*) ++ with_cpu=sw6a ++ ;; ++ sw_64sw6b*-*-*) ++ with_cpu=sw6b ++ ;; ++ sw_64sw8a*-*-*) ++ with_cpu=sw8a ++ ;; + visium-*-*) + with_cpu=gr5 + ;; +@@ -5571,6 +5589,23 @@ case "${target}" in + esac + ;; + ++ sw_64*-*-*) ++ supported_defaults="cpu tune" ++ for which in cpu tune; do ++ eval "val=\$with_$which" ++ case "$val" in ++ "" \ ++ | sw6 | sw6a | sw6b | sw8a \ ++ | sw6c) ++ ;; ++ *) ++ echo "Unknown CPU used in --with-$which=$val" 1>&2 ++ exit 1 ++ ;; ++ esac ++ done ++ ;; ++ + tic6x-*-*) + supported_defaults="arch" + +diff --git a/gcc/config.host b/gcc/config.host +index bf7dcb4cc..081ce29c2 100644 +--- a/gcc/config.host ++++ b/gcc/config.host +@@ -198,6 +198,14 @@ case ${host} in + ;; + esac + ;; ++ sw_64*-*-linux*) ++ case ${target} in ++ sw_64*-*-linux*) ++ host_extra_gcc_objs="driver-sw_64.o" ++ host_xmake_file="${host_xmake_file} sw_64/x-sw_64" ++ ;; ++ esac ++ ;; + esac + + # Machine-specific settings. +diff --git a/gcc/config.in b/gcc/config.in +index 91328572b..caf0d6492 100644 +--- a/gcc/config.in ++++ b/gcc/config.in +@@ -205,6 +205,11 @@ + #undef ENABLE_LD_BUILDID + #endif + ++/* Define if gcc should always pass --no-relax to linker for sw_64. */ ++#ifndef USED_FOR_TARGET ++#undef ENABLE_LD_NORELAX ++#endif ++ + + /* Define to 1 to enable libquadmath support */ + #ifndef USED_FOR_TARGET +@@ -422,6 +427,10 @@ + #undef HAVE_AS_EXPLICIT_RELOCS + #endif + ++/* Define if your assembler supports explicit relocations. */ ++#ifndef USED_FOR_TARGET ++#undef SW_64_ENABLE_ASAN ++#endif + + /* Define if your assembler supports FMAF, HPC, and VIS 3.0 instructions. */ + #ifndef USED_FOR_TARGET +@@ -2726,3 +2735,11 @@ + #undef vfork + #endif + ++/* Define only sw64 target */ ++#undef FLAG_SW64_ATOMIC ++#undef FLAG_SW64_90139 ++#undef FLAG_SW64_PREFETCH ++#undef FLAG_SW64_PROTECT ++#undef FLAG_SW64_INC_DEC ++#undef FLAG_SW64_DELNOP ++#undef FLAG_SW64_FM +diff --git a/gcc/config/host-linux.cc b/gcc/config/host-linux.cc +index 817d3c087..a65468272 100644 +--- a/gcc/config/host-linux.cc ++++ b/gcc/config/host-linux.cc +@@ -100,6 +100,8 @@ + # define TRY_EMPTY_VM_SPACE 0x1000000000 + #elif defined(__loongarch__) && defined(__LP64__) + # define TRY_EMPTY_VM_SPACE 0x8000000000 ++#elif defined(__sw_64) ++#define TRY_EMPTY_VM_SPACE 0x10000000000 + #else + # define TRY_EMPTY_VM_SPACE 0 + #endif +diff --git a/gcc/configure b/gcc/configure +index ef0449edd..4a70b7c66 100755 +--- a/gcc/configure ++++ b/gcc/configure +@@ -25775,6 +25775,29 @@ foo: .long 25 + xor %l1, %tle_lox10(foo), %o5 + ld [%g7 + %o5], %o1" + ;; ++ sw_64*-*-*) ++ conftest_s=' ++ .section ".tdata","awT",@progbits ++foo: .long 25 ++ .text ++ ldl $27,__tls_get_addr($29) !literal!1 ++ ldi $16,foo($29) !tlsgd!1 ++ call $26,($27),__tls_get_addr !lituse_tlsgd!1 ++ ldl $27,__tls_get_addr($29) !literal!2 ++ ldi $16,foo($29) !tlsldm!2 ++ call $26,($27),__tls_get_addr !lituse_tlsldm!2 ++ ldl $1,foo($29) !gotdtprel ++ ldih $2,foo($29) !dtprelhi ++ ldi $3,foo($2) !dtprello ++ ldi $4,foo($29) !dtprel ++ ldl $1,foo($29) !gottprel ++ ldih $2,foo($29) !tprelhi ++ ldi $3,foo($2) !tprello ++ ldi $4,foo($29) !tprel' ++ tls_first_major=2 ++ tls_first_minor=13 ++ tls_as_opt=--fatal-warnings ++ ;; + tilepro*-*-*) + conftest_s=' + .section ".tdata","awT",@progbits +@@ -26313,6 +26336,101 @@ fi + + ;; + ++ sw_64*-*-linux* | sw_64*-*-*bsd*) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for explicit relocation support" >&5 ++$as_echo_n "checking assembler for explicit relocation support... " >&6; } ++if ${gcc_cv_as_sw_64_explicit_relocs+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ gcc_cv_as_sw_64_explicit_relocs=no ++ if test x$gcc_cv_as != x; then ++ $as_echo ' .set nomacro ++ .text ++ ext0b $3, $2, $3 !lituse_bytoff!1 ++ ldl $2, a($29) !literal!1 ++ ldl $4, b($29) !literal!2 ++ ldl_u $3, 0($2) !lituse_base!1 ++ ldl $27, f($29) !literal!5 ++ call $26, ($27), f !lituse_jsr!5 ++ ldih $29, 0($26) !gpdisp!3 ++ ldi $0, c($29) !gprel ++ ldih $1, d($29) !gprelhigh ++ ldi $1, d($1) !gprellow ++ ldi $29, 0($29) !gpdisp!3' > conftest.s ++ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ++ then ++ gcc_cv_as_sw_64_explicit_relocs=yes ++ else ++ echo "configure: failed program was" >&5 ++ cat conftest.s >&5 ++ fi ++ rm -f conftest.o conftest.s ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sw_64_explicit_relocs" >&5 ++$as_echo "$gcc_cv_as_sw_64_explicit_relocs" >&6; } ++if test $gcc_cv_as_sw_64_explicit_relocs = yes; then ++ ++$as_echo "#define HAVE_AS_EXPLICIT_RELOCS 1" >>confdefs.h ++ ++fi ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for jsrdirect relocation support" >&5 ++$as_echo_n "checking assembler for jsrdirect relocation support... " >&6; } ++if ${gcc_cv_as_sw_64_jsrdirect_relocs+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ gcc_cv_as_sw_64_jsrdirect_relocs=no ++ if test $in_tree_gas = yes; then ++ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 90` ++ then gcc_cv_as_sw_64_jsrdirect_relocs=yes ++fi ++#trouble# ++ elif test x$gcc_cv_as != x; then ++ $as_echo ' .set nomacro ++ .text ++ ldl $27, a($29) !literal!1 ++ call $26, ($27), a !lituse_jsrdirect!1' > conftest.s ++ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ++ then ++ gcc_cv_as_sw_64_jsrdirect_relocs=yes ++ else ++ echo "configure: failed program was" >&5 ++ cat conftest.s >&5 ++ fi ++ rm -f conftest.o conftest.s ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sw_64_jsrdirect_relocs" >&5 ++$as_echo "$gcc_cv_as_sw_64_jsrdirect_relocs" >&6; } ++if test $gcc_cv_as_sw_64_jsrdirect_relocs = yes; then ++ ++$as_echo "#define HAVE_AS_JSRDIRECT_RELOCS 1" >>confdefs.h ++ ++fi ++cat >> confdefs.h <<_ACEOF ++#define FLAG_SW64_ATOMIC 1 ++#define FLAG_SW64_90139 1 ++#define FLAG_SW64_PREFETCH 1 ++#define FLAG_SW64_PROTECT 1 ++#define FLAG_SW64_INC_DEC 1 ++#define FLAG_SW64_DELNOP 1 ++#define FLAG_SW64_FM 1 ++_ACEOF ++ ++ ;; ++ + avr-*-*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for --mlink-relax option" >&5 + $as_echo_n "checking assembler for --mlink-relax option... " >&6; } +@@ -29377,7 +29495,7 @@ esac + case "$cpu_type" in + aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | loongarch | m32c \ + | m68k | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \ +- | tilegx | tilepro | visium | xstormy16 | xtensa) ++ | sw_64 | tilegx | tilepro | visium | xstormy16 | xtensa) + insn="nop" + ;; + ia64 | s390) +@@ -31151,6 +31269,17 @@ $as_echo "$as_me: WARNING: --build-id is not supported by your linker; --enable- + fi + fi + ++# sw_64 add --enable-linker-no-relax to support linker -Wl,-no-relax ++# Check whether --enable-linker-no-relax was given. ++if test "${enable_linker_no_relax+set}" = set; then : ++ enableval=$enable_linker_no_relax; ++else ++ enable_linker_no_relax=no ++fi ++ ++if test x"$enable_linker_no_relax" = xyes; then ++ $as_echo "#define ENABLE_LD_NORELAX 1" >>confdefs.h ++fi + # In binutils 2.21, GNU ld gained support for new emulations fully + # supporting the Solaris 2 ABI. Detect their presence in the linker used. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker *_sol2 emulation support" >&5 +diff --git a/gcc/configure.ac b/gcc/configure.ac +index 708ec3fd3..9683ab156 100644 +--- a/gcc/configure.ac ++++ b/gcc/configure.ac +@@ -23,6 +23,7 @@ + # Initialization and sanity checks + # -------------------------------- + ++AC_PREREQ(2.64) + AC_INIT + AC_CONFIG_SRCDIR(tree.cc) + AC_CONFIG_HEADER(auto-host.h:config.in) +@@ -4076,6 +4077,29 @@ foo: .long 25 + xor %l1, %tle_lox10(foo), %o5 + ld [%g7 + %o5], %o1" + ;; ++ sw_64*-*-*) ++ conftest_s=' ++ .section ".tdata","awT",@progbits ++foo: .long 25 ++ .text ++ ldl $27,__tls_get_addr($29) !literal!1 ++ ldi $16,foo($29) !tlsgd!1 ++ call $26,($27),__tls_get_addr !lituse_tlsgd!1 ++ ldl $27,__tls_get_addr($29) !literal!2 ++ ldi $16,foo($29) !tlsldm!2 ++ call $26,($27),__tls_get_addr !lituse_tlsldm!2 ++ ldl $1,foo($29) !gotdtprel ++ ldih $2,foo($29) !dtprelhi ++ ldi $3,foo($2) !dtprello ++ ldi $4,foo($29) !dtprel ++ ldl $1,foo($29) !gottprel ++ ldih $2,foo($29) !tprelhi ++ ldi $3,foo($2) !tprello ++ ldi $4,foo($29) !tprel' ++ tls_first_major=2 ++ tls_first_minor=13 ++ tls_as_opt=--fatal-warnings ++ ;; + tilepro*-*-*) + conftest_s=' + .section ".tdata","awT",@progbits +@@ -4677,6 +4701,36 @@ foo: + [Define if your assembler supports LEON instructions.])]) + ;; + ++ sw_64*-*-linux* | sw_64*-*-*bsd*) ++ gcc_GAS_CHECK_FEATURE([explicit relocation support], ++ gcc_cv_as_sw_64_explicit_relocs, [2,12,0],, ++[ .set nomacro ++ .text ++ ext0b $3, $2, $3 !lituse_bytoff!1 ++ ldl $2, a($29) !literal!1 ++ ldl $4, b($29) !literal!2 ++ ldl_u $3, 0($2) !lituse_base!1 ++ ldl $27, f($29) !literal!5 ++ call $26, ($27), f !lituse_jsr!5 ++ ldih $29, 0($26) !gpdisp!3 ++ ldi $0, c($29) !gprel ++ ldih $1, d($29) !gprelhigh ++ ldi $1, d($1) !gprellow ++ ldi $29, 0($29) !gpdisp!3],, ++ [AC_DEFINE(HAVE_AS_EXPLICIT_RELOCS, 1, ++ [Define if your assembler supports explicit relocations.])]) ++ gcc_GAS_CHECK_FEATURE([jsrdirect relocation support], ++ gcc_cv_as_sw_64_jsrdirect_relocs,, ++[ .set nomacro ++ .text ++ ldl $27, a($29) !literal!1 ++ call $26, ($27), a !lituse_jsrdirect!1],, ++ [AC_DEFINE(HAVE_AS_JSRDIRECT_RELOCS, 1, ++ [Define if your assembler supports the lituse_jsrdirect relocation.])]) ++# [AC_DEFINE(SW_64_ENABLE_ASAN, 1, ++# [Define if your target fully enable asan supports.])]) ++ ;; ++ + changequote(,)dnl + i[34567]86-*-* | x86_64-*-*) + changequote([,])dnl +@@ -5505,7 +5559,7 @@ esac + # version to the per-target configury. + case "$cpu_type" in + aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | loongarch | m32c \ +- | m68k | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \ ++ | m68k | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | sw_64 \ + | tilegx | tilepro | visium | xstormy16 | xtensa) + insn="nop" + ;; +@@ -6758,6 +6812,31 @@ if test x"$enable_linker_build_id" = xyes; then + fi + fi + ++# --no-relax ++AC_ARG_ENABLE(linker-no-relax, ++[AS_HELP_STRING([--enable-linker-no-relax], ++ [compiler will always pass --no-relax to linker])], ++[], ++enable_linker_no_relax=no) ++ ++if test x"$enable_linker_build_id" = xyes; then ++ if test x"$gcc_cv_ld_buildid" = xyes; then ++ AC_DEFINE(ENABLE_LD_BUILDID, 1, ++ [Define if gcc should always pass --build-id to linker.]) ++ else ++ AC_MSG_WARN(--build-id is not supported by your linker; --enable-linker-build-id ignored) ++ fi ++fi ++ ++# --no-relax ++if test x"$enable_linker_no_relax" = xyes; then ++ AC_DEFINE(ENABLE_LD_NORELAX, 1, ++ [Define if gcc should always pass --no-relax to linker.]) ++ else ++ AC_MSG_WARN(--no-relax is not supported by your linker; --enable-linker-no-relax ignored) ++ fi ++fi ++ + # In binutils 2.21, GNU ld gained support for new emulations fully + # supporting the Solaris 2 ABI. Detect their presence in the linker used. + AC_CACHE_CHECK(linker *_sol2 emulation support, +@@ -6930,7 +7009,8 @@ case "$target" in + powerpc*-*-linux* | \ + sparc*-*-linux* | \ + s390*-*-linux* | \ +- alpha*-*-linux*) ++ alpha*-*-linux*) | \ ++ sw_64*-*-linux*) + AC_ARG_WITH(long-double-128, + [AS_HELP_STRING([--with-long-double-128], + [use 128-bit long double by default])], +diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi +index a650f60c7..40dc7ae75 100644 +--- a/gcc/doc/install.texi ++++ b/gcc/doc/install.texi +@@ -5005,6 +5005,15 @@ on a Solaris 11 system: + @heading sparcv9-*-solaris2* + This is a synonym for @samp{sparc64-*-solaris2*}. + ++@html ++
++@end html ++@anchor{sw_64-x-x} ++@heading sw_64*-*-* ++This section contains general configuration information for all ++SW64-based platforms using ELF@. In addition to reading this ++section, please read all other sections that match your target. ++ + @html +
+ @end html +-- +2.25.1 + diff --git a/0002-Sw64-Port-add-gcc-compiler.patch b/0002-Sw64-Port-add-gcc-compiler.patch new file mode 100644 index 0000000000000000000000000000000000000000..3432307f050fe3b06a182063580a20c62047b46e --- /dev/null +++ b/0002-Sw64-Port-add-gcc-compiler.patch @@ -0,0 +1,22899 @@ +From 98573a01187b7eadd9d632c8ac3c536e50f4cb97 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:30:44 +0800 +Subject: [PATCH 02/16] Sw64 Port: add gcc compiler + +--- + gcc/ada/libgnarl/s-linux__sw_64.ads | 138 + + gcc/ada/libgnat/system-linux-sw_64.ads | 146 + + gcc/auto-inc-dec.cc | 15 +- + gcc/common/config/sw_64/sw_64-common.cc | 115 + + gcc/config/sw_64/constraints.md | 123 + + gcc/config/sw_64/driver-sw_64.cc | 105 + + gcc/config/sw_64/elf.h | 190 + + gcc/config/sw_64/elf.opt | 29 + + gcc/config/sw_64/freebsd.h | 69 + + gcc/config/sw_64/gnu-user.h | 177 + + gcc/config/sw_64/linux-elf.h | 54 + + gcc/config/sw_64/linux.h | 109 + + gcc/config/sw_64/netbsd.h | 68 + + gcc/config/sw_64/openbsd.h | 75 + + gcc/config/sw_64/predicates.md | 653 ++ + gcc/config/sw_64/sw6.md | 180 + + gcc/config/sw_64/sw8.md | 181 + + gcc/config/sw_64/sw_64-modes.def | 27 + + gcc/config/sw_64/sw_64-passes.def | 21 + + gcc/config/sw_64/sw_64-protos.h | 152 + + gcc/config/sw_64/sw_64.cc | 10076 ++++++++++++++++++++++ + gcc/config/sw_64/sw_64.h | 1001 +++ + gcc/config/sw_64/sw_64.md | 7814 +++++++++++++++++ + gcc/config/sw_64/sw_64.opt | 326 + + gcc/config/sw_64/sync.md | 495 ++ + gcc/config/sw_64/t-linux | 1 + + gcc/config/sw_64/t-sw_64 | 19 + + gcc/config/sw_64/x-sw_64 | 3 + + gcc/emit-rtl.cc | 35 + + gcc/explow.cc | 4 + + gcc/final.cc | 12 + + gcc/flags.h | 4 + + gcc/fortran/interface.cc | 11 +- + gcc/gcc.cc | 6 + + gcc/gimple-match-head.cc | 5 + + gcc/optabs.cc | 10 + + include/longlong.h | 59 + + 37 files changed, 22506 insertions(+), 2 deletions(-) + create mode 100644 gcc/ada/libgnarl/s-linux__sw_64.ads + create mode 100644 gcc/ada/libgnat/system-linux-sw_64.ads + create mode 100644 gcc/common/config/sw_64/sw_64-common.cc + create mode 100644 gcc/config/sw_64/constraints.md + create mode 100644 gcc/config/sw_64/driver-sw_64.cc + create mode 100644 gcc/config/sw_64/elf.h + create mode 100644 gcc/config/sw_64/elf.opt + create mode 100644 gcc/config/sw_64/freebsd.h + create mode 100644 gcc/config/sw_64/gnu-user.h + create mode 100644 gcc/config/sw_64/linux-elf.h + create mode 100644 gcc/config/sw_64/linux.h + create mode 100644 gcc/config/sw_64/netbsd.h + create mode 100644 gcc/config/sw_64/openbsd.h + create mode 100644 gcc/config/sw_64/predicates.md + create mode 100644 gcc/config/sw_64/sw6.md + create mode 100644 gcc/config/sw_64/sw8.md + create mode 100644 gcc/config/sw_64/sw_64-modes.def + create mode 100644 gcc/config/sw_64/sw_64-passes.def + create mode 100644 gcc/config/sw_64/sw_64-protos.h + create mode 100644 gcc/config/sw_64/sw_64.cc + create mode 100644 gcc/config/sw_64/sw_64.h + create mode 100644 gcc/config/sw_64/sw_64.md + create mode 100644 gcc/config/sw_64/sw_64.opt + create mode 100644 gcc/config/sw_64/sync.md + create mode 100644 gcc/config/sw_64/t-linux + create mode 100644 gcc/config/sw_64/t-sw_64 + create mode 100644 gcc/config/sw_64/x-sw_64 + +diff --git a/gcc/ada/libgnarl/s-linux__sw_64.ads b/gcc/ada/libgnarl/s-linux__sw_64.ads +new file mode 100644 +index 000000000..b63d4cc46 +--- /dev/null ++++ b/gcc/ada/libgnarl/s-linux__sw_64.ads +@@ -0,0 +1,138 @@ ++------------------------------------------------------------------------------ ++-- -- ++-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS -- ++-- -- ++-- S Y S T E M . L I N U X -- ++-- -- ++-- S p e c -- ++-- -- ++-- Copyright (C) 2009-2022, Free Software Foundation, Inc. -- ++-- -- ++-- GNARL is free software; you can redistribute it and/or modify it under -- ++-- terms of the GNU General Public License as published by the Free Soft- -- ++-- ware Foundation; either version 3, or (at your option) any later ver- -- ++-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- ++-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- ++-- or FITNESS FOR A PARTICULAR PURPOSE. -- ++-- -- ++-- As a special exception under Section 7 of GPL version 3, you are granted -- ++-- additional permissions described in the GCC Runtime Library Exception, -- ++-- version 3.1, as published by the Free Software Foundation. -- ++-- -- ++-- You should have received a copy of the GNU General Public License and -- ++-- a copy of the GCC Runtime Library Exception along with this program; -- ++-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- ++-- . -- ++-- -- ++-- -- ++------------------------------------------------------------------------------ ++ ++-- This is the alpha version of this package ++ ++-- This package encapsulates cpu specific differences between implementations ++-- of GNU/Linux, in order to share s-osinte-linux.ads. ++ ++-- PLEASE DO NOT add any with-clauses to this package or remove the pragma ++-- Preelaborate. This package is designed to be a bottom-level (leaf) package. ++ ++with Interfaces.C; ++with System.Parameters; ++ ++package System.Linux is ++ pragma Preelaborate; ++ ++ ---------- ++ -- Time -- ++ ---------- ++ ++ subtype long is Interfaces.C.long; ++ subtype suseconds_t is Interfaces.C.long; ++ type time_t is range -2 ** (System.Parameters.time_t_bits - 1) ++ .. 2 ** (System.Parameters.time_t_bits - 1) - 1; ++ subtype clockid_t is Interfaces.C.int; ++ ++ type timespec is record ++ tv_sec : time_t; ++ tv_nsec : long; ++ end record; ++ pragma Convention (C, timespec); ++ ++ type timeval is record ++ tv_sec : time_t; ++ tv_usec : suseconds_t; ++ end record; ++ pragma Convention (C, timeval); ++ ++ ----------- ++ -- Errno -- ++ ----------- ++ ++ EAGAIN : constant := 35; ++ EINTR : constant := 4; ++ EINVAL : constant := 22; ++ ENOMEM : constant := 12; ++ EPERM : constant := 1; ++ ETIMEDOUT : constant := 60; ++ ++ ------------- ++ -- Signals -- ++ ------------- ++ ++ SIGHUP : constant := 1; -- hangup ++ SIGINT : constant := 2; -- interrupt (rubout) ++ SIGQUIT : constant := 3; -- quit (ASCD FS) ++ SIGILL : constant := 4; -- illegal instruction (not reset) ++ SIGTRAP : constant := 5; -- trace trap (not reset) ++ SIGIOT : constant := 6; -- IOT instruction ++ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future ++ SIGFPE : constant := 8; -- floating point exception ++ SIGKILL : constant := 9; -- kill (cannot be caught or ignored) ++ SIGBUS : constant := 10; -- bus error ++ SIGSEGV : constant := 11; -- segmentation violation ++ SIGSYS : constant := 12; -- bad system call ++ SIGPIPE : constant := 13; -- write on a pipe with no one to read it ++ SIGALRM : constant := 14; -- alarm clock ++ SIGTERM : constant := 15; -- software termination signal from kill ++ SIGURG : constant := 16; -- urgent condition on IO channel ++ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored) ++ SIGTSTP : constant := 18; -- user stop requested from tty ++ SIGCONT : constant := 19; -- stopped process has been continued ++ SIGCLD : constant := 20; -- alias for SIGCHLD ++ SIGCHLD : constant := 20; -- child status change ++ SIGTTIN : constant := 21; -- background tty read attempted ++ SIGTTOU : constant := 22; -- background tty write attempted ++ SIGIO : constant := 23; -- I/O now possible (4.2 BSD) ++ SIGPOLL : constant := 23; -- pollable event occurred ++ SIGXCPU : constant := 24; -- CPU time limit exceeded ++ SIGXFSZ : constant := 25; -- filesize limit exceeded ++ SIGVTALRM : constant := 26; -- virtual timer expired ++ SIGPROF : constant := 27; -- profiling timer expired ++ SIGWINCH : constant := 28; -- window size change ++ SIGPWR : constant := 29; -- power-fail restart ++ SIGUSR1 : constant := 30; -- user defined signal 1 ++ SIGUSR2 : constant := 31; -- user defined signal 2 ++ ++ SIG32 : constant := 32; -- glibc internal signal ++ SIG33 : constant := 33; -- glibc internal signal ++ SIG34 : constant := 34; -- glibc internal signal ++ ++ SIGADAABORT : constant := SIGABRT; ++ -- Change this if you want to use another signal for task abort. ++ -- SIGTERM might be a good one. ++ ++ SIGUNUSED : constant := 0; ++ SIGSTKFLT : constant := 0; ++ SIGLOST : constant := 0; ++ -- These don't exist for Linux/Alpha. The constants are present ++ -- so that we can continue to use a-intnam-linux.ads. ++ ++ -- struct_sigaction offsets ++ ++ sa_handler_pos : constant := 0; ++ sa_mask_pos : constant := Standard'Address_Size / 8; ++ sa_flags_pos : constant := 128 + sa_mask_pos; ++ ++ SA_SIGINFO : constant := 16#40#; ++ SA_ONSTACK : constant := 16#01#; ++ ++end System.Linux; +diff --git a/gcc/ada/libgnat/system-linux-sw_64.ads b/gcc/ada/libgnat/system-linux-sw_64.ads +new file mode 100644 +index 000000000..b6f15501e +--- /dev/null ++++ b/gcc/ada/libgnat/system-linux-sw_64.ads +@@ -0,0 +1,146 @@ ++------------------------------------------------------------------------------ ++-- -- ++-- GNAT RUN-TIME COMPONENTS -- ++-- -- ++-- S Y S T E M -- ++-- -- ++-- S p e c -- ++-- (GNU-Linux/alpha Version) -- ++-- -- ++-- Copyright (C) 1992-2022, Free Software Foundation, Inc. -- ++-- -- ++-- This specification is derived from the Ada Reference Manual for use with -- ++-- GNAT. The copyright notice above, and the license provisions that follow -- ++-- apply solely to the contents of the part following the private keyword. -- ++-- -- ++-- GNAT is free software; you can redistribute it and/or modify it under -- ++-- terms of the GNU General Public License as published by the Free Soft- -- ++-- ware Foundation; either version 3, or (at your option) any later ver- -- ++-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- ++-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- ++-- or FITNESS FOR A PARTICULAR PURPOSE. -- ++-- -- ++-- As a special exception under Section 7 of GPL version 3, you are granted -- ++-- additional permissions described in the GCC Runtime Library Exception, -- ++-- version 3.1, as published by the Free Software Foundation. -- ++-- -- ++-- You should have received a copy of the GNU General Public License and -- ++-- a copy of the GCC Runtime Library Exception along with this program; -- ++-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- ++-- . -- ++-- -- ++-- GNAT was originally developed by the GNAT team at New York University. -- ++-- Extensive contributions were provided by Ada Core Technologies Inc. -- ++-- -- ++------------------------------------------------------------------------------ ++ ++package System is ++ pragma Pure; ++ -- Note that we take advantage of the implementation permission to make ++ -- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada ++ -- 2005, this is Pure in any case (AI-362). ++ ++ pragma No_Elaboration_Code_All; ++ -- Allow the use of that restriction in units that WITH this unit ++ ++ type Name is (SYSTEM_NAME_GNAT); ++ System_Name : constant Name := SYSTEM_NAME_GNAT; ++ ++ -- System-Dependent Named Numbers ++ ++ Min_Int : constant := -2 ** (Standard'Max_Integer_Size - 1); ++ Max_Int : constant := 2 ** (Standard'Max_Integer_Size - 1) - 1; ++ ++ Max_Binary_Modulus : constant := 2 ** Standard'Max_Integer_Size; ++ Max_Nonbinary_Modulus : constant := 2 ** Integer'Size - 1; ++ ++ Max_Base_Digits : constant := Long_Long_Float'Digits; ++ Max_Digits : constant := Long_Long_Float'Digits; ++ ++ Max_Mantissa : constant := Standard'Max_Integer_Size - 1; ++ Fine_Delta : constant := 2.0 ** (-Max_Mantissa); ++ ++ Tick : constant := 1.0 / 1024.0; ++ ++ -- Storage-related Declarations ++ ++ type Address is private; ++ pragma Preelaborable_Initialization (Address); ++ Null_Address : constant Address; ++ ++ Storage_Unit : constant := 8; ++ Word_Size : constant := 64; ++ Memory_Size : constant := 2 ** 64; ++ ++ -- Address comparison ++ ++ function "<" (Left, Right : Address) return Boolean; ++ function "<=" (Left, Right : Address) return Boolean; ++ function ">" (Left, Right : Address) return Boolean; ++ function ">=" (Left, Right : Address) return Boolean; ++ function "=" (Left, Right : Address) return Boolean; ++ ++ pragma Import (Intrinsic, "<"); ++ pragma Import (Intrinsic, "<="); ++ pragma Import (Intrinsic, ">"); ++ pragma Import (Intrinsic, ">="); ++ pragma Import (Intrinsic, "="); ++ ++ -- Other System-Dependent Declarations ++ ++ type Bit_Order is (High_Order_First, Low_Order_First); ++ Default_Bit_Order : constant Bit_Order := Low_Order_First; ++ pragma Warnings (Off, Default_Bit_Order); -- kill constant condition warning ++ ++ -- Priority-related Declarations (RM D.1) ++ ++ Max_Priority : constant Positive := 30; ++ Max_Interrupt_Priority : constant Positive := 31; ++ ++ subtype Any_Priority is Integer range 0 .. 31; ++ subtype Priority is Any_Priority range 0 .. 30; ++ subtype Interrupt_Priority is Any_Priority range 31 .. 31; ++ ++ Default_Priority : constant Priority := 15; ++ ++private ++ ++ type Address is mod Memory_Size; ++ Null_Address : constant Address := 0; ++ ++ -------------------------------------- ++ -- System Implementation Parameters -- ++ -------------------------------------- ++ ++ -- These parameters provide information about the target that is used ++ -- by the compiler. They are in the private part of System, where they ++ -- can be accessed using the special circuitry in the Targparm unit ++ -- whose source should be consulted for more detailed descriptions ++ -- of the individual switch values. ++ ++ Backend_Divide_Checks : constant Boolean := False; ++ Backend_Overflow_Checks : constant Boolean := True; ++ Command_Line_Args : constant Boolean := True; ++ Configurable_Run_Time : constant Boolean := False; ++ Denorm : constant Boolean := True; ++ Duration_32_Bits : constant Boolean := False; ++ Exit_Status_Supported : constant Boolean := True; ++ Machine_Overflows : constant Boolean := False; ++ Machine_Rounds : constant Boolean := True; ++ Preallocated_Stacks : constant Boolean := False; ++ Signed_Zeros : constant Boolean := True; ++ Stack_Check_Default : constant Boolean := False; ++ Stack_Check_Probes : constant Boolean := True; ++ Stack_Check_Limits : constant Boolean := False; ++ Support_Aggregates : constant Boolean := True; ++ Support_Atomic_Primitives : constant Boolean := True; ++ Support_Composite_Assign : constant Boolean := True; ++ Support_Composite_Compare : constant Boolean := True; ++ Support_Long_Shifts : constant Boolean := True; ++ Always_Compatible_Rep : constant Boolean := False; ++ Suppress_Standard_Library : constant Boolean := False; ++ Use_Ada_Main_Program_Name : constant Boolean := False; ++ Frontend_Exceptions : constant Boolean := False; ++ ZCX_By_Default : constant Boolean := True; ++ ++end System; +diff --git a/gcc/auto-inc-dec.cc b/gcc/auto-inc-dec.cc +index 85fe9d149..277eda070 100644 +--- a/gcc/auto-inc-dec.cc ++++ b/gcc/auto-inc-dec.cc +@@ -892,6 +892,10 @@ parse_add_or_inc (rtx_insn *insn, bool before_mem) + inc_insn.reg1_val = -INTVAL (XEXP (SET_SRC (pat), 1)); + inc_insn.reg1 = GEN_INT (inc_insn.reg1_val); + } ++#ifdef FLAG_SW64_INC_DEC ++ if (inc_insn.reg1_val > 2047 || inc_insn.reg1_val < -2048) ++ return false; ++#endif + return true; + } + else if ((HAVE_PRE_MODIFY_REG || HAVE_POST_MODIFY_REG) +@@ -1369,6 +1373,10 @@ find_mem (rtx *address_of_x) + mem_insn.reg1_is_const = true; + /* Match with *(reg0 + c) where c is a const. */ + mem_insn.reg1_val = INTVAL (reg1); ++#ifdef FLAG_SW64_INC_DEC ++ if (mem_insn.reg1_val > 2047 || mem_insn.reg1_val < -2048) ++ return false; ++#endif + if (find_inc (true)) + return true; + } +@@ -1696,8 +1704,13 @@ public: + { + if (!AUTO_INC_DEC) + return false; +- ++#ifdef FLAG_SW64_INC_DEC ++ return ((optimize > 0 && flag_auto_inc_dec && (!TARGET_SW8A)) ++ || (optimize > 0 && flag_auto_inc_dec && (TARGET_SW8A) ++ && flag_sw_auto_inc_dec)); ++#else + return (optimize > 0 && flag_auto_inc_dec); ++#endif + } + + +diff --git a/gcc/common/config/sw_64/sw_64-common.cc b/gcc/common/config/sw_64/sw_64-common.cc +new file mode 100644 +index 000000000..b3d34dad5 +--- /dev/null ++++ b/gcc/common/config/sw_64/sw_64-common.cc +@@ -0,0 +1,115 @@ ++/* Common hooks for Sw64. ++ Copyright (C) 1992-2022 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#include "config.h" ++#include "system.h" ++#include "coretypes.h" ++#include "diagnostic-core.h" ++#include "tm.h" ++#include "common/common-target.h" ++#include "common/common-target-def.h" ++#include "opts.h" ++#include "flags.h" ++ ++int flag_fpcr_set; ++ ++/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ ++static const struct default_options sw_64_option_optimization_table[] = { ++ /* Enable redundant extension instructions removal at -O2 and higher. */ ++ {OPT_LEVELS_2_PLUS, OPT_free, NULL, 1}, ++ {OPT_LEVELS_NONE, 0, NULL, 0}}; ++ ++/* Implement TARGET_OPTION_INIT_STRUCT. */ ++ ++static void ++sw_64_option_init_struct (struct gcc_options *opts ATTRIBUTE_UNUSED) ++{ ++ opts->x_target_flags |= MASK_IEEE; ++ global_options.x_flag_prefetch_loop_arrays = 1; ++} ++ ++/* Implement TARGET_HANDLE_OPTION. */ ++ ++static bool ++sw_64_handle_option (struct gcc_options *opts, ++ struct gcc_options *opts_set ATTRIBUTE_UNUSED, ++ const struct cl_decoded_option *decoded, location_t loc) ++{ ++ size_t code = decoded->opt_index; ++ const char *arg = decoded->arg; ++ int value = decoded->value; ++ ++ switch (code) ++ { ++ case OPT_mfp_regs: ++ if (value == 0) ++ opts->x_target_flags |= MASK_SOFT_FP; ++ break; ++ ++ case OPT_mieee: ++ case OPT_mieee_with_inexact: ++ /* add mieee for sw_64 */ ++ case OPT_mieee_main: ++ if (code == OPT_mieee) ++ flag_fpcr_set = 1; ++ else if (code == OPT_mieee_with_inexact) ++ flag_fpcr_set = 3; ++ else if (code == OPT_mieee_main) ++ flag_fpcr_set = 4; ++ opts->x_target_flags |= MASK_IEEE_CONFORMANT; ++ break; ++ ++ case OPT_mtls_size_: ++ if (value != 16 && value != 32 && value != 64) ++ error_at (loc, "bad value %qs for %<-mtls-size%> switch", arg); ++ break; ++ ++ case OPT_mtls_tlsgd_: ++ if (value != 16 && value != 32) ++ error_at (loc, "bad value %qs for -mtls-tlsgd switch", arg); ++ break; ++ ++ case OPT_mtls_tlsldm_: ++ if (value != 16 && value != 32) ++ error_at (loc, "bad value %qs for -mtls-tlsldm switch", arg); ++ break; ++ ++ // 2021-12-06 add by wangw, to support mgprel-size option ++ case OPT_mgprel_size_: ++ if (value != 16 && value != 32) ++ error_at (loc, "bad value %qs for -mgprel-size switch", arg); ++ break; ++ } ++ ++ return true; ++} ++ ++#undef TARGET_DEFAULT_TARGET_FLAGS ++#define TARGET_DEFAULT_TARGET_FLAGS \ ++ (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS) ++#undef TARGET_HANDLE_OPTION ++#define TARGET_HANDLE_OPTION sw_64_handle_option ++ ++#undef TARGET_OPTION_INIT_STRUCT ++#define TARGET_OPTION_INIT_STRUCT sw_64_option_init_struct ++ ++#undef TARGET_OPTION_OPTIMIZATION_TABLE ++#define TARGET_OPTION_OPTIMIZATION_TABLE sw_64_option_optimization_table ++ ++struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; +diff --git a/gcc/config/sw_64/constraints.md b/gcc/config/sw_64/constraints.md +new file mode 100644 +index 000000000..6d06f0e13 +--- /dev/null ++++ b/gcc/config/sw_64/constraints.md +@@ -0,0 +1,123 @@ ++;; Constraint definitions for Sw64. ++;; Copyright (C) 2007-2022 Free Software Foundation, Inc. ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++;;; Unused letters: ++;;; ABCDEF H V YZ ++;;; de ghijkl pq tu wxyz ++ ++;; Integer register constraints. ++ ++(define_register_constraint "a" "R24_REG" ++ "General register 24, input to division routine") ++ ++(define_register_constraint "b" "R25_REG" ++ "General register 24, input to division routine") ++ ++(define_register_constraint "c" "R27_REG" ++ "General register 27, function call address") ++ ++(define_register_constraint "f" "TARGET_FPREGS ? FLOAT_REGS : NO_REGS" ++ "Any floating-point register") ++ ++(define_register_constraint "v" "R0_REG" ++ "General register 0, function value return address") ++ ++(define_memory_constraint "w" ++ "A memory whose address is only a register" ++ (match_operand 0 "mem_noofs_operand")) ++ ++;; Integer constant constraints. ++(define_constraint "I" ++ "An unsigned 8 bit constant" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (ival, 0, 255)"))) ++ ++(define_constraint "J" ++ "The constant zero" ++ (and (match_code "const_int") ++ (match_test "ival == 0"))) ++ ++(define_constraint "K" ++ "Signed 16-bit integer constant" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (ival, -32768, 32767)"))) ++ ++(define_constraint "L" ++ "A shifted signed 16-bit constant appropriate for LDAH" ++ (and (match_code "const_int") ++ (match_test "(ival & 0xffff) == 0 ++ && (ival >> 31 == -1 || ival >> 31 == 0)"))) ++ ++(define_constraint "M" ++ "A valid operand of a ZAP insn" ++ (and (match_code "const_int") ++ (match_test "zap_mask (ival) != 0"))) ++ ++(define_constraint "N" ++ "A complemented unsigned 8-bit constant" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (~ival, 0, 255)"))) ++ ++(define_constraint "O" ++ "A negated unsigned 8-bit constant" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (-ival, 0, 255)"))) ++ ++(define_constraint "P" ++ "The constant 1, 2 or 3" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (ival, 1, 3)"))) ++ ++;; Floating-point constant constraints. ++(define_constraint "G" ++ "The floating point zero constant" ++ (and (match_code "const_double") ++ (match_test "op == CONST0_RTX (mode)"))) ++ ++;; "Extra" constraints. ++ ++;; A memory location that is not a reference ++;; (using an AND) to an unaligned location. ++(define_memory_constraint "Q" ++ "@internal A normal_memory_operand" ++ (and (match_code "mem") ++ (not (match_code "and" "0")))) ++ ++(define_constraint "R" ++ "@internal A direct_call_operand" ++ (match_operand:DI 0 "direct_call_operand")) ++ ++(define_constraint "S" ++ "An unsigned 6-bit constant" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (ival, 0, 63)"))) ++ ++(define_constraint "T" ++ "@internal A high-part symbol" ++ (match_code "high")) ++ ++(define_constraint "W" ++ "A vector zero constant" ++ (and (match_code "const_vector") ++ (match_test "op == CONST0_RTX (mode)"))) ++ ++(define_constraint "Y" ++ "An unsigned 5-bit constant" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (ival, 0, 31)"))) +diff --git a/gcc/config/sw_64/driver-sw_64.cc b/gcc/config/sw_64/driver-sw_64.cc +new file mode 100644 +index 000000000..a3e50aba1 +--- /dev/null ++++ b/gcc/config/sw_64/driver-sw_64.cc +@@ -0,0 +1,105 @@ ++/* Subroutines for the gcc driver. ++ Copyright (C) 2009-2022 Free Software Foundation, Inc. ++ Contributed by Arthur Loiret ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#define IN_TARGET_CODE 1 ++ ++#include "config.h" ++#include "system.h" ++#include "coretypes.h" ++#include "tm.h" ++ ++/* Chip family type IDs, returned by implver instruction. */ ++#define IMPLVER_SW6_FAMILY 2 /* SW6 */ ++#define IMPLVER_SW8_FAMILY 4 /* SW8 */ ++ ++/* Bit defines for amask instruction. */ ++#define AMASK_BWX 0x1 /* byte/word extension. */ ++#define AMASK_FIX \ ++ 0x2 /* sqrt and f <-> i conversions \ ++ extension. */ ++#define AMASK_CIX 0x4 /* count extension. */ ++#define AMASK_MVI 0x100 /* multimedia extension. */ ++#define AMASK_PRECISE 0x200 /* Precise arithmetic traps. */ ++#define AMASK_LOCKPFTCHOK \ ++ 0x1000 /* Safe to prefetch lock cache \ ++ block. */ ++#define AMASK_SW6A (1U << 16) ++#define AMASK_SW6B (1U << 17) ++#define AMASK_SW4D (1U << 18) ++#define AMASK_SW8A (1U << 19) ++ ++/* This will be called by the spec parser in gcc.c when it sees ++ a %:local_cpu_detect(args) construct. Currently it will be called ++ with either "cpu" or "tune" as argument depending on if -mcpu=native ++ or -mtune=native is to be substituted. ++ ++ It returns a string containing new command line parameters to be ++ put at the place of the above two options, depending on what CPU ++ this is executed. E.g. "-mcpu=sw6" on an Sw_64 for ++ -mcpu=native. If the routine can't detect a known processor, ++ the -mcpu or -mtune option is discarded. ++ ++ ARGC and ARGV are set depending on the actual arguments given ++ in the spec. */ ++const char * ++host_detect_local_cpu (int argc, const char **argv) ++{ ++ static const struct cpu_types ++ { ++ long implver; ++ long amask; ++ const char *const cpu; ++ } cpu_types[] = {{IMPLVER_SW6_FAMILY, ++ AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_SW6B, "sw6b"}, ++ {IMPLVER_SW6_FAMILY, ++ AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_SW6A, "sw6a"}, ++ {IMPLVER_SW6_FAMILY, ++ AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_SW4D, "sw4d"}, ++ {IMPLVER_SW8_FAMILY, ++ AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_SW8A, "sw8a"}, ++ {0, 0, NULL}}; ++ long implver; ++ long amask; ++ const char *cpu; ++ int i; ++ ++ if (argc < 1) ++ return NULL; ++ ++ if (strcmp (argv[0], "cpu") && strcmp (argv[0], "tune")) ++ return NULL; ++ ++ implver = __builtin_sw_64_implver (); ++ amask = __builtin_sw_64_amask (~0L); ++ cpu = NULL; ++ ++ for (i = 0; cpu_types[i].cpu != NULL; i++) ++ if (implver == cpu_types[i].implver ++ && (~amask & cpu_types[i].amask) == cpu_types[i].amask) ++ { ++ cpu = cpu_types[i].cpu; ++ break; ++ } ++ ++ if (cpu == NULL) ++ return NULL; ++ ++ return concat ("-m", argv[0], "=", cpu, NULL); ++} +diff --git a/gcc/config/sw_64/elf.h b/gcc/config/sw_64/elf.h +new file mode 100644 +index 000000000..d3809508b +--- /dev/null ++++ b/gcc/config/sw_64/elf.h +@@ -0,0 +1,190 @@ ++/* Definitions of target machine for GNU compiler, for Sw64 w/ELF. ++ Copyright (C) 1996-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson (rth@tamu.edu). ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#undef CC1_SPEC ++#define CC1_SPEC "%{G*}" ++ ++#undef ASM_SPEC ++#define ASM_SPEC "%{G*} %{relax:-relax} %{mcpu=*:-m%*}" ++ ++/* Do not output a .file directive at the beginning of the input file. */ ++ ++#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE ++#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true ++ ++/* This is how to output an assembler line ++ that says to advance the location counter ++ to a multiple of 2**LOG bytes. */ ++ ++#define ASM_OUTPUT_ALIGN(FILE, LOG) \ ++ if ((LOG) != 0) \ ++ fprintf (FILE, "\t.align %d\n", LOG); ++ ++/* This says how to output assembler code to declare an ++ uninitialized internal linkage data object. Under SVR4, ++ the linker seems to want the alignment of data objects ++ to depend on their types. We do exactly that here. */ ++ ++#undef ASM_OUTPUT_ALIGNED_LOCAL ++#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ ++ do \ ++ { \ ++ if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value) \ ++ switch_to_section (sbss_section); \ ++ else \ ++ switch_to_section (bss_section); \ ++ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \ ++ if (!flag_inhibit_size_directive) \ ++ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \ ++ ASM_OUTPUT_ALIGN ((FILE), exact_log2 ((ALIGN) / BITS_PER_UNIT)); \ ++ ASM_OUTPUT_LABEL (FILE, NAME); \ ++ ASM_OUTPUT_SKIP ((FILE), (SIZE) ? (SIZE) : 1); \ ++ } while (0) ++ ++/* This says how to output assembler code to declare an ++ uninitialized external linkage data object. */ ++ ++#undef ASM_OUTPUT_ALIGNED_BSS ++#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ ++ do \ ++ { \ ++ ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ ++ } while (0) ++ ++#undef BSS_SECTION_ASM_OP ++#define BSS_SECTION_ASM_OP "\t.section\t.bss" ++#undef SBSS_SECTION_ASM_OP ++#define SBSS_SECTION_ASM_OP "\t.section\t.sbss,\"aw\"" ++#undef SDATA_SECTION_ASM_OP ++#define SDATA_SECTION_ASM_OP "\t.section\t.sdata,\"aw\"" ++ ++/* This is how we tell the assembler that two symbols have the same value. */ ++ ++#undef ASM_OUTPUT_DEF ++#define ASM_OUTPUT_DEF(FILE, ALIAS, NAME) \ ++ do \ ++ { \ ++ assemble_name (FILE, ALIAS); \ ++ fputs (" = ", FILE); \ ++ assemble_name (FILE, NAME); \ ++ fputc ('\n', FILE); \ ++ } while (0) ++ ++#undef ASM_OUTPUT_DEF_FROM_DECLS ++#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \ ++ do \ ++ { \ ++ const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ ++ const char *name = IDENTIFIER_POINTER (TARGET); \ ++ if (TREE_CODE (DECL) == FUNCTION_DECL) \ ++ { \ ++ fputc ('$', FILE); \ ++ assemble_name (FILE, alias); \ ++ fputs ("..ng = $", FILE); \ ++ assemble_name (FILE, name); \ ++ fputs ("..ng\n", FILE); \ ++ } \ ++ ASM_OUTPUT_DEF (FILE, alias, name); \ ++ } while (0) ++ ++/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the ++ (even more) magical crtbegin.o file which provides part of the ++ support for getting C++ file-scope static object constructed ++ before entering `main'. */ ++ ++#undef STARTFILE_SPEC ++#ifdef HAVE_LD_PIE ++#define STARTFILE_SPEC \ ++ "%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\ ++ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}" ++#else ++#define STARTFILE_SPEC \ ++ "%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}}\ ++ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}" ++#endif ++ ++/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the ++ magical crtend.o file which provides part of the support for ++ getting C++ file-scope static object constructed before entering ++ `main', followed by a normal ELF "finalizer" file, `crtn.o'. */ ++ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC \ ++ "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \ ++ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s" ++ ++/* This variable should be set to 'true' if the target ABI requires ++ unwinding tables even when exceptions are not used. */ ++#define TARGET_UNWIND_TABLES_DEFAULT true ++ ++/* Select a format to encode pointers in exception handling data. CODE ++ is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is ++ true if the symbol may be affected by dynamic relocations. ++ ++ Since application size is already constrained to <2GB by the form of ++ the ldgp relocation, we can use a 32-bit pc-relative relocation to ++ static data. Dynamic data is accessed indirectly to allow for read ++ only EH sections. */ ++#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ ++ (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) ++ ++/* If defined, a C statement to be executed just prior to the output of ++ assembler code for INSN. */ ++#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ ++ (sw_64_this_literal_sequence_number = 0, \ ++ sw_64_this_gpdisp_sequence_number = 0) ++extern int sw_64_this_literal_sequence_number; ++extern int sw_64_this_gpdisp_sequence_number; ++ ++/* Since the bits of the _init and _fini function is spread across ++ many object files, each potentially with its own GP, we must assume ++ we need to load our GP. Further, the .init/.fini section can ++ easily be more than 4MB away from the function to call so we can't ++ use bsr. */ ++// jsr->call ++#ifdef __sw_64_sw8a__ ++#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ ++ asm (SECTION_OP "\n" \ ++ " addpi 0, $29\n" \ ++ " ldgp $29,0($29)\n" \ ++ " unop\n" \ ++ " call $26," USER_LABEL_PREFIX #FUNC "\n" \ ++ " .align 3\n" \ ++ " .previous"); ++#else ++#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ ++ asm (SECTION_OP "\n" \ ++ " br $29,1f\n" \ ++ "1: ldgp $29,0($29)\n" \ ++ " unop\n" \ ++ " call $26," USER_LABEL_PREFIX #FUNC "\n" \ ++ " .align 3\n" \ ++ " .previous"); ++#endif ++/* If we have the capability create headers for efficient EH lookup. ++ As of Jan 2002, only glibc 2.2.4 can actually make use of this, but ++ I imagine that other systems will catch up. In the meantime, it ++ doesn't harm to make sure that the data exists to be used later. */ ++#if defined(HAVE_LD_EH_FRAME_HDR) ++#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} " ++#endif ++ ++#undef ASM_DECLARE_OBJECT_NAME ++#define ASM_DECLARE_OBJECT_NAME sw_64_declare_object_name +diff --git a/gcc/config/sw_64/elf.opt b/gcc/config/sw_64/elf.opt +new file mode 100644 +index 000000000..3cdc21f4a +--- /dev/null ++++ b/gcc/config/sw_64/elf.opt +@@ -0,0 +1,29 @@ ++; Sw_64 ELF options. ++ ++; Copyright (C) 2011-2022 Free Software Foundation, Inc. ++; ++; This file is part of GCC. ++; ++; GCC is free software; you can redistribute it and/or modify it under ++; the terms of the GNU General Public License as published by the Free ++; Software Foundation; either version 3, or (at your option) any later ++; version. ++; ++; GCC is distributed in the hope that it will be useful, but WITHOUT ANY ++; WARRANTY; without even the implied warranty of MERCHANTABILITY or ++; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++; for more details. ++; ++; You should have received a copy of the GNU General Public License ++; along with GCC; see the file COPYING3. If not see ++; . ++ ++; See the GCC internals manual (options.texi) for a description of ++; this file's format. ++ ++; Please try to keep this file in ASCII collating order. ++ ++relax ++Driver ++ ++; This comment is to ensure we retain the blank line above. +diff --git a/gcc/config/sw_64/freebsd.h b/gcc/config/sw_64/freebsd.h +new file mode 100644 +index 000000000..a866fa817 +--- /dev/null ++++ b/gcc/config/sw_64/freebsd.h +@@ -0,0 +1,69 @@ ++/* Definitions for Sw64 running FreeBSD using the ELF format ++ Copyright (C) 2000-2022 Free Software Foundation, Inc. ++ Contributed by David E. O'Brien and BSDi. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#undef EXTRA_SPECS ++#define EXTRA_SPECS \ ++ { \ ++ "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER \ ++ } ++ ++/* Provide a CPP_SPEC appropriate for FreeBSD/sw_64 -- dealing with ++ the GCC option `-posix'. */ ++ ++#undef CPP_SPEC ++#define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" ++ ++#define LINK_SPEC \ ++ "%{G*} %{relax:-relax} \ ++ %{p:%nconsider using '-pg' instead of '-p' with gprof(1)} \ ++ %{assert*} %{R*} %{rpath*} %{defsym*} \ ++ %{shared:-Bshareable %{h*} %{soname*}} \ ++ %{!shared: \ ++ %{!static: \ ++ %{rdynamic:-export-dynamic} \ ++ -dynamic-linker %(fbsd_dynamic_linker) } \ ++ %{static:-Bstatic}} \ ++ %{symbolic:-Bsymbolic}" ++ ++/************************[ Target stuff ]***********************************/ ++ ++/* Define the actual types of some ANSI-mandated types. ++ Needs to agree with . GCC defaults come from c-decl.c, ++ c-common.c, and config//.h. */ ++ ++/* sw_64.h gets this wrong for FreeBSD. We use the GCC defaults instead. */ ++#undef WCHAR_TYPE ++ ++#undef WCHAR_TYPE_SIZE ++#define WCHAR_TYPE_SIZE 32 ++ ++#define TARGET_ELF 1 ++ ++#undef HAS_INIT_SECTION ++ ++/* Show that we need a GP when profiling. */ ++#undef TARGET_PROFILING_NEEDS_GP ++#define TARGET_PROFILING_NEEDS_GP 1 ++ ++/* Don't default to pcc-struct-return, we want to retain compatibility with ++ older FreeBSD releases AND pcc-struct-return may not be reentrant. */ ++ ++#undef DEFAULT_PCC_STRUCT_RETURN ++#define DEFAULT_PCC_STRUCT_RETURN 0 +diff --git a/gcc/config/sw_64/gnu-user.h b/gcc/config/sw_64/gnu-user.h +new file mode 100644 +index 000000000..539f0573a +--- /dev/null ++++ b/gcc/config/sw_64/gnu-user.h +@@ -0,0 +1,177 @@ ++/* Definitions for systems using, at least optionally, a GNU ++ (glibc-based) userspace or other userspace with libc derived from ++ glibc (e.g. uClibc) or for which similar specs are appropriate. ++ Copyright (C) 1995-2022 Free Software Foundation, Inc. ++ Contributed by Eric Youngdale. ++ Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org). ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++Under Section 7 of GPL version 3, you are granted additional ++permissions described in the GCC Runtime Library Exception, version ++3.1, as published by the Free Software Foundation. ++ ++You should have received a copy of the GNU General Public License and ++a copy of the GCC Runtime Library Exception along with this program; ++see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++. */ ++ ++/* Don't assume anything about the header files. */ ++//#define SYSTEM_IMPLICIT_EXTERN_C ++/* ++#undef ASM_APP_ON ++#define ASM_APP_ON "#APP\n" ++ ++#undef ASM_APP_OFF ++#define ASM_APP_OFF "#NO_APP\n" ++*/ ++#if ENABLE_OFFLOADING == 1 ++#define CRTOFFLOADBEGIN "%{fopenacc|fopenmp:crtoffloadbegin%O%s}" ++#define CRTOFFLOADEND "%{fopenacc|fopenmp:crtoffloadend%O%s}" ++#else ++#define CRTOFFLOADBEGIN "" ++#define CRTOFFLOADEND "" ++#endif ++ ++/* Provide a STARTFILE_SPEC appropriate for GNU userspace. Here we add ++ the GNU userspace magical crtbegin.o file (see crtstuff.c) which ++ provides part of the support for getting C++ file-scope static ++ object constructed before entering `main'. */ ++ ++#if defined HAVE_LD_PIE ++#define GNU_USER_TARGET_STARTFILE_SPEC \ ++ "%{shared:; \ ++ pg|p|profile:%{static-pie:grcrt1.o%s;:gcrt1.o%s}; \ ++ static:crt1.o%s; \ ++ static-pie:rcrt1.o%s; \ ++ " PIE_SPEC ":Scrt1.o%s; \ ++ :crt1.o%s} \ ++ crti.o%s \ ++ %{static:crtbeginT.o%s; \ ++ shared|static-pie|" PIE_SPEC ":crtbeginS.o%s; \ ++ :crtbegin.o%s} \ ++ %{fvtable-verify=none:%s; \ ++ fvtable-verify=preinit:vtv_start_preinit.o%s; \ ++ fvtable-verify=std:vtv_start.o%s} \ ++ " CRTOFFLOADBEGIN ++#else ++#define GNU_USER_TARGET_STARTFILE_SPEC \ ++ "%{shared:; \ ++ pg|p|profile:gcrt1.o%s; \ ++ :crt1.o%s} \ ++ crti.o%s \ ++ %{static:crtbeginT.o%s; \ ++ shared|pie|static-pie:crtbeginS.o%s; \ ++ :crtbegin.o%s} \ ++ %{fvtable-verify=none:%s; \ ++ fvtable-verify=preinit:vtv_start_preinit.o%s; \ ++ fvtable-verify=std:vtv_start.o%s} \ ++ " CRTOFFLOADBEGIN ++#endif ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC GNU_USER_TARGET_STARTFILE_SPEC ++ ++/* Provide a ENDFILE_SPEC appropriate for GNU userspace. Here we tack on ++ the GNU userspace magical crtend.o file (see crtstuff.c) which ++ provides part of the support for getting C++ file-scope static ++ object constructed before entering `main', followed by a normal ++ GNU userspace "finalizer" file, `crtn.o'. */ ++ ++#if defined HAVE_LD_PIE ++#define GNU_USER_TARGET_ENDFILE_SPEC \ ++ "%{fvtable-verify=none:%s; \ ++ fvtable-verify=preinit:vtv_end_preinit.o%s; \ ++ fvtable-verify=std:vtv_end.o%s} \ ++ %{static:crtend.o%s; \ ++ shared|static-pie|" PIE_SPEC ":crtendS.o%s; \ ++ :crtend.o%s} \ ++ crtn.o%s \ ++ " CRTOFFLOADEND ++#else ++#define GNU_USER_TARGET_ENDFILE_SPEC \ ++ "%{fvtable-verify=none:%s; \ ++ fvtable-verify=preinit:vtv_end_preinit.o%s; \ ++ fvtable-verify=std:vtv_end.o%s} \ ++ %{static:crtend.o%s; \ ++ shared|pie|static-pie:crtendS.o%s; \ ++ :crtend.o%s} \ ++ crtn.o%s \ ++ " CRTOFFLOADEND ++#endif ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC GNU_USER_TARGET_ENDFILE_SPEC ++ ++/* This is for -profile to use -lc_p instead of -lc. */ ++#define GNU_USER_TARGET_CC1_SPEC "%{profile:-p}" ++#ifndef CC1_SPEC ++#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC ++#endif ++ ++/* The GNU C++ standard library requires that these macros be defined. */ ++#undef CPLUSPLUS_CPP_SPEC ++#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" ++ ++#define GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC \ ++ "%{shared:-lc} \ ++ %{!shared:%{profile:-lc_p}%{!profile:-lc}}" ++ ++#define GNU_USER_TARGET_LIB_SPEC \ ++ "%{pthread:-lpthread} " GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC ++ ++#undef LIB_SPEC ++#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC ++ ++#if defined(HAVE_LD_EH_FRAME_HDR) ++#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} " ++#endif ++ ++#undef LINK_GCC_C_SEQUENCE_SPEC ++#define LINK_GCC_C_SEQUENCE_SPEC \ ++ "%{static|static-pie:--start-group} %G %L \ ++ %{static|static-pie:--end-group}%{!static:%{!static-pie:%G}}" ++ ++/* Use --as-needed -lgcc_s for eh support. */ ++#ifdef HAVE_LD_AS_NEEDED ++#define USE_LD_AS_NEEDED 1 ++#endif ++ ++#define TARGET_POSIX_IO ++ ++#undef TARGET_LIBC_HAS_FUNCTION ++#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function ++ ++/* Link -lasan early on the command line. For -static-libasan, don't link ++ it for -shared link, the executable should be compiled with -static-libasan ++ in that case, and for executable link with --{,no-}whole-archive around ++ it to force everything into the executable. And similarly for -ltsan ++ and -llsan. */ ++#if defined(HAVE_LD_STATIC_DYNAMIC) ++#undef LIBASAN_EARLY_SPEC ++#define LIBASAN_EARLY_SPEC \ ++ "%{!shared:libasan_preinit%O%s} " \ ++ "%{static-libasan:%{!shared:" LD_STATIC_OPTION \ ++ " --whole-archive -lasan --no-whole-archive " LD_DYNAMIC_OPTION \ ++ "}}%{!static-libasan:-lasan}" ++#undef LIBTSAN_EARLY_SPEC ++#define LIBTSAN_EARLY_SPEC \ ++ "%{!shared:libtsan_preinit%O%s} " \ ++ "%{static-libtsan:%{!shared:" LD_STATIC_OPTION \ ++ " --whole-archive -ltsan --no-whole-archive " LD_DYNAMIC_OPTION \ ++ "}}%{!static-libtsan:-ltsan}" ++#undef LIBLSAN_EARLY_SPEC ++#define LIBLSAN_EARLY_SPEC \ ++ "%{!shared:liblsan_preinit%O%s} " \ ++ "%{static-liblsan:%{!shared:" LD_STATIC_OPTION \ ++ " --whole-archive -llsan --no-whole-archive " LD_DYNAMIC_OPTION \ ++ "}}%{!static-liblsan:-llsan}" ++#endif +diff --git a/gcc/config/sw_64/linux-elf.h b/gcc/config/sw_64/linux-elf.h +new file mode 100644 +index 000000000..79543910b +--- /dev/null ++++ b/gcc/config/sw_64/linux-elf.h +@@ -0,0 +1,54 @@ ++/* Definitions of target machine for GNU compiler ++ for Sw_64 Linux-based GNU systems using ELF. ++ Copyright (C) 1996-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#undef EXTRA_SPECS ++#define EXTRA_SPECS {"elf_dynamic_linker", ELF_DYNAMIC_LINKER}, ++ ++#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2" ++#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" ++#if DEFAULT_LIBC == LIBC_UCLIBC ++#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}" ++#elif DEFAULT_LIBC == LIBC_GLIBC ++#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}" ++#else ++#error "Unsupported DEFAULT_LIBC" ++#endif ++#define GNU_USER_DYNAMIC_LINKER \ ++ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER) ++ ++#define ELF_DYNAMIC_LINKER GNU_USER_DYNAMIC_LINKER ++ ++#define LINK_SPEC \ ++ "-m elf64sw_64 %{G*} %{relax:-relax} \ ++ %{O*:-O3} %{!O*:-O1} \ ++ %{shared:-shared} \ ++ %{!shared: \ ++ %{!static: \ ++ %{rdynamic:-export-dynamic} \ ++ -dynamic-linker %(elf_dynamic_linker)} \ ++ %{static:-static}}" ++ ++#undef LIB_SPEC ++#define LIB_SPEC \ ++ "%{pthread:-lpthread} " \ ++ "%{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} " ++ ++#define TARGET_ASM_FILE_END file_end_indicate_exec_stack +diff --git a/gcc/config/sw_64/linux.h b/gcc/config/sw_64/linux.h +new file mode 100644 +index 000000000..38b93ed18 +--- /dev/null ++++ b/gcc/config/sw_64/linux.h +@@ -0,0 +1,109 @@ ++/* Definitions of target machine for GNU compiler, ++ for Sw_64 Linux-based GNU systems. ++ Copyright (C) 1996-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#define TARGET_OS_CPP_BUILTINS() \ ++ do \ ++ { \ ++ builtin_define ("__gnu_linux__"); \ ++ builtin_define ("_LONGLONG"); \ ++ builtin_define_std ("linux"); \ ++ builtin_define_std ("unix"); \ ++ builtin_assert ("system=linux"); \ ++ builtin_assert ("system=unix"); \ ++ builtin_assert ("system=posix"); \ ++ /* The GNU C++ standard library requires this. */ \ ++ if (c_dialect_cxx ()) \ ++ builtin_define ("_GNU_SOURCE"); \ ++ } while (0) ++ ++#undef LIB_SPEC ++#define LIB_SPEC \ ++ "%{pthread:-lpthread} \ ++ %{shared:-lc} \ ++ %{!shared: %{profile:-lc_p}%{!profile:-lc}}" ++ ++#undef CPP_SPEC ++#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" ++ ++/* Show that we need a GP when profiling. */ ++#undef TARGET_PROFILING_NEEDS_GP ++#define TARGET_PROFILING_NEEDS_GP 1 ++ ++/* Don't care about faults in the prologue. */ ++#undef TARGET_CAN_FAULT_IN_PROLOGUE ++#define TARGET_CAN_FAULT_IN_PROLOGUE 1 ++ ++#undef WCHAR_TYPE ++#define WCHAR_TYPE "int" ++ ++#ifdef SINGLE_LIBC ++#define OPTION_GLIBC_P(opts) (DEFAULT_LIBC == LIBC_GLIBC) ++#define OPTION_UCLIBC_P(opts) (DEFAULT_LIBC == LIBC_UCLIBC) ++#define OPTION_BIONIC_P(opts) (DEFAULT_LIBC == LIBC_BIONIC) ++#undef OPTION_MUSL_P ++#define OPTION_MUSL_P(opts) (DEFAULT_LIBC == LIBC_MUSL) ++#else ++#define OPTION_GLIBC_P(opts) (linux_libc == LIBC_GLIBC) ++#define OPTION_UCLIBC_P(opts) (linux_libc == LIBC_UCLIBC) ++#define OPTION_BIONIC_P(opts) (linux_libc == LIBC_BIONIC) ++#undef OPTION_MUSL_P ++#define OPTION_MUSL_P(opts) (linux_libc == LIBC_MUSL) ++#endif ++#define OPTION_GLIBC OPTION_GLIBC_P (&global_options) ++#define OPTION_UCLIBC OPTION_UCLIBC_P (&global_options) ++#define OPTION_BIONIC OPTION_BIONIC_P (&global_options) ++#undef OPTION_MUSL ++#define OPTION_MUSL OPTION_MUSL_P (&global_options) ++ ++/* Determine what functions are present at the runtime; ++ this includes full c99 runtime and sincos. */ ++#undef TARGET_LIBC_HAS_FUNCTION ++#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function ++ ++#define TARGET_POSIX_IO ++ ++#define LINK_GCC_C_SEQUENCE_SPEC \ ++ "%{static|static-pie:--start-group} %G %L \ ++ %{static|static-pie:--end-group}%{!static:%{!static-pie:%G}}" ++ ++/* Use --as-needed -lgcc_s for eh support. */ ++#ifdef HAVE_LD_AS_NEEDED ++#define USE_LD_AS_NEEDED 1 ++#endif ++ ++/* Define if long doubles should be mangled as 'g'. */ ++#define TARGET_ALTERNATE_LONG_DOUBLE_MANGLING ++ ++/* -mcpu=native handling only makes sense with compiler running on ++ an Sw_64 chip. */ ++#if defined(__sw_64__) || defined(__sw_64) ++extern const char * ++host_detect_local_cpu (int argc, const char **argv); ++#define EXTRA_SPEC_FUNCTIONS {"local_cpu_detect", host_detect_local_cpu}, ++ ++#define MCPU_MTUNE_NATIVE_SPECS \ ++ " %{mcpu=native:%. */ ++ ++#define TARGET_OS_CPP_BUILTINS() \ ++ do \ ++ { \ ++ NETBSD_OS_CPP_BUILTINS_ELF (); \ ++ } while (0) ++ ++/* NetBSD doesn't use the LANGUAGE* built-ins. */ ++#undef SUBTARGET_LANGUAGE_CPP_BUILTINS ++#define SUBTARGET_LANGUAGE_CPP_BUILTINS() /* nothing */ ++ ++/* Show that we need a GP when profiling. */ ++#undef TARGET_PROFILING_NEEDS_GP ++#define TARGET_PROFILING_NEEDS_GP 1 ++ ++/* Provide a CPP_SPEC appropriate for NetBSD/sw_64. We use ++ this to pull in CPP specs that all NetBSD configurations need. */ ++ ++#undef CPP_SPEC ++#define CPP_SPEC NETBSD_CPP_SPEC ++ ++#undef EXTRA_SPECS ++#define EXTRA_SPECS \ ++ {"netbsd_link_spec", NETBSD_LINK_SPEC_ELF}, \ ++ {"netbsd_entry_point", NETBSD_ENTRY_POINT}, \ ++ {"netbsd_endfile_spec", NETBSD_ENDFILE_SPEC}, ++ ++/* Provide a LINK_SPEC appropriate for a NetBSD/sw_64 ELF target. */ ++ ++#undef LINK_SPEC ++#define LINK_SPEC \ ++ "%{G*} %{relax:-relax} \ ++ %{O*:-O3} %{!O*:-O1} \ ++ %(netbsd_link_spec)" ++ ++#define NETBSD_ENTRY_POINT "__start" ++ ++/* Provide an ENDFILE_SPEC appropriate for NetBSD/sw_64 ELF. Here we ++ add crtend.o, which provides part of the support for getting ++ C++ file-scope static objects deconstructed after exiting "main". ++ ++ We also need to handle the GCC option `-ffast-math'. */ ++ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC \ ++ "%{Ofast|ffast-math|funsafe-math-optimizations:crtfm%O%s} \ ++ %(netbsd_endfile_spec)" ++ ++#define HAVE_ENABLE_EXECUTE_STACK +diff --git a/gcc/config/sw_64/openbsd.h b/gcc/config/sw_64/openbsd.h +new file mode 100644 +index 000000000..6fca63ab4 +--- /dev/null ++++ b/gcc/config/sw_64/openbsd.h +@@ -0,0 +1,75 @@ ++/* Configuration file for an sw_64 OpenBSD target. ++ Copyright (C) 1999-2022 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++/* Controlling the compilation driver. */ ++#undef TARGET_DEFAULT ++#define TARGET_DEFAULT (MASK_FPREGS | MASK_IEEE | MASK_IEEE_CONFORMANT) ++ ++#define LINK_SPEC \ ++ "%{!shared:%{!nostdlib:%{!r*:%{!e*:-e __start}}}} \ ++ %{shared:-shared} %{R*} \ ++ %{static:-Bstatic} \ ++ %{!static:-Bdynamic} \ ++ %{rdynamic:-export-dynamic} \ ++ %{assert*} \ ++ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so}" ++ ++/* As an elf system, we need crtbegin/crtend stuff. */ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC \ ++ "\ ++ %{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} \ ++ %{!p:%{!static:crt0%O%s} %{static:%{nopie:crt0%O%s} \ ++ %{!nopie:rcrt0%O%s}}}} crtbegin%O%s} %{shared:crtbeginS%O%s}" ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC "%{!shared:crtend%O%s} %{shared:crtendS%O%s}" ++ ++/* run-time target specifications */ ++#define TARGET_OS_CPP_BUILTINS() \ ++ do \ ++ { \ ++ OPENBSD_OS_CPP_BUILTINS_ELF (); \ ++ OPENBSD_OS_CPP_BUILTINS_LP64 (); \ ++ } while (0) ++ ++/* Layout of source language data types. */ ++ ++/* This must agree with */ ++#undef SIZE_TYPE ++#define SIZE_TYPE "long unsigned int" ++ ++#undef PTRDIFF_TYPE ++#define PTRDIFF_TYPE "long int" ++ ++#undef INTMAX_TYPE ++#define INTMAX_TYPE "long long int" ++ ++#undef UINTMAX_TYPE ++#define UINTMAX_TYPE "long long unsigned int" ++ ++#undef WCHAR_TYPE ++#define WCHAR_TYPE "int" ++ ++#undef WCHAR_TYPE_SIZE ++#define WCHAR_TYPE_SIZE 32 ++ ++#undef WINT_TYPE ++#define WINT_TYPE "int" ++ ++#define LOCAL_LABEL_PREFIX "." +diff --git a/gcc/config/sw_64/predicates.md b/gcc/config/sw_64/predicates.md +new file mode 100644 +index 000000000..b22086aa9 +--- /dev/null ++++ b/gcc/config/sw_64/predicates.md +@@ -0,0 +1,653 @@ ++;; Predicate definitions for Sw64. ++;; Copyright (C) 2004-2022 Free Software Foundation, Inc. ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++;; Return 1 if OP is the zero constant for MODE. ++(define_predicate "const0_operand" ++ (and (match_code "const_int,const_wide_int,const_double,const_vector") ++ (match_test "op == CONST0_RTX (mode)"))) ++ ++;; Returns true if OP is either the constant zero or a register. ++(define_predicate "reg_or_0_operand" ++ (ior (match_operand 0 "register_operand") ++ (match_operand 0 "const0_operand"))) ++ ++;; Return 1 if OP is a constant in the range of 0-63 (for a shift) or ++;; any register. ++(define_predicate "reg_or_6bit_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "INTVAL (op) >= 0 && INTVAL (op) < 64") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if OP is a constant in the range of 0-31 (for a shift) or ++;; any register. ++(define_predicate "reg_or_5bit_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "INTVAL (op) >= 0 && INTVAL (op) < 32") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if OP is an 8-bit constant. ++(define_predicate "cint8_operand" ++ (and (match_code "const_int") ++ (match_test "INTVAL (op) >= 0 && INTVAL (op) < 256"))) ++ ++;; Return 1 if OP is an 8-bit constant or any register. ++(define_predicate "reg_or_8bit_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "INTVAL (op) >= 0 && INTVAL (op) < 256") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if OP is a constant or any register. ++(define_predicate "reg_or_cint_operand" ++ (ior (match_operand 0 "register_operand") ++ (match_operand 0 "const_int_operand"))) ++ ++;; Return 1 if the operand is a valid second operand to an add insn. ++(define_predicate "add_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "satisfies_constraint_K (op) || satisfies_constraint_L (op)") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if the operand is a valid second operand to a ++;; sign-extending add insn. ++(define_predicate "sext_add_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "satisfies_constraint_I (op) || satisfies_constraint_O (op)") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if the operand is a non-symbolic constant operand that ++;; does not satisfy add_operand. ++(define_predicate "non_add_const_operand" ++ (and (match_code "const_int,const_wide_int,const_double,const_vector") ++ (not (match_operand 0 "add_operand")))) ++ ++;; Return 1 if the operand is a non-symbolic, nonzero constant operand. ++(define_predicate "non_zero_const_operand" ++ (and (match_code "const_int,const_wide_int,const_double,const_vector") ++ (not (match_test "op == CONST0_RTX (mode)")))) ++ ++;; Return 1 if OP is the constant 1, 2 or 3. ++(define_predicate "const123_operand" ++ (and (match_code "const_int") ++ (match_test "IN_RANGE (INTVAL (op), 1, 3)"))) ++ ++;; Return 1 if OP is the constant 2 or 3. ++(define_predicate "const23_operand" ++ (and (match_code "const_int") ++ (match_test "INTVAL (op) == 2 || INTVAL (op) == 3"))) ++ ++;; Return 1 if OP is the constant 4 or 8. ++(define_predicate "const48_operand" ++ (and (match_code "const_int") ++ (match_test "INTVAL (op) == 4 || INTVAL (op) == 8"))) ++ ++;; Return 1 if OP is a valid first operand to an AND insn. ++(define_predicate "and_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 ++ || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100 ++ || zap_mask (INTVAL (op))") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if OP is a valid first operand to an IOR or XOR insn. ++(define_predicate "or_operand" ++ (if_then_else (match_code "const_int") ++ (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 ++ || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if OP is a constant that is the width, in bits, of an integral ++;; mode not larger than DImode. ++(define_predicate "mode_width_operand" ++ (match_code "const_int") ++{ ++ HOST_WIDE_INT i = INTVAL (op); ++ return i == 8 || i == 16 || i == 32 || i == 64; ++}) ++ ++;; Return 1 if OP is a constant that is a mask of ones of width of an ++;; integral machine mode not larger than DImode. ++(define_predicate "mode_mask_operand" ++ (match_code "const_int") ++{ ++ HOST_WIDE_INT value = INTVAL (op); ++ ++ if (value == 0xff) ++ return 1; ++ if (value == 0xffff) ++ return 1; ++ if (value == 0xffffffff) ++ return 1; ++ if (value == -1) ++ return 1; ++ ++ return 0; ++}) ++ ++;; Return 1 if OP is a multiple of 8 less than 64. ++(define_predicate "mul8_operand" ++ (match_code "const_int") ++{ ++ unsigned HOST_WIDE_INT i = INTVAL (op); ++ return i < 64 && i % 8 == 0; ++}) ++ ++;; Return 1 if OP is a hard floating-point register. ++(define_predicate "hard_fp_register_operand" ++ (match_operand 0 "register_operand") ++{ ++ if (SUBREG_P (op)) ++ op = SUBREG_REG (op); ++ return REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS; ++}) ++ ++;; Return 1 if OP is a hard general register. ++(define_predicate "hard_int_register_operand" ++ (match_operand 0 "register_operand") ++{ ++ if (SUBREG_P (op)) ++ op = SUBREG_REG (op); ++ return REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS; ++}) ++ ++;; Return 1 if OP is a valid operand for the source of a move insn. ++(define_predicate "input_operand" ++ (match_operand 0 "general_operand") ++{ ++ switch (GET_CODE (op)) ++ { ++ case LABEL_REF: ++ case SYMBOL_REF: ++ case CONST: ++ if (TARGET_EXPLICIT_RELOCS) ++ { ++ /* We don't split symbolic operands into something unintelligable ++ until after reload, but we do not wish non-small, non-global ++ symbolic operands to be reconstructed from their high/lo_sum ++ form. */ ++ return (small_symbolic_operand (op, mode) ++ || global_symbolic_operand (op, mode) ++ || gotdtp_symbolic_operand (op, mode) ++ || gottp_symbolic_operand (op, mode)); ++ } ++ /* VMS still has a 32-bit mode. */ ++ return mode == ptr_mode || mode == Pmode; ++ ++ case HIGH: ++ return (TARGET_EXPLICIT_RELOCS ++ && local_symbolic_operand (XEXP (op, 0), mode)); ++ ++ case REG: ++ return 1; ++ ++ case SUBREG: ++ if (register_operand (op, mode)) ++ return 1; ++ /* fall through */ ++ case MEM: ++ return ((TARGET_BWX || (mode != HImode && mode != QImode)) ++ && general_operand (op, mode)); ++ ++ case CONST_WIDE_INT: ++ case CONST_DOUBLE: ++ return op == CONST0_RTX (mode); ++ ++ case CONST_VECTOR: ++ if (reload_in_progress || reload_completed) ++ return sw_64_legitimate_constant_p (mode, op); ++ return op == CONST0_RTX (mode); ++ ++ case CONST_INT: ++ if (mode == QImode || mode == HImode) ++ return true; ++ if (reload_in_progress || reload_completed) ++ return sw_64_legitimate_constant_p (mode, op); ++ return add_operand (op, mode); ++ ++ default: ++ gcc_unreachable (); ++ } ++ return 0; ++}) ++ ++;; Return 1 if OP is a SYMBOL_REF for a function known to be in this ++;; file, and in the same section as the current function. ++ ++(define_predicate "samegp_function_operand" ++ (match_code "symbol_ref") ++{ ++ /* Easy test for recursion. */ ++ if (op == XEXP (DECL_RTL (current_function_decl), 0)) ++ return true; ++ ++ /* Functions that are not local can be overridden, and thus may ++ not share the same gp. */ ++ if (! SYMBOL_REF_LOCAL_P (op)) ++ return false; ++ ++ /* If -msmall-data is in effect, assume that there is only one GP ++ for the module, and so any local symbol has this property. We ++ need explicit relocations to be able to enforce this for symbols ++ not defined in this unit of translation, however. */ ++ if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA) ++ return true; ++ ++ /* Functions that are not external are defined in this UoT, ++ and thus must share the same gp. */ ++ return ! SYMBOL_REF_EXTERNAL_P (op); ++}) ++ ++;; Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. ++(define_predicate "direct_call_operand" ++ (match_operand 0 "samegp_function_operand") ++{ ++ /* If profiling is implemented via linker tricks, we can't jump ++ to the nogp alternate entry point. Note that crtl->profile ++ would not be correct, since that doesn't indicate if the target ++ function uses profiling. */ ++ /* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test, ++ but is approximately correct for the SYSV ABIs. Don't know ++ what to do for VMS, NT, or UMK. */ ++ if (!TARGET_PROFILING_NEEDS_GP && profile_flag) ++ return false; ++ ++ /* Must be a function. In some cases folks create thunks in static ++ data structures and then make calls to them. If we allow the ++ direct call, we'll get an error from the linker about !samegp reloc ++ against a symbol without a .prologue directive. */ ++ if (!SYMBOL_REF_FUNCTION_P (op)) ++ return false; ++ ++ /* Must be "near" so that the branch is assumed to reach. With ++ -msmall-text, this is assumed true of all local symbols. Since ++ we've already checked samegp, locality is already assured. */ ++ if (TARGET_SMALL_TEXT) ++ return true; ++ ++ return false; ++}) ++ ++;; Return 1 if OP is a valid operand for the MEM of a CALL insn. ++;; ++;; For TARGET_ABI_SYSV, we want to restrict to R27 or a pseudo. ++ ++(define_predicate "call_operand" ++ (ior (match_code "symbol_ref") ++ (and (match_code "reg") ++ (ior (not (match_test "TARGET_ABI_OSF")) ++ (not (match_test "HARD_REGISTER_P (op)")) ++ (match_test "REGNO (op) == R27_REG"))))) ++ ++;; Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing ++;; a (non-tls) variable known to be defined in this file. ++(define_predicate "local_symbolic_operand" ++ (match_code "label_ref,const,symbol_ref") ++{ ++ if (GET_CODE (op) == CONST ++ && GET_CODE (XEXP (op, 0)) == PLUS ++ && CONST_INT_P (XEXP (XEXP (op, 0), 1))) ++ op = XEXP (XEXP (op, 0), 0); ++ ++ if (GET_CODE (op) == LABEL_REF) ++ return 1; ++ ++ if (GET_CODE (op) != SYMBOL_REF) ++ return 0; ++ ++ return (SYMBOL_REF_LOCAL_P (op) ++ && !SYMBOL_REF_WEAK (op) ++ && !SYMBOL_REF_TLS_MODEL (op)); ++}) ++ ++;; Return true if OP is a SYMBOL_REF or CONST referencing a variable ++;; known to be defined in this file in the small data area. ++(define_predicate "small_symbolic_operand" ++ (match_code "const,symbol_ref") ++{ ++ HOST_WIDE_INT ofs = 0, max_ofs = 0; ++ ++ if (! TARGET_SMALL_DATA) ++ return false; ++ ++ if (GET_CODE (op) == CONST ++ && GET_CODE (XEXP (op, 0)) == PLUS ++ && CONST_INT_P (XEXP (XEXP (op, 0), 1))) ++ { ++ ofs = INTVAL (XEXP (XEXP (op, 0), 1)); ++ op = XEXP (XEXP (op, 0), 0); ++ } ++ ++ if (GET_CODE (op) != SYMBOL_REF) ++ return false; ++ ++ /* ??? There's no encode_section_info equivalent for the rtl ++ constant pool, so SYMBOL_FLAG_SMALL never gets set. */ ++ if (CONSTANT_POOL_ADDRESS_P (op)) ++ { ++ max_ofs = GET_MODE_SIZE (get_pool_mode (op)); ++ if (max_ofs > g_switch_value) ++ return false; ++ } ++ else if (SYMBOL_REF_LOCAL_P (op) ++ && SYMBOL_REF_SMALL_P (op) ++ && !SYMBOL_REF_WEAK (op) ++ && !SYMBOL_REF_TLS_MODEL (op)) ++ { ++ if (SYMBOL_REF_DECL (op)) ++ max_ofs = tree_to_uhwi (DECL_SIZE_UNIT (SYMBOL_REF_DECL (op))); ++ } ++ else ++ return false; ++ ++ /* Given that we know that the GP is always 8 byte aligned, we can ++ always adjust by 7 without overflowing. */ ++ if (max_ofs < 8) ++ max_ofs = 8; ++ ++ /* Since we know this is an object in a small data section, we know the ++ entire section is addressable via GP. We don't know where the section ++ boundaries are, but we know the entire object is within. */ ++ /* support -mgprel-size option. */ ++ /*return IN_RANGE (ofs, 0, max_ofs - 1);*/ ++ ++ if (sw_64_gprel_size == 16) ++ return IN_RANGE (ofs, 0, max_ofs - 1); ++ if (sw_64_gprel_size == 32) ++ return false; ++}) ++ ++;; Return true if OP is a SYMBOL_REF or CONST referencing a variable ++;; not known (or known not) to be defined in this file. ++(define_predicate "global_symbolic_operand" ++ (match_code "const,symbol_ref") ++{ ++ if (GET_CODE (op) == CONST ++ && GET_CODE (XEXP (op, 0)) == PLUS ++ && CONST_INT_P (XEXP (XEXP (op, 0), 1))) ++ op = XEXP (XEXP (op, 0), 0); ++ ++ if (GET_CODE (op) != SYMBOL_REF) ++ return 0; ++ ++ return ((!SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_WEAK (op)) ++ && !SYMBOL_REF_TLS_MODEL (op)); ++}) ++ ++;; Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref, ++;; possibly with an offset. ++(define_predicate "symbolic_operand" ++ (ior (match_code "symbol_ref,label_ref") ++ (and (match_code "const") ++ (match_code "plus" "0") ++ (match_code "symbol_ref,label_ref" "00") ++ (match_code "const_int" "01")))) ++ ++;; Return true if OP is valid for 16-bit DTP relative relocations. ++(define_predicate "dtp16_symbolic_operand" ++ (and (match_code "const") ++ (match_test "tls_symbolic_operand_1 (op, 16, UNSPEC_DTPREL)"))) ++ ++;; Return true if OP is valid for 32-bit DTP relative relocations. ++(define_predicate "dtp32_symbolic_operand" ++ (and (match_code "const") ++ (match_test "tls_symbolic_operand_1 (op, 32, UNSPEC_DTPREL)"))) ++ ++;; Return true if OP is valid for 64-bit DTP relative relocations. ++(define_predicate "gotdtp_symbolic_operand" ++ (and (match_code "const") ++ (match_test "tls_symbolic_operand_1 (op, 64, UNSPEC_DTPREL)"))) ++ ++;; Return true if OP is valid for 16-bit TP relative relocations. ++(define_predicate "tp16_symbolic_operand" ++ (and (match_code "const") ++ (match_test "tls_symbolic_operand_1 (op, 16, UNSPEC_TPREL)"))) ++ ++;; Return true if OP is valid for 32-bit TP relative relocations. ++(define_predicate "tp32_symbolic_operand" ++ (and (match_code "const") ++ (match_test "tls_symbolic_operand_1 (op, 32, UNSPEC_TPREL)"))) ++ ++;; Return true if OP is valid for 64-bit TP relative relocations. ++(define_predicate "gottp_symbolic_operand" ++ (and (match_code "const") ++ (match_test "tls_symbolic_operand_1 (op, 64, UNSPEC_TPREL)"))) ++ ++;; Return 1 if this memory address is a known aligned register plus ++;; a constant. It must be a valid address. This means that we can do ++;; this as an aligned reference plus some offset. ++;; ++;; Take into account what reload will do. Oh god this is awful. ++;; The horrible comma-operator construct below is to prevent genrecog ++;; from thinking that this predicate accepts REG and SUBREG. We don't ++;; use recog during reload, so pretending these codes are accepted ++;; pessimizes things a tad. ++ ++(define_special_predicate "aligned_memory_operand" ++ (ior (match_test "op = resolve_reload_operand (op), 0") ++ (match_code "mem")) ++{ ++ rtx base; ++ int offset; ++ ++ if (MEM_ALIGN (op) >= 32) ++ return 1; ++ ++ op = XEXP (op, 0); ++ ++ /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) ++ sorts of constructs. Dig for the real base register. */ ++ if (reload_in_progress ++ && GET_CODE (op) == PLUS ++ && GET_CODE (XEXP (op, 0)) == PLUS) ++ { ++ base = XEXP (XEXP (op, 0), 0); ++ offset = INTVAL (XEXP (op, 1)); ++ } ++ else ++ { ++ if (! memory_address_p (mode, op)) ++ return 0; ++ if (GET_CODE (op) == PLUS) ++ { ++ base = XEXP (op, 0); ++ offset = INTVAL (XEXP (op, 1)); ++ } ++ else ++ { ++ base = op; ++ offset = 0; ++ } ++ } ++ ++ if (offset % GET_MODE_SIZE (mode)) ++ return 0; ++ ++ return (REG_P (base) && REGNO_POINTER_ALIGN (REGNO (base)) >= 32); ++}) ++ ++;; Similar, but return 1 if OP is a MEM which is not alignable. ++ ++(define_special_predicate "unaligned_memory_operand" ++ (ior (match_test "op = resolve_reload_operand (op), 0") ++ (match_code "mem")) ++{ ++ rtx base; ++ int offset; ++ ++ if (MEM_ALIGN (op) >= 32) ++ return 0; ++ ++ op = XEXP (op, 0); ++ ++ /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) ++ sorts of constructs. Dig for the real base register. */ ++ if (reload_in_progress ++ && GET_CODE (op) == PLUS ++ && GET_CODE (XEXP (op, 0)) == PLUS) ++ { ++ base = XEXP (XEXP (op, 0), 0); ++ offset = INTVAL (XEXP (op, 1)); ++ } ++ else ++ { ++ if (! memory_address_p (mode, op)) ++ return 0; ++ if (GET_CODE (op) == PLUS) ++ { ++ base = XEXP (op, 0); ++ offset = INTVAL (XEXP (op, 1)); ++ } ++ else ++ { ++ base = op; ++ offset = 0; ++ } ++ } ++ ++ if (offset % GET_MODE_SIZE (mode)) ++ return 1; ++ ++ return (REG_P (base) && REGNO_POINTER_ALIGN (REGNO (base)) < 32); ++}) ++ ++;; Return 1 if OP is any memory location. During reload a pseudo matches. ++(define_special_predicate "any_memory_operand" ++ (match_code "mem,reg,subreg") ++{ ++ if (SUBREG_P (op)) ++ op = SUBREG_REG (op); ++ ++ if (MEM_P (op)) ++ return true; ++ if (reload_in_progress && REG_P (op)) ++ { ++ unsigned regno = REGNO (op); ++ if (HARD_REGISTER_NUM_P (regno)) ++ return false; ++ else ++ return reg_renumber[regno] < 0; ++ } ++ ++ return false; ++}) ++ ++;; Returns 1 if OP is not an eliminable register. ++;; ++;; This exists to cure a pathological failure in the s8addq (et al) patterns, ++;; ++;; long foo () { long t; bar(); return (long) &t * 26107; } ++;; ++;; which run afoul of a hack in reload to cure a (presumably) similar ++;; problem with lea-type instructions on other targets. But there is ++;; one of us and many of them, so work around the problem by selectively ++;; preventing combine from making the optimization. ++ ++(define_predicate "reg_not_elim_operand" ++ (match_operand 0 "register_operand") ++{ ++ if (SUBREG_P (op)) ++ op = SUBREG_REG (op); ++ return op != frame_pointer_rtx && op != arg_pointer_rtx; ++}) ++ ++;; Accept a register, but not a subreg of any kind. This allows us to ++;; avoid pathological cases in reload wrt data movement common in ++;; int->fp conversion. */ ++(define_predicate "reg_no_subreg_operand" ++ (and (match_code "reg") ++ (match_operand 0 "register_operand"))) ++ ++;; Return 1 if OP is a valid Sw_64 comparison operator for "cbranch" ++;; instructions. ++(define_predicate "sw_64_cbranch_operator" ++ (ior (match_operand 0 "ordered_comparison_operator") ++ (match_code "ordered,unordered"))) ++ ++;; Return 1 if OP is a valid Sw_64 comparison operator for "cmp" style ++;; instructions. ++(define_predicate "sw_64_comparison_operator" ++ (match_code "eq,le,lt,leu,ltu")) ++ ++;; Similarly, but with swapped operands. ++(define_predicate "sw_64_swapped_comparison_operator" ++ (match_code "eq,ge,gt,gtu")) ++ ++;; Return 1 if OP is a valid Sw_64 comparison operator against zero ++;; for "bcc" style instructions. ++(define_predicate "sw_64_zero_comparison_operator" ++ (match_code "eq,ne,le,lt,leu,ltu")) ++ ++;; Return 1 if OP is a signed comparison operation. ++(define_predicate "signed_comparison_operator" ++ (match_code "eq,ne,le,lt,ge,gt")) ++ ++;; Return 1 if OP is a valid Sw_64 floating point comparison operator. ++(define_predicate "sw_64_fp_comparison_operator" ++ (match_code "eq,le,lt,unordered")) ++ ++;; Return 1 if this is a divide or modulus operator. ++(define_predicate "divmod_operator" ++ (match_code "div,mod,udiv,umod")) ++ ++;; Return 1 if this is a float->int conversion operator. ++(define_predicate "fix_operator" ++ (match_code "fix,unsigned_fix")) ++ ++;; Recognize an addition operation that includes a constant. Used to ++;; convince reload to canonize (plus (plus reg c1) c2) during register ++;; elimination. ++ ++(define_predicate "addition_operation" ++ (and (match_code "plus") ++ (match_test "register_operand (XEXP (op, 0), mode) ++ && satisfies_constraint_K (XEXP (op, 1))"))) ++ ++;; For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a ++;; small symbolic operand until after reload. At which point we need ++;; to replace (mem (symbol_ref)) with (mem (lo_sum $29 symbol_ref)) ++;; so that sched2 has the proper dependency information. */ ++(define_predicate "some_small_symbolic_operand" ++ (match_code "set,parallel,prefetch,unspec,unspec_volatile") ++{ ++ /* Avoid search unless necessary. */ ++ if (!TARGET_EXPLICIT_RELOCS || !reload_completed) ++ return false; ++ return some_small_symbolic_operand_int (op); ++}) ++ ++;; Accept a register, or a memory if BWX is enabled. ++(define_predicate "reg_or_bwx_memory_operand" ++ (ior (match_operand 0 "register_operand") ++ (and (match_test "TARGET_BWX") ++ (match_operand 0 "memory_operand")))) ++ ++;; Accept a memory whose address is only a register. ++(define_predicate "mem_noofs_operand" ++ (and (match_code "mem") ++ (match_code "reg" "0"))) ++ ++;; Accept a register, or any immediate. ++(define_predicate "reg_or_immediate_operand" ++ (ior (match_operand 0 "register_operand") ++ (match_operand 0 "immediate_operand"))) ++ ++(define_predicate "sw_64_branch_combination" ++ (match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu")) ++ ++(define_predicate "sw_64_swapped_branch_combination" ++ (match_code "ne,ge,gt,geu,gtu")) +diff --git a/gcc/config/sw_64/sw6.md b/gcc/config/sw_64/sw6.md +new file mode 100644 +index 000000000..c8971ec34 +--- /dev/null ++++ b/gcc/config/sw_64/sw6.md +@@ -0,0 +1,180 @@ ++;; Scheduling description for Sw64 SW6. ++;; Copyright (C) 2002-2022 Free Software Foundation, Inc. ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++; SW6 can issue 4 insns per clock. It's out-of-order, so this isn't ++; expected to help over-much, but a precise description can be important ++; for software pipelining. ++; ++; SW6 has two symmetric pairs ("clusters") of two asymmetric integer ++; units ("upper" and "lower"), yielding pipe names U0, U1, L0, L1. ++; ++; ??? The clusters have independent register files that are re-synced ++; every cycle. Thus there is one additional cycle of latency between ++; insns issued on different clusters. Possibly model that by duplicating ++; all EBOX insn_reservations that can issue to either cluster, increasing ++; all latencies by one, and adding bypasses within the cluster. ++; ++; ??? In addition, instruction order affects cluster issue. ++ ++(define_automaton "sw6_0,sw6_1") ++(define_cpu_unit "sw6_u0,sw6_u1,sw6_l0,sw6_l1" "sw6_0") ++(define_reservation "sw6_u" "sw6_u0|sw6_u1") ++(define_reservation "sw6_l" "sw6_l0|sw6_l1") ++(define_reservation "sw6_ebox" "sw6_u|sw6_l") ++ ++(define_cpu_unit "sw6_fa" "sw6_1") ++(define_cpu_unit "sw6_fm,sw6_fst0,sw6_fst1" "sw6_0") ++(define_reservation "sw6_fst" "sw6_fst0|sw6_fst1") ++ ++; Assume type "multi" single issues. ++(define_insn_reservation "sw6_multi" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "multi")) ++ "sw6_u0+sw6_u1+sw6_l0+sw6_l1+sw6_fa+sw6_fm+sw6_fst0+sw6_fst1") ++ ++; Integer loads take at least 3 clocks, and only issue to lower units. ++; adjust_cost still factors in user-specified memory latency, so return 1 here. ++(define_insn_reservation "sw6_ild" 4 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "ild,ldsym,ld_l")) ++ "sw6_l") ++ ++(define_insn_reservation "sw6_ist" 4 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "ist,st_c")) ++ "sw6_l") ++ ++(define_insn_reservation "sw6_mb" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "mb")) ++ "sw6_l1") ++ ++; FP loads take at least 4 clocks. adjust_cost still factors ++; in user-specified memory latency, so return 2 here. ++(define_insn_reservation "sw6_fld" 2 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "fld")) ++ "sw6_l") ++ ++; The FPU communicates with memory and the integer register file ++; via two fp store units. We need a slot in the fst immediately, and ++; a slot in LOW after the operand data is ready. At which point the ++; data may be moved either to the store queue or the integer register ++; file and the insn retired. ++ ++(define_insn_reservation "sw6_fst" 3 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "fst")) ++ "sw6_fst,nothing,sw6_l") ++ ++; Arithmetic goes anywhere. ++(define_insn_reservation "sw6_arith" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "iadd,ilog,icmp")) ++ "sw6_ebox") ++ ++; Motion video insns also issue only to U0, and take three ticks. ++(define_insn_reservation "sw6_mvi" 3 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "mvi")) ++ "sw6_u0") ++ ++; Shifts issue to upper units. ++(define_insn_reservation "sw6_shift" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "shift")) ++ "sw6_u") ++ ++; Multiplies issue only to U1, and all take 4 ticks. ++(define_insn_reservation "sw6_imul" 4 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "imul")) ++ "sw6_u1") ++ ++; Conditional moves decompose into two independent primitives, each taking ++; one cycle. Since sw6 is out-of-order, we can't see anything but two cycles. ++(define_insn_reservation "sw6_icmov" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "icmov")) ++ "sw6_ebox,sw6_ebox") ++ ++; Integer branches issue to upper units ++(define_insn_reservation "sw6_ibr" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "ibr,callpal")) ++ "sw6_u") ++ ++; Calls only issue to L0. ++(define_insn_reservation "sw6_jsr" 1 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "call")) ++ "sw6_l0") ++ ++; Ftoi/itof only issue to lower pipes. ++(define_insn_reservation "sw6_itof" 4 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "itof")) ++ "sw6_l") ++ ++(define_insn_reservation "sw6_ftoi" 4 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "ftoi")) ++ "sw6_fst,nothing,sw6_l") ++ ++(define_insn_reservation "sw6_fmul" 6 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "fmul")) ++ "sw6_fm") ++ ++(define_insn_reservation "sw6_fadd" 6 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "fadd,fcpys,fbr")) ++ "sw6_fa") ++ ++(define_bypass 8 "sw6_fmul,sw6_fadd" "sw6_fst,sw6_ftoi") ++ ++(define_insn_reservation "sw6_fcmov" 2 ++ (and (eq_attr "tune" "sw6") ++ (eq_attr "type" "fcmov")) ++ "sw6_fa,nothing*3,sw6_fa") ++ ++(define_bypass 4 "sw6_fcmov" "sw6_fst,sw6_ftoi") ++ ++(define_insn_reservation "sw6_fdivsf" 19 ++ (and (eq_attr "tune" "sw6") ++ (and (eq_attr "type" "fdiv") ++ (eq_attr "opsize" "si"))) ++ "sw6_fa*9") ++ ++(define_insn_reservation "sw6_fdivdf" 34 ++ (and (eq_attr "tune" "sw6") ++ (and (eq_attr "type" "fdiv") ++ (eq_attr "opsize" "di"))) ++ "sw6_fa*12") ++(define_insn_reservation "sw6_sqrtsf" 19 ++ (and (eq_attr "tune" "sw6") ++ (and (eq_attr "type" "fsqrt") ++ (eq_attr "opsize" "si"))) ++ "sw6_fa*15") ++ ++(define_insn_reservation "sw6_sqrtdf" 33 ++ (and (eq_attr "tune" "sw6") ++ (and (eq_attr "type" "fsqrt") ++ (eq_attr "opsize" "di"))) ++ "sw6_fa*30") +diff --git a/gcc/config/sw_64/sw8.md b/gcc/config/sw_64/sw8.md +new file mode 100644 +index 000000000..7946cdddd +--- /dev/null ++++ b/gcc/config/sw_64/sw8.md +@@ -0,0 +1,181 @@ ++;; Scheduling description for Sw64 SW8. ++;; Copyright (C) 2002-2022 Free Software Foundation, Inc. ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++; SW6 can issue 4 insns per clock. It's out-of-order, so this isn't ++; expected to help over-much, but a precise description can be important ++; for software pipelining. ++; ++; SW6 has two symmetric pairs ("clusters") of two asymmetric integer ++; units ("upper" and "lower"), yielding pipe names U0, U1, L0, L1. ++; ++; ??? The clusters have independent register files that are re-synced ++; every cycle. Thus there is one additional cycle of latency between ++; insns issued on different clusters. Possibly model that by duplicating ++; all EBOX insn_reservations that can issue to either cluster, increasing ++; all latencies by one, and adding bypasses within the cluster. ++; ++; ??? In addition, instruction order affects cluster issue. ++ ++(define_automaton "sw8_0,sw8_1") ++(define_cpu_unit "sw8_u0,sw8_u1,sw8_l0,sw8_l1" "sw8_0") ++(define_reservation "sw8_u" "sw8_u0|sw8_u1") ++(define_reservation "sw8_l" "sw8_l0|sw8_l1") ++(define_reservation "sw8_ebox" "sw8_u|sw8_l") ++ ++(define_cpu_unit "sw8_fa" "sw8_1") ++(define_cpu_unit "sw8_fm,sw8_fst0,sw8_fst1" "sw8_0") ++(define_reservation "sw8_fst" "sw8_fst0|sw8_fst1") ++ ++; Assume type "multi" single issues. ++(define_insn_reservation "sw8_multi" 1 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "multi")) ++ "sw8_u0+sw8_u1+sw8_l0+sw8_l1+sw8_fa+sw8_fm+sw8_fst0+sw8_fst1") ++ ++; Integer loads take at least 3 clocks, and only issue to lower units. ++; adjust_cost still factors in user-specified memory latency, so return 1 here. ++(define_insn_reservation "sw8_ild" 4 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "ild,ldsym,ld_l")) ++ "sw8_l") ++ ++(define_insn_reservation "sw8_ist" 4 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "ist,st_c")) ++ "sw8_l") ++ ++(define_insn_reservation "sw8_mb" 1 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "mb")) ++ "sw8_l1") ++ ++; FP loads take at least 4 clocks. adjust_cost still factors ++; in user-specified memory latency, so return 2 here. ++(define_insn_reservation "sw8_fld" 2 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "fld")) ++ "sw8_l") ++ ++; The FPU communicates with memory and the integer register file ++; via two fp store units. We need a slot in the fst immediately, and ++; a slot in LOW after the operand data is ready. At which point the ++; data may be moved either to the store queue or the integer register ++; file and the insn retired. ++ ++(define_insn_reservation "sw8_fst" 3 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "fst")) ++ "sw8_fst,nothing,sw8_l") ++ ++; Arithmetic goes anywhere. ++(define_insn_reservation "sw8_arith" 1 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "iadd,ilog,icmp")) ++ "sw8_ebox") ++ ++; Motion video insns also issue only to U0, and take three ticks. ++(define_insn_reservation "sw8_mvi" 3 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "mvi")) ++ "sw8_u0") ++ ++; Shifts issue to upper units. ++(define_insn_reservation "sw8_shift" 1 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "shift")) ++ "sw8_u") ++ ++; Multiplies issue only to U1, and all take 7 ticks. ++(define_insn_reservation "sw8_imul" 7 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "imul")) ++ "sw8_u1") ++ ++; Conditional moves decompose into two independent primitives, each taking ++; one cycle. Since sw8 is out-of-order, we can't see anything but two cycles. ++(define_insn_reservation "sw8_icmov" 2 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "icmov")) ++ "sw8_ebox,sw8_ebox") ++ ++; Integer branches issue to upper units ++(define_insn_reservation "sw8_ibr" 1 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "ibr,callpal")) ++ "sw8_u") ++ ++; Calls only issue to L0. ++(define_insn_reservation "sw8_jsr" 1 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "call")) ++ "sw8_l0") ++ ++; Ftoi/itof only issue to lower pipes. ++(define_insn_reservation "sw8_itof" 3 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "itof")) ++ "sw8_l") ++ ++(define_insn_reservation "sw8_ftoi" 3 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "ftoi")) ++ "sw8_fst,nothing,sw8_l") ++ ++(define_insn_reservation "sw8_fmul" 4 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "fmul")) ++ "sw8_fm") ++ ++(define_insn_reservation "sw8_fadd" 4 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "fadd,fcpys,fbr")) ++ "sw8_fa") ++ ++(define_bypass 6 "sw8_fmul,sw8_fadd" "sw8_fst,sw8_ftoi") ++ ++(define_insn_reservation "sw8_fcmov" 8 ++ (and (eq_attr "tune" "sw8") ++ (eq_attr "type" "fcmov")) ++ "sw8_fa,nothing*3,sw8_fa") ++ ++(define_bypass 10 "sw8_fcmov" "sw8_fst,sw8_ftoi") ++ ++(define_insn_reservation "sw8_fdivsf" 12 ++ (and (eq_attr "tune" "sw8") ++ (and (eq_attr "type" "fdiv") ++ (eq_attr "opsize" "si"))) ++ "sw8_fa*9") ++ ++(define_insn_reservation "sw8_fdivdf" 15 ++ (and (eq_attr "tune" "sw8") ++ (and (eq_attr "type" "fdiv") ++ (eq_attr "opsize" "di"))) ++ "sw8_fa*12") ++ ++(define_insn_reservation "sw8_sqrtsf" 18 ++ (and (eq_attr "tune" "sw8") ++ (and (eq_attr "type" "fsqrt") ++ (eq_attr "opsize" "si"))) ++ "sw8_fa*15") ++ ++(define_insn_reservation "sw8_sqrtdf" 33 ++ (and (eq_attr "tune" "sw8") ++ (and (eq_attr "type" "fsqrt") ++ (eq_attr "opsize" "di"))) ++ "sw8_fa*30") +diff --git a/gcc/config/sw_64/sw_64-modes.def b/gcc/config/sw_64/sw_64-modes.def +new file mode 100644 +index 000000000..ce55aca9a +--- /dev/null ++++ b/gcc/config/sw_64/sw_64-modes.def +@@ -0,0 +1,27 @@ ++/* Sw_64 extra machine modes. ++ Copyright (C) 2003-2022 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++/* 128-bit floating point. This gets reset in sw_64_option_override ++ if VAX float format is in use. */ ++FLOAT_MODE (TF, 16, ieee_quad_format); ++ ++/* Vector modes. */ ++VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */ ++VECTOR_MODE (INT, QI, 4); /* V4QI */ ++VECTOR_MODE (INT, QI, 2); /* V2QI */ +diff --git a/gcc/config/sw_64/sw_64-passes.def b/gcc/config/sw_64/sw_64-passes.def +new file mode 100644 +index 000000000..36c384c6f +--- /dev/null ++++ b/gcc/config/sw_64/sw_64-passes.def +@@ -0,0 +1,21 @@ ++/* Description of target passes for Sw64 ++ Copyright (C) 2016-2022 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 3, or (at your option) any later ++version. ++ ++GCC is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++ INSERT_PASS_AFTER (pass_convert_to_eh_region_ranges, 1, pass_handle_trap_shadows); ++ INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_align_insns); +diff --git a/gcc/config/sw_64/sw_64-protos.h b/gcc/config/sw_64/sw_64-protos.h +new file mode 100644 +index 000000000..42cc6be0d +--- /dev/null ++++ b/gcc/config/sw_64/sw_64-protos.h +@@ -0,0 +1,152 @@ ++/* Prototypes for sw_64.c functions used in the md file & elsewhere. ++ Copyright (C) 1999-2022 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++extern int sw_64_next_sequence_number; ++ ++extern void ++literal_section (void); ++extern int zap_mask (HOST_WIDE_INT); ++extern bool ++direct_return (void); ++ ++extern HOST_WIDE_INT ++sw_64_initial_elimination_offset (unsigned int, unsigned int); ++extern void ++sw_64_expand_prologue (void); ++extern void ++sw_64_expand_epilogue (void); ++extern void ++sw_64_output_filename (FILE *, const char *); ++ ++extern bool sw_64_legitimate_constant_p (machine_mode, rtx); ++extern rtx ++sw_64_legitimize_reload_address (rtx, machine_mode, int, int, int); ++ ++extern rtx split_small_symbolic_operand (rtx); ++ ++extern void ++get_aligned_mem (rtx, rtx *, rtx *); ++extern rtx get_unaligned_address (rtx); ++extern rtx get_unaligned_offset (rtx, HOST_WIDE_INT); ++extern enum reg_class sw_64_preferred_reload_class (rtx, enum reg_class); ++ ++extern void sw_64_set_memflags (rtx, rtx); ++extern bool ++sw_64_split_const_mov (machine_mode, rtx *); ++extern bool ++sw_64_expand_mov (machine_mode, rtx *); ++extern bool ++sw_64_expand_mov_nobwx (machine_mode, rtx *); ++extern void ++sw_64_expand_movmisalign (machine_mode, rtx *); ++extern void sw_64_emit_floatuns (rtx[]); ++extern rtx sw_64_emit_conditional_move (rtx, machine_mode); ++extern void ++sw_64_split_tmode_pair (rtx[], machine_mode, bool); ++extern void sw_64_split_tfmode_frobsign (rtx[], rtx (*) (rtx, rtx, rtx)); ++extern void ++sw_64_expand_unaligned_load (rtx, rtx, HOST_WIDE_INT, HOST_WIDE_INT, int); ++extern void sw_64_expand_unaligned_store (rtx, rtx, HOST_WIDE_INT, ++ HOST_WIDE_INT); ++extern int sw_64_expand_block_move (rtx[]); ++extern int sw_64_expand_block_clear (rtx[]); ++extern rtx sw_64_expand_zap_mask (HOST_WIDE_INT); ++extern void sw_64_expand_builtin_vector_binop (rtx (*) (rtx, rtx, rtx), ++ machine_mode, rtx, rtx, rtx); ++ ++extern rtx ++sw_64_return_addr (int, rtx); ++extern rtx ++sw_64_gp_save_rtx (void); ++extern void ++sw_64_initialize_trampoline (rtx, rtx, rtx, int, int, int); ++ ++extern rtx sw_64_va_arg (tree, tree); ++ ++extern void ++sw_64_start_function (FILE *, const char *, tree); ++extern void ++sw_64_end_function (FILE *, const char *, tree); ++ ++extern bool sw_64_find_lo_sum_using_gp (rtx); ++ ++extern void ++sw_64_emit_rsqrt (rtx, rtx, bool); ++ ++#ifdef REAL_VALUE_TYPE ++extern int ++check_float_value (machine_mode, REAL_VALUE_TYPE *, int); ++#endif ++ ++#ifdef RTX_CODE ++extern void sw_64_emit_conditional_branch (rtx[], machine_mode); ++extern bool sw_64_emit_setcc (rtx[], machine_mode); ++extern int sw_64_split_conditional_move (enum rtx_code, rtx, rtx, rtx, rtx); ++extern void sw_64_emit_xfloating_arith (enum rtx_code, rtx[]); ++extern void sw_64_emit_xfloating_cvt (enum rtx_code, rtx[]); ++extern void sw_64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, ++ enum memmodel); ++extern void ++sw_64_split_compare_and_swap (rtx op[]); ++extern void ++sw_64_expand_compare_and_swap_12 (rtx op[]); ++extern void ++sw_64_split_compare_and_swap_12 (rtx op[]); ++extern void ++sw_64_split_atomic_exchange (rtx op[]); ++extern void ++sw_64_expand_atomic_exchange_12 (rtx op[]); ++extern void ++sw_64_split_atomic_exchange_12 (rtx op[]); ++#endif ++ ++extern void ++sw_64_split_atomic_cas (rtx op[]); ++extern void ++sw_64_split_atomic_cas_12 (rtx op[]); ++ ++extern rtx ++sw_64_use_linkage (rtx, bool, bool); ++ ++extern rtx unicosmk_add_call_info_word (rtx); ++ ++extern bool some_small_symbolic_operand_int (rtx); ++extern int ++tls_symbolic_operand_1 (rtx, int, int); ++extern rtx resolve_reload_operand (rtx); ++ ++namespace gcc { ++class context; ++} ++class rtl_opt_pass; ++ ++extern rtl_opt_pass * ++make_pass_handle_trap_shadows (gcc::context *); ++extern rtl_opt_pass * ++make_pass_align_insns (gcc::context *); ++ ++extern void ++sw_64_emit_swdiv (rtx, rtx, rtx, bool); ++extern rtx gen_move_reg (rtx); ++ ++extern void ++sw_64_declare_object (FILE *, const char *, const char *, const char *, ++ ...) ATTRIBUTE_PRINTF_4; ++extern void ++sw_64_declare_object_name (FILE *, const char *, tree); +diff --git a/gcc/config/sw_64/sw_64.cc b/gcc/config/sw_64/sw_64.cc +new file mode 100644 +index 000000000..d2387100e +--- /dev/null ++++ b/gcc/config/sw_64/sw_64.cc +@@ -0,0 +1,10076 @@ ++/* Subroutines used for code generation on the Sw64. ++ Copyright (C) 1992-2022 Free Software Foundation, Inc. ++ Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ GCC is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GCC; see the file COPYING3. If not see ++ . */ ++ ++#define IN_TARGET_CODE 1 ++ ++#include "config.h" ++#include "system.h" ++#include "coretypes.h" ++#include "backend.h" ++#include "target.h" ++#include "rtl.h" ++#include "tree.h" ++#include "stringpool.h" ++#include "attribs.h" ++#include "memmodel.h" ++#include "gimple.h" ++#include "df.h" ++#include "predict.h" ++#include "tm_p.h" ++#include "ssa.h" ++#include "expmed.h" ++#include "optabs.h" ++#include "regs.h" ++#include "emit-rtl.h" ++#include "recog.h" ++#include "diagnostic-core.h" ++#include "alias.h" ++#include "fold-const.h" ++#include "stor-layout.h" ++#include "calls.h" ++#include "varasm.h" ++#include "output.h" ++#include "insn-attr.h" ++#include "explow.h" ++#include "expr.h" ++#include "reload.h" ++#include "except.h" ++#include "common/common-target.h" ++#include "debug.h" ++#include "langhooks.h" ++#include "cfgrtl.h" ++#include "tree-pass.h" ++#include "context.h" ++#include "gimple-iterator.h" ++#include "gimplify.h" ++#include "tree-stdarg.h" ++#include "tm-constrs.h" ++#include "libfuncs.h" ++#include "opts.h" ++#include "builtins.h" ++#include "rtl-iter.h" ++#include "asan.h" ++ ++#include "flags.h" ++/* This file should be included last. */ ++#include "target-def.h" ++ ++/* Specify which cpu to schedule for. */ ++enum processor_type sw_64_tune; ++ ++/* Which cpu we're generating code for. */ ++enum processor_type sw_64_cpu; ++ ++static const char *const sw_64_cpu_name[] = { ++ "sw6", "sw8a" ++}; ++ ++/* Specify how accurate floating-point traps need to be. */ ++ ++enum sw_64_trap_precision sw_64_tp; ++ ++/* Specify the floating-point rounding mode. */ ++ ++enum sw_64_fp_rounding_mode sw_64_fprm; ++ ++/* Specify which things cause traps. */ ++ ++enum sw_64_fp_trap_mode sw_64_fptm; ++ ++/* Nonzero if inside of a function, because the Sw_64 asm can't ++ handle .files inside of functions. */ ++ ++static int inside_function = FALSE; ++ ++/* The number of cycles of latency we should assume on memory reads. */ ++ ++static int sw_64_memory_latency = 3; ++ ++/* Whether the function needs the GP. */ ++ ++static int sw_64_function_needs_gp; ++ ++/* The assembler name of the current function. */ ++ ++static const char *sw_64_fnname; ++ ++/* The next explicit relocation sequence number. */ ++extern GTY (()) int sw_64_next_sequence_number; ++int sw_64_next_sequence_number = 1; ++ ++int stfp3_flag; ++extern int flag_fpcr_set; ++/* The literal and gpdisp sequence numbers for this insn, as printed ++ by %# and %* respectively. */ ++extern GTY (()) int sw_64_this_literal_sequence_number; ++extern GTY (()) int sw_64_this_gpdisp_sequence_number; ++int sw_64_this_literal_sequence_number; ++int sw_64_this_gpdisp_sequence_number; ++ ++/* Costs of various operations on the different architectures. */ ++ ++struct sw_64_rtx_cost_data ++{ ++ unsigned char fp_add; ++ unsigned char fp_mult; ++ unsigned char fp_div_sf; ++ unsigned char fp_div_df; ++ unsigned char int_mult_si; ++ unsigned char int_mult_di; ++ unsigned char int_shift; ++ unsigned char int_cmov; ++ unsigned short int_div; ++}; ++static struct sw_64_rtx_cost_data const sw_64_rtx_cost_data[PROCESSOR_MAX + 1] = ++ { ++ { ++ /* sw6a */ ++ COSTS_N_INSNS (6), /* fp_add */ ++ COSTS_N_INSNS (6), /* fp_mult */ ++ COSTS_N_INSNS (19), /* fp_div_sf */ ++ COSTS_N_INSNS (19), /* fp_div_df */ ++ COSTS_N_INSNS (4), /* int_mult_si */ ++ COSTS_N_INSNS (4), /* int_mult_di */ ++ COSTS_N_INSNS (1), /* int_shift */ ++ COSTS_N_INSNS (1), /* int_cmov */ ++ COSTS_N_INSNS (83), /* int_div */ ++ }, ++ { ++ /* sw8a */ ++ COSTS_N_INSNS (6), /* fp_add */ ++ COSTS_N_INSNS (6), /* fp_mult */ ++ COSTS_N_INSNS (19), /* fp_div_sf */ ++ COSTS_N_INSNS (19), /* fp_div_df */ ++ COSTS_N_INSNS (4), /* int_mult_si */ ++ COSTS_N_INSNS (4), /* int_mult_di */ ++ COSTS_N_INSNS (1), /* int_shift */ ++ COSTS_N_INSNS (1), /* int_cmov */ ++ COSTS_N_INSNS (20), /* int_div */ ++ }, ++ }; ++ ++/* Similar but tuned for code size instead of execution latency. The ++ extra +N is fractional cost tuning based on latency. It's used to ++ encourage use of cheaper insns like shift, but only if there's just ++ one of them. */ ++ ++static struct sw_64_rtx_cost_data const sw_64_rtx_cost_size = { ++ COSTS_N_INSNS (1), /* fp_add */ ++ COSTS_N_INSNS (1), /* fp_mult */ ++ COSTS_N_INSNS (1), /* fp_div_sf */ ++ COSTS_N_INSNS (1) + 1, /* fp_div_df */ ++ COSTS_N_INSNS (1) + 1, /* int_mult_si */ ++ COSTS_N_INSNS (1) + 2, /* int_mult_di */ ++ COSTS_N_INSNS (1), /* int_shift */ ++ COSTS_N_INSNS (1), /* int_cmov */ ++ COSTS_N_INSNS (6), /* int_div */ ++}; ++ ++/* Get the number of args of a function in one of two ways. */ ++#define NUM_ARGS crtl->args.info ++ ++#define REG_PV 27 ++#define REG_RA 26 ++ ++/* Declarations of static functions. */ ++static struct machine_function * ++sw_64_init_machine_status (void); ++static rtx ++sw_64_emit_xfloating_compare (enum rtx_code *, rtx, rtx); ++static void ++sw_64_handle_trap_shadows (void); ++static void ++sw_64_align_insns (void); ++static void ++sw_64_override_options_after_change (void); ++ ++static unsigned int ++rest_of_handle_trap_shadows (void) ++{ ++ sw_64_handle_trap_shadows (); ++ return 0; ++} ++ ++namespace { ++ ++const pass_data pass_data_handle_trap_shadows = { ++ RTL_PASS, ++ "trap_shadows", /* name */ ++ OPTGROUP_NONE, /* optinfo_flags */ ++ TV_NONE, /* tv_id */ ++ 0, /* properties_required */ ++ 0, /* properties_provided */ ++ 0, /* properties_destroyed */ ++ 0, /* todo_flags_start */ ++ TODO_df_finish, /* todo_flags_finish */ ++}; ++ ++class pass_handle_trap_shadows : public rtl_opt_pass ++{ ++public: ++ pass_handle_trap_shadows (gcc::context *ctxt) ++ : rtl_opt_pass (pass_data_handle_trap_shadows, ctxt) ++ {} ++ ++ /* opt_pass methods: */ ++ virtual bool gate (function *) ++ { ++ return sw_64_tp != SW_64_TP_PROG || flag_exceptions; ++ } ++ ++ virtual unsigned int execute (function *) ++ { ++ return rest_of_handle_trap_shadows (); ++ } ++ ++}; // class pass_handle_trap_shadows ++ ++} // namespace ++ ++rtl_opt_pass * ++make_pass_handle_trap_shadows (gcc::context *ctxt) ++{ ++ return new pass_handle_trap_shadows (ctxt); ++} ++ ++static unsigned int ++rest_of_align_insns (void) ++{ ++ sw_64_align_insns (); ++ return 0; ++} ++ ++namespace { ++ ++const pass_data pass_data_align_insns = { ++ RTL_PASS, ++ "align_insns", /* name */ ++ OPTGROUP_NONE, /* optinfo_flags */ ++ TV_NONE, /* tv_id */ ++ 0, /* properties_required */ ++ 0, /* properties_provided */ ++ 0, /* properties_destroyed */ ++ 0, /* todo_flags_start */ ++ TODO_df_finish, /* todo_flags_finish */ ++}; ++ ++class pass_align_insns : public rtl_opt_pass ++{ ++public: ++ pass_align_insns (gcc::context *ctxt) ++ : rtl_opt_pass (pass_data_align_insns, ctxt) ++ {} ++ ++ /* opt_pass methods: */ ++ virtual bool gate (function *) ++ { ++ /* Due to the number of extra memb insns, don't bother fixing up ++ alignment when trap precision is instruction. Moreover, we can ++ only do our job when sched2 is run. */ ++ return ((sw_64_tune != PROCESSOR_SW6 && sw_64_tune != PROCESSOR_SW8) ++ && optimize && !optimize_size && sw_64_tp != SW_64_TP_INSN ++ && flag_schedule_insns_after_reload); ++ } ++ ++ virtual unsigned int execute (function *) ++ { ++ return rest_of_align_insns (); ++ } ++ ++}; // class pass_align_insns ++ ++} // namespace ++ ++rtl_opt_pass * ++make_pass_align_insns (gcc::context *ctxt) ++{ ++ return new pass_align_insns (ctxt); ++} ++ ++#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING ++/* Implement TARGET_MANGLE_TYPE. */ ++ ++static const char * ++sw_64_mangle_type (const_tree type) ++{ ++ if (TYPE_MAIN_VARIANT (type) == long_double_type_node ++ && TARGET_LONG_DOUBLE_128) ++ return "g"; ++ ++ /* For all other types, use normal C++ mangling. */ ++ return NULL; ++} ++#endif ++ ++/* Parse target option strings. */ ++ ++static void ++sw_64_option_override (void) ++{ ++ static const struct cpu_table ++ { ++ const char *const name; ++ const enum processor_type processor; ++ const int flags; ++ const unsigned short line_size; /* in bytes */ ++ const unsigned short l1_size; /* in kb. */ ++ const unsigned short l2_size; /* in kb. */ ++ } cpu_table[] = { ++ /* SW6/LCA45 had 8k L1 caches; SW6f had 16k L1 caches. ++ * SW6/SW6a had 128k to 16M 32-byte direct Bcache. LCA45 ++ * had 64k to 8M 8-byte direct Bcache. */ ++ {"sw6a", PROCESSOR_SW6, MASK_BWX | MASK_CIX | MASK_FIX | MASK_SW6A, 128, 32, ++ 512}, ++ {"sw6b", PROCESSOR_SW6, MASK_BWX | MASK_CIX | MASK_FIX | MASK_SW6B, 128, 32, ++ 512}, ++ {"sw4d", PROCESSOR_SW6, MASK_BWX | MASK_CIX | MASK_FIX | MASK_SW4D, 128, 32, ++ 512}, ++ {"sw8a", PROCESSOR_SW8, MASK_BWX | MASK_CIX | MASK_FIX | MASK_SW8A, 128, 32, ++ 512}, ++ }; ++ ++ int const ct_size = ARRAY_SIZE (cpu_table); ++ int line_size = 0, l1_size = 0, l2_size = 0; ++ int i; ++ ++#ifdef SUBTARGET_OVERRIDE_OPTIONS ++ SUBTARGET_OVERRIDE_OPTIONS; ++#endif ++ ++ /* Default to full IEEE compliance mode for Go language. */ ++ if (strcmp (lang_hooks.name, "GNU Go") == 0 ++ && !(target_flags_explicit & MASK_IEEE)) ++ target_flags |= MASK_IEEE; ++ ++ sw_64_fprm = SW_64_FPRM_NORM; ++ sw_64_tp = SW_64_TP_PROG; ++ sw_64_fptm = SW_64_FPTM_N; ++ ++ if (TARGET_IEEE) ++ { ++ sw_64_tp = SW_64_TP_INSN; ++ sw_64_fptm = SW_64_FPTM_SU; ++ } ++ if (TARGET_IEEE_WITH_INEXACT) ++ { ++ sw_64_tp = SW_64_TP_INSN; ++ sw_64_fptm = SW_64_FPTM_SUI; ++ } ++ if (TARGET_IEEE_MAIN) ++ { ++ sw_64_tp = SW_64_TP_INSN; ++ sw_64_fptm = SW_64_FPTM_SU; ++ } ++ ++ if (sw_64_tp_string) ++ { ++ if (!strcmp (sw_64_tp_string, "p")) ++ sw_64_tp = SW_64_TP_PROG; ++ else if (!strcmp (sw_64_tp_string, "f")) ++ sw_64_tp = SW_64_TP_FUNC; ++ else if (!strcmp (sw_64_tp_string, "i")) ++ sw_64_tp = SW_64_TP_INSN; ++ else ++ error ("bad value %qs for %<-mtrap-precision%> switch", ++ sw_64_tp_string); ++ } ++ ++ if (sw_64_fprm_string) ++ { ++ if (!strcmp (sw_64_fprm_string, "n")) ++ sw_64_fprm = SW_64_FPRM_NORM; ++ else if (!strcmp (sw_64_fprm_string, "m")) ++ sw_64_fprm = SW_64_FPRM_MINF; ++ else if (!strcmp (sw_64_fprm_string, "c")) ++ sw_64_fprm = SW_64_FPRM_CHOP; ++ else if (!strcmp (sw_64_fprm_string, "d")) ++ sw_64_fprm = SW_64_FPRM_DYN; ++ else ++ error ("bad value %qs for %<-mfp-rounding-mode%> switch", ++ sw_64_fprm_string); ++ } ++ ++ if (sw_64_fptm_string) ++ { ++ if (strcmp (sw_64_fptm_string, "n") == 0) ++ sw_64_fptm = SW_64_FPTM_N; ++ else if (strcmp (sw_64_fptm_string, "u") == 0) ++ sw_64_fptm = SW_64_FPTM_U; ++ else if (strcmp (sw_64_fptm_string, "su") == 0) ++ sw_64_fptm = SW_64_FPTM_SU; ++ else if (strcmp (sw_64_fptm_string, "sui") == 0) ++ sw_64_fptm = SW_64_FPTM_SUI; ++ else ++ error ("bad value %qs for %<-mfp-trap-mode%> switch", ++ sw_64_fptm_string); ++ } ++ ++ if (sw_64_cpu_string) ++ { ++ for (i = 0; i < ct_size; i++) ++ if (!strcmp (sw_64_cpu_string, cpu_table[i].name)) ++ { ++ sw_64_tune = sw_64_cpu = cpu_table[i].processor; ++ line_size = cpu_table[i].line_size; ++ l1_size = cpu_table[i].l1_size; ++ l2_size = cpu_table[i].l2_size; ++ target_flags &= ~(MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX ++ | MASK_SW6A | MASK_SW6B | MASK_SW4D | MASK_SW8A); ++ target_flags |= cpu_table[i].flags; ++ break; ++ } ++ if (i == ct_size) ++ error ("bad value %qs for %<-mcpu%> switch", sw_64_cpu_string); ++ } ++ ++ if (sw_64_tune_string) ++ { ++ for (i = 0; i < ct_size; i++) ++ if (!strcmp (sw_64_tune_string, cpu_table[i].name)) ++ { ++ sw_64_tune = cpu_table[i].processor; ++ line_size = cpu_table[i].line_size; ++ l1_size = cpu_table[i].l1_size; ++ l2_size = cpu_table[i].l2_size; ++ break; ++ } ++ if (i == ct_size) ++ error ("bad value %qs for %<-mtune%> switch", sw_64_tune_string); ++ } ++ if (line_size) ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_l1_cache_line_size, line_size); ++ if (l1_size) ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_l1_cache_size, l1_size); ++ if (l2_size) ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_l2_cache_size, l2_size); ++ ++ // generate prefetch for cases like stream add ++ if (flag_sw_prefetch_add == 1) ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_prefetch_min_insn_to_mem_ratio, 2); ++ /* This cannot reside in s390_option_optimization_table since HAVE_prefetch ++ requires the arch flags to be evaluated already. Since prefetching ++ is beneficial on s390, we enable it if available. */ ++ if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch) ++ flag_prefetch_loop_arrays = 1; ++ ++ /* set simultaneous prefetches and latency for sw ++ * * need add some conditions to decide what the cpu kind */ ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_simultaneous_prefetches, 8); ++ ++ if (flag_sw_non_temporal == 1) ++ /* set this param from default 3 to 2 to turn on prefetch and ++ * non-temporal for cases like c[i] = a[i] + b[i] in stream. */ ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_prefetch_min_insn_to_mem_ratio, 2); ++ ++ if (flag_sw_prefetch_unroll == 1) ++ { ++ SET_OPTION_IF_UNSET (&global_options, &global_options_set, ++ param_max_unrolled_insns, 400); ++ } ++ /* Do some sanity checks on the above options. */ ++ ++ if ((sw_64_fptm == SW_64_FPTM_SU || sw_64_fptm == SW_64_FPTM_SUI) ++ && sw_64_tp != SW_64_TP_INSN && sw_64_cpu != PROCESSOR_SW6 ++ && sw_64_cpu != PROCESSOR_SW8) ++ { ++ warning (0, "fp software completion requires %<-mtrap-precision=i%>"); ++ sw_64_tp = SW_64_TP_INSN; ++ } ++ ++ if (sw_64_cpu == PROCESSOR_SW6 || sw_64_cpu == PROCESSOR_SW8) ++ { ++ /* Except for SW6 pass 1 (not released), we always have precise ++ arithmetic traps. Which means we can do software completion ++ without minding trap shadows. */ ++ sw_64_tp = SW_64_TP_PROG; ++ } ++ ++ if (TARGET_FLOAT_VAX) ++ { ++ if (sw_64_fprm == SW_64_FPRM_MINF || sw_64_fprm == SW_64_FPRM_DYN) ++ { ++ warning (0, "rounding mode not supported for VAX floats"); ++ sw_64_fprm = SW_64_FPRM_NORM; ++ } ++ if (sw_64_fptm == SW_64_FPTM_SUI) ++ { ++ warning (0, "trap mode not supported for VAX floats"); ++ sw_64_fptm = SW_64_FPTM_SU; ++ } ++ if (target_flags_explicit & MASK_LONG_DOUBLE_128) ++ warning (0, "128-bit long double not supported for VAX floats"); ++ target_flags &= ~MASK_LONG_DOUBLE_128; ++ } ++ ++ { ++ char *end; ++ int lat; ++ ++ if (!sw_64_mlat_string) ++ sw_64_mlat_string = "L1"; ++ ++ if (ISDIGIT ((unsigned char) sw_64_mlat_string[0]) ++ && (lat = strtol (sw_64_mlat_string, &end, 10), *end == '\0')) ++ ; ++ else if ((sw_64_mlat_string[0] == 'L' || sw_64_mlat_string[0] == 'l') ++ && ISDIGIT ((unsigned char) sw_64_mlat_string[1]) ++ && sw_64_mlat_string[2] == '\0') ++ { ++ static int cache_latency[][4] = { ++ {3, 12, 30}, /* sw6 -- Bcache from DS20 LMbench. */ ++ {4, 15, 90}, /* sw6b -- Bcache from DS20 LMbench. */ ++ {3, 7, 11}, /* sw8a -- Bcache from DS20 LMbench. */ ++ }; ++ if (flag_sw_rtx_cost) ++ { ++ cache_latency[sw_64_tune][0] = 3; ++ cache_latency[sw_64_tune][1] = 7; ++ cache_latency[sw_64_tune][2] = 11; ++ } ++ lat = sw_64_mlat_string[1] - '0'; ++ if (lat <= 0 || lat > 3 || cache_latency[sw_64_tune][lat - 1] == -1) ++ { ++ warning (0, "L%d cache latency unknown for %s", lat, ++ sw_64_cpu_name[sw_64_tune]); ++ lat = 3; ++ } ++ else ++ lat = cache_latency[sw_64_tune][lat - 1]; ++ } ++ else if (!strcmp (sw_64_mlat_string, "main")) ++ { ++ /* Most current memories have about 370ns latency. This is ++ a reasonable guess for a fast cpu. */ ++ lat = 150; ++ } ++ else ++ { ++ warning (0, "bad value %qs for %<-mmemory-latency%>", ++ sw_64_mlat_string); ++ lat = 3; ++ } ++ ++ sw_64_memory_latency = lat; ++ } ++ ++ /* Default the definition of "small data" to 8 bytes. */ ++ if (!OPTION_SET_P (g_switch_value)) ++ g_switch_value = 8; ++ ++ /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */ ++ if (flag_pic == 1) ++ target_flags |= MASK_SMALL_DATA; ++ else if (flag_pic == 2) ++ target_flags &= ~MASK_SMALL_DATA; ++ ++ sw_64_override_options_after_change (); ++ ++ /* Register variables and functions with the garbage collector. */ ++ ++ /* Set up function hooks. */ ++ init_machine_status = sw_64_init_machine_status; ++ ++ /* Tell the compiler when we're using VAX floating point. */ ++ if (TARGET_FLOAT_VAX) ++ { ++ REAL_MODE_FORMAT (SFmode) = &vax_f_format; ++ REAL_MODE_FORMAT (DFmode) = &vax_g_format; ++ REAL_MODE_FORMAT (TFmode) = NULL; ++ } ++ ++#ifdef TARGET_DEFAULT_LONG_DOUBLE_128 ++ if (!(target_flags_explicit & MASK_LONG_DOUBLE_128)) ++ target_flags |= MASK_LONG_DOUBLE_128; ++#endif ++} ++ ++/* Implement targetm.override_options_after_change. */ ++ ++static void ++sw_64_override_options_after_change (void) ++{ ++ /* Align labels and loops for optimal branching. */ ++ /* ??? Kludge these by not doing anything if we don't optimize. */ ++ if (optimize > 0) ++ { ++ if (flag_align_loops && !str_align_loops) ++ str_align_loops = "16"; ++ if (flag_align_jumps && !str_align_jumps) ++ str_align_jumps = "16"; ++ } ++ if (flag_align_functions && !str_align_functions) ++ str_align_functions = "16"; ++} ++ ++/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */ ++ ++int ++zap_mask (HOST_WIDE_INT value) ++{ ++ int i; ++ ++ for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++, value >>= 8) ++ if ((value & 0xff) != 0 && (value & 0xff) != 0xff) ++ return 0; ++ ++ return 1; ++} ++ ++/* Return true if OP is valid for a particular TLS relocation. ++ We are already guaranteed that OP is a CONST. */ ++ ++int ++tls_symbolic_operand_1 (rtx op, int size, int unspec) ++{ ++ op = XEXP (op, 0); ++ ++ if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec) ++ return 0; ++ op = XVECEXP (op, 0, 0); ++ ++ if (GET_CODE (op) != SYMBOL_REF) ++ return 0; ++ ++ switch (SYMBOL_REF_TLS_MODEL (op)) ++ { ++ case TLS_MODEL_LOCAL_DYNAMIC: ++ return unspec == UNSPEC_DTPREL && size == sw_64_tls_size; ++ case TLS_MODEL_INITIAL_EXEC: ++ return unspec == UNSPEC_TPREL && size == 64; ++ case TLS_MODEL_LOCAL_EXEC: ++ return unspec == UNSPEC_TPREL && size == sw_64_tls_size; ++ default: ++ gcc_unreachable (); ++ } ++} ++ ++/* Used by aligned_memory_operand and unaligned_memory_operand to ++ resolve what reload is going to do with OP if it's a register. */ ++ ++rtx ++resolve_reload_operand (rtx op) ++{ ++ if (reload_in_progress) ++ { ++ rtx tmp = op; ++ if (SUBREG_P (tmp)) ++ tmp = SUBREG_REG (tmp); ++ if (REG_P (tmp) && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) ++ { ++ op = reg_equiv_memory_loc (REGNO (tmp)); ++ if (op == 0) ++ return 0; ++ } ++ } ++ return op; ++} ++ ++/* The scalar modes supported differs from the default check-what-c-supports ++ version in that sometimes TFmode is available even when long double ++ indicates only DFmode. */ ++ ++static bool ++sw_64_scalar_mode_supported_p (scalar_mode mode) ++{ ++ switch (mode) ++ { ++ case E_QImode: ++ case E_HImode: ++ case E_SImode: ++ case E_DImode: ++ case E_TImode: /* via optabs.cc */ ++ return true; ++ ++ case E_SFmode: ++ case E_DFmode: ++ return true; ++ ++ case E_TFmode: ++ return TARGET_HAS_XFLOATING_LIBS; ++ ++ default: ++ return false; ++ } ++} ++ ++/* Sw_64 implements a couple of integer vector mode operations when ++ TARGET_MAX is enabled. We do not check TARGET_MAX here, however, ++ which allows the vectorizer to operate on e.g. move instructions, ++ or when expand_vector_operations can do something useful. */ ++ ++static bool ++sw_64_vector_mode_supported_p (machine_mode mode) ++{ ++ return mode == V8QImode || mode == V4HImode || mode == V2SImode; ++} ++ ++/* Return the TLS model to use for SYMBOL. */ ++ ++static enum tls_model ++tls_symbolic_operand_type (rtx symbol) ++{ ++ enum tls_model model; ++ ++ if (GET_CODE (symbol) != SYMBOL_REF) ++ return TLS_MODEL_NONE; ++ model = SYMBOL_REF_TLS_MODEL (symbol); ++ ++ /* Local-exec with a 64-bit size is the same code as initial-exec. */ ++ if (model == TLS_MODEL_LOCAL_EXEC && sw_64_tls_size == 64) ++ model = TLS_MODEL_INITIAL_EXEC; ++ ++ return model; ++} ++ ++/* Return true if the function DECL will share the same GP as any ++ function in the current unit of translation. */ ++ ++static bool ++decl_has_samegp (const_tree decl) ++{ ++ /* Functions that are not local can be overridden, and thus may ++ not share the same gp. */ ++ if (!(*targetm.binds_local_p) (decl)) ++ return false; ++ ++ /* If -msmall-data is in effect, assume that there is only one GP ++ for the module, and so any local symbol has this property. We ++ need explicit relocations to be able to enforce this for symbols ++ not defined in this unit of translation, however. */ ++ if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA) ++ return true; ++ ++ /* Functions that are not external are defined in this UoT. */ ++ /* ??? Irritatingly, static functions not yet emitted are still ++ marked "external". Apply this to non-static functions only. */ ++ return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl); ++} ++ ++/* Return true if EXP should be placed in the small data section. */ ++ ++static bool ++sw_64_in_small_data_p (const_tree exp) ++{ ++ /* We want to merge strings, so we never consider them small data. */ ++ if (TREE_CODE (exp) == STRING_CST) ++ return false; ++ ++ /* Functions are never in the small data area. Duh. */ ++ if (TREE_CODE (exp) == FUNCTION_DECL) ++ return false; ++ ++ /* COMMON symbols are never small data. */ ++ if (TREE_CODE (exp) == VAR_DECL && DECL_COMMON (exp)) ++ return false; ++ ++ if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) ++ { ++ const char *section = DECL_SECTION_NAME (exp); ++ if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0) ++ return true; ++ } ++ else ++ { ++ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp)); ++ ++ /* If this is an incomplete type with size 0, then we can't put it ++ in sdata because it might be too big when completed. */ ++ if (size > 0 && size <= g_switch_value) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* legitimate_address_p recognizes an RTL expression that is a valid ++ memory address for an instruction. The MODE argument is the ++ machine mode for the MEM expression that wants to use this address. ++ ++ For Sw_64, we have either a constant address or the sum of a ++ register and a constant address, or just a register. For DImode, ++ any of those forms can be surrounded with an AND that clear the ++ low-order three bits; this is an "unaligned" access. */ ++ ++static bool ++sw_64_legitimate_address_p (machine_mode mode, rtx x, bool strict) ++{ ++ /* If this is an ldl_u type address, discard the outer AND. */ ++ if (mode == DImode && GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1)) ++ && INTVAL (XEXP (x, 1)) == -8) ++ x = XEXP (x, 0); ++ ++ /* Discard non-paradoxical subregs. */ ++ if (SUBREG_P (x) ++ && (GET_MODE_SIZE (GET_MODE (x)) ++ < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) ++ x = SUBREG_REG (x); ++ ++ /* Unadorned general registers are valid. */ ++ if (REG_P (x) ++ && (strict ? STRICT_REG_OK_FOR_BASE_P (x) ++ : NONSTRICT_REG_OK_FOR_BASE_P (x))) ++ return true; ++ ++ /* Constant addresses (i.e. +/- 32k) are valid. */ ++ if (CONSTANT_ADDRESS_P (x)) ++ return true; ++ ++ if ((GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC ++ || GET_CODE (x) == POST_MODIFY) ++ && (TARGET_SW8A) ++ && (strict ? STRICT_REG_OK_FOR_BASE_P (XEXP (x, 0)) ++ : NONSTRICT_REG_OK_FOR_BASE_P (XEXP (x, 0)))) ++ return true; ++ /* Register plus a small constant offset is valid. */ ++ if (GET_CODE (x) == PLUS) ++ { ++ rtx ofs = XEXP (x, 1); ++ x = XEXP (x, 0); ++ ++ /* Discard non-paradoxical subregs. */ ++ if (SUBREG_P (x) ++ && (GET_MODE_SIZE (GET_MODE (x)) ++ < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) ++ x = SUBREG_REG (x); ++ ++ if (REG_P (x)) ++ { ++ if (!strict && NONSTRICT_REG_OK_FP_BASE_P (x) && CONST_INT_P (ofs)) ++ return true; ++ if ((strict ? STRICT_REG_OK_FOR_BASE_P (x) ++ : NONSTRICT_REG_OK_FOR_BASE_P (x)) ++ && CONSTANT_ADDRESS_P (ofs)) ++ return true; ++ } ++ } ++ ++ /* If we're managing explicit relocations, LO_SUM is valid, as are small ++ data symbols. Avoid explicit relocations of modes larger than word ++ mode since i.e. $LC0+8($1) can fold around +/- 32k offset. */ ++ else if (TARGET_EXPLICIT_RELOCS && GET_MODE_SIZE (mode) <= UNITS_PER_WORD) ++ { ++ if (small_symbolic_operand (x, Pmode)) ++ return true; ++ ++ if (GET_CODE (x) == LO_SUM) ++ { ++ rtx ofs = XEXP (x, 1); ++ x = XEXP (x, 0); ++ ++ /* Discard non-paradoxical subregs. */ ++ if (SUBREG_P (x) ++ && (GET_MODE_SIZE (GET_MODE (x)) ++ < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) ++ x = SUBREG_REG (x); ++ ++ /* Must have a valid base register. */ ++ if (!(REG_P (x) ++ && (strict ? STRICT_REG_OK_FOR_BASE_P (x) ++ : NONSTRICT_REG_OK_FOR_BASE_P (x)))) ++ return false; ++ ++ /* The symbol must be local. */ ++ if (local_symbolic_operand (ofs, Pmode) ++ || dtp32_symbolic_operand (ofs, Pmode) ++ || tp32_symbolic_operand (ofs, Pmode)) ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++/* Build the SYMBOL_REF for __tls_get_addr. */ ++ ++static GTY (()) rtx tls_get_addr_libfunc; ++ ++static rtx ++get_tls_get_addr (void) ++{ ++ if (!tls_get_addr_libfunc) ++ tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr"); ++ return tls_get_addr_libfunc; ++} ++ ++/* Try machine-dependent ways of modifying an illegitimate address ++ to be legitimate. If we find one, return the new, valid address. */ ++ ++static rtx ++sw_64_legitimize_address_1 (rtx x, rtx scratch, machine_mode mode) ++{ ++ HOST_WIDE_INT addend; ++ ++ /* If the address is (plus reg const_int) and the CONST_INT is not a ++ valid offset, compute the high part of the constant and add it to ++ the register. Then our address is (plus temp low-part-const). */ ++ if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)) ++ && !CONSTANT_ADDRESS_P (XEXP (x, 1))) ++ { ++ addend = INTVAL (XEXP (x, 1)); ++ x = XEXP (x, 0); ++ goto split_addend; ++ } ++ ++ /* If the address is (const (plus FOO const_int)), find the low-order ++ part of the CONST_INT. Then load FOO plus any high-order part of the ++ CONST_INT into a register. Our address is (plus reg low-part-const). ++ This is done to reduce the number of GOT entries. */ ++ if (can_create_pseudo_p () && GET_CODE (x) == CONST ++ && GET_CODE (XEXP (x, 0)) == PLUS && CONST_INT_P (XEXP (XEXP (x, 0), 1))) ++ { ++ addend = INTVAL (XEXP (XEXP (x, 0), 1)); ++ x = force_reg (Pmode, XEXP (XEXP (x, 0), 0)); ++ goto split_addend; ++ } ++ ++ /* If we have a (plus reg const), emit the load as in (2), then add ++ the two registers, and finally generate (plus reg low-part-const) as ++ our address. */ ++ if (can_create_pseudo_p () && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) ++ && GET_CODE (XEXP (x, 1)) == CONST ++ && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS ++ && CONST_INT_P (XEXP (XEXP (XEXP (x, 1), 0), 1))) ++ { ++ addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1)); ++ x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0), ++ XEXP (XEXP (XEXP (x, 1), 0), 0), NULL_RTX, 1, ++ OPTAB_LIB_WIDEN); ++ goto split_addend; ++ } ++ ++ /* If this is a local symbol, split the address into HIGH/LO_SUM parts. ++ Avoid modes larger than word mode since i.e. $LC0+8($1) can fold ++ around +/- 32k offset. */ ++ if (TARGET_EXPLICIT_RELOCS && GET_MODE_SIZE (mode) <= UNITS_PER_WORD ++ && symbolic_operand (x, Pmode)) ++ { ++ rtx r0, r16, eqv, tga, tp, dest, seq; ++ rtx_insn *insn; ++ ++ switch (tls_symbolic_operand_type (x)) ++ { ++ case TLS_MODEL_NONE: ++ break; ++ ++ case TLS_MODEL_GLOBAL_DYNAMIC: { ++ start_sequence (); ++ ++ r0 = gen_rtx_REG (Pmode, 0); ++ r16 = gen_rtx_REG (Pmode, 16); ++ tga = get_tls_get_addr (); ++ dest = gen_reg_rtx (Pmode); ++ seq = GEN_INT (sw_64_next_sequence_number++); ++ if (sw_64_tls_gd == 16) ++ { ++ emit_insn ( ++ gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq)); ++ } ++ else if (sw_64_tls_gd == 32) ++ { ++ eqv ++ = gen_rtx_UNSPEC (Pmode, ++ gen_rtvec (3, pic_offset_table_rtx, x, seq), ++ UNSPEC_TLSRELGOT); ++ // eqv = gen_rtx_CONST (Pmode, eqv); ++ emit_insn (gen_rtx_SET (r16, eqv)); ++ emit_insn (gen_movdi_er_tlsgd (r16, r16, x, seq)); ++ } ++ rtx val = gen_call_value_osf_tlsgd (r0, tga, seq); ++ insn = emit_call_insn (val); ++ RTL_CONST_CALL_P (insn) = 1; ++ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16); ++ ++ insn = get_insns (); ++ end_sequence (); ++ ++ emit_libcall_block (insn, dest, r0, x); ++ return dest; ++ } ++ ++ case TLS_MODEL_LOCAL_DYNAMIC: { ++ start_sequence (); ++ ++ r0 = gen_rtx_REG (Pmode, 0); ++ r16 = gen_rtx_REG (Pmode, 16); ++ tga = get_tls_get_addr (); ++ scratch = gen_reg_rtx (Pmode); ++ seq = GEN_INT (sw_64_next_sequence_number++); ++ if (sw_64_tls_ldm == 16) ++ { ++ emit_insn ( ++ gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq)); ++ } ++ else if (sw_64_tls_ldm == 32) ++ { ++ eqv ++ = gen_rtx_UNSPEC (Pmode, ++ gen_rtvec (3, pic_offset_table_rtx, x, seq), ++ UNSPEC_TLSRELGOT); ++ // eqv = gen_rtx_CONST (Pmode, eqv); ++ emit_insn (gen_rtx_SET (r16, eqv)); ++ emit_insn (gen_movdi_er_tlsldm (r16, r16, seq)); ++ } ++ rtx val = gen_call_value_osf_tlsldm (r0, tga, seq); ++ insn = emit_call_insn (val); ++ RTL_CONST_CALL_P (insn) = 1; ++ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16); ++ ++ insn = get_insns (); ++ end_sequence (); ++ ++ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), ++ UNSPEC_TLSLDM_CALL); ++ emit_libcall_block (insn, scratch, r0, eqv); ++ ++ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL); ++ eqv = gen_rtx_CONST (Pmode, eqv); ++ ++ if (sw_64_tls_size == 64) ++ { ++ if (sw_64_tls_gotdtprel == 16) ++ { ++ dest = gen_reg_rtx (Pmode); ++ emit_insn (gen_rtx_SET (dest, eqv)); ++ emit_insn (gen_adddi3 (dest, dest, scratch)); ++ } ++ else if (sw_64_tls_gotdtprel == 32) ++ { ++ seq = GEN_INT (sw_64_next_sequence_number++); ++ eqv = gen_rtx_UNSPEC (Pmode, ++ gen_rtvec (3, pic_offset_table_rtx, x, ++ seq), ++ UNSPEC_TLSRELGOT); ++ // eqv = gen_rtx_CONST (Pmode, eqv); ++ dest = gen_reg_rtx (Pmode); ++ emit_insn (gen_rtx_SET (dest, eqv)); ++ ++ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, dest, x, seq), ++ UNSPEC_GOTDTPREL); ++ // eqv = gen_rtx_CONST (Pmode, eqv); ++ emit_insn (gen_rtx_SET (dest, eqv)); ++ ++ emit_insn (gen_adddi3 (dest, dest, scratch)); ++ } ++ return dest; ++ } ++ if (sw_64_tls_size == 32) ++ { ++ rtx temp = gen_rtx_HIGH (Pmode, eqv); ++ temp = gen_rtx_PLUS (Pmode, scratch, temp); ++ scratch = gen_reg_rtx (Pmode); ++ emit_insn (gen_rtx_SET (scratch, temp)); ++ } ++ return gen_rtx_LO_SUM (Pmode, scratch, eqv); ++ } ++ ++ case TLS_MODEL_INITIAL_EXEC: ++ { ++ if (sw_64_tls_gottprel == 16) ++ { ++ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL); ++ eqv = gen_rtx_CONST (Pmode, eqv); ++ tp = gen_reg_rtx (Pmode); ++ scratch = gen_reg_rtx (Pmode); ++ dest = gen_reg_rtx (Pmode); ++ ++ emit_insn (gen_get_thread_pointerdi (tp)); ++ emit_insn (gen_rtx_SET (scratch, eqv)); ++ emit_insn (gen_adddi3 (dest, tp, scratch)); ++ } ++ else if (sw_64_tls_gottprel == 32) ++ { ++ seq = GEN_INT (sw_64_next_sequence_number++); ++ tp = gen_reg_rtx (Pmode); ++ emit_insn (gen_get_thread_pointerdi (tp)); ++ ++ scratch = gen_reg_rtx (Pmode); ++ eqv ++ = gen_rtx_UNSPEC (Pmode, ++ gen_rtvec (3, pic_offset_table_rtx, x, seq), ++ UNSPEC_TLSRELGOT); ++ // eqv = gen_rtx_CONST (Pmode, eqv); ++ emit_insn (gen_rtx_SET (scratch, eqv)); ++ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, scratch, x, seq), ++ UNSPEC_TPREL); ++ // eqv = gen_rtx_CONST (Pmode, eqv); ++ emit_insn (gen_rtx_SET (scratch, eqv)); ++ ++ dest = gen_reg_rtx (Pmode); ++ emit_insn (gen_adddi3 (dest, tp, scratch)); ++ } ++ return dest; ++ } ++ ++ case TLS_MODEL_LOCAL_EXEC: ++ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL); ++ eqv = gen_rtx_CONST (Pmode, eqv); ++ tp = gen_reg_rtx (Pmode); ++ ++ emit_insn (gen_get_thread_pointerdi (tp)); ++ if (sw_64_tls_size == 32) ++ { ++ rtx temp = gen_rtx_HIGH (Pmode, eqv); ++ temp = gen_rtx_PLUS (Pmode, tp, temp); ++ tp = gen_reg_rtx (Pmode); ++ emit_insn (gen_rtx_SET (tp, temp)); ++ } ++ return gen_rtx_LO_SUM (Pmode, tp, eqv); ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (local_symbolic_operand (x, Pmode)) ++ { ++ if (small_symbolic_operand (x, Pmode)) ++ return x; ++ else ++ { ++ if (can_create_pseudo_p ()) ++ scratch = gen_reg_rtx (Pmode); ++ emit_insn (gen_rtx_SET (scratch, gen_rtx_HIGH (Pmode, x))); ++ return gen_rtx_LO_SUM (Pmode, scratch, x); ++ } ++ } ++ } ++ ++ return NULL; ++ ++ split_addend : { ++ HOST_WIDE_INT low, high; ++ ++ low = ((addend & 0xffff) ^ 0x8000) - 0x8000; ++ addend -= low; ++ high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ addend -= high; ++ ++ if (addend) ++ x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend), ++ (!can_create_pseudo_p () ? scratch : NULL_RTX), ++ 1, OPTAB_LIB_WIDEN); ++ if (high) ++ x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high), ++ (!can_create_pseudo_p () ? scratch : NULL_RTX), ++ 1, OPTAB_LIB_WIDEN); ++ ++ return plus_constant (Pmode, x, low); ++ } ++} ++ ++/* Try machine-dependent ways of modifying an illegitimate address ++ to be legitimate. Return X or the new, valid address. */ ++ ++static rtx ++sw_64_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, machine_mode mode) ++{ ++ rtx new_x = sw_64_legitimize_address_1 (x, NULL_RTX, mode); ++ return new_x ? new_x : x; ++} ++ ++/* Return true if ADDR has an effect that depends on the machine mode it ++ is used for. On the Sw_64 this is true only for the unaligned modes. ++ We can simplify the test since we know that the address must be valid. */ ++ ++static bool ++sw_64_mode_dependent_address_p (const_rtx addr, ++ addr_space_t as ATTRIBUTE_UNUSED) ++{ ++ return GET_CODE (addr) == AND; ++} ++ ++/* Primarily this is required for TLS symbols, but given that our move ++ patterns *ought* to be able to handle any symbol at any time, we ++ should never be spilling symbolic operands to the constant pool, ever. */ ++ ++static bool ++sw_64_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) ++{ ++ enum rtx_code code = GET_CODE (x); ++ return code == SYMBOL_REF || code == LABEL_REF || code == CONST; ++} ++ ++/* We do not allow indirect calls to be optimized into sibling calls, nor ++ can we allow a call to a function with a different GP to be optimized ++ into a sibcall. */ ++ ++static bool ++sw_64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) ++{ ++ /* Can't do indirect tail calls, since we don't know if the target ++ uses the same GP. */ ++ if (!decl) ++ return false; ++ ++ /* Otherwise, we can make a tail call if the target function shares ++ the same GP. */ ++ return decl_has_samegp (decl); ++} ++ ++bool ++some_small_symbolic_operand_int (rtx x) ++{ ++ subrtx_var_iterator::array_type array; ++ FOR_EACH_SUBRTX_VAR (iter, array, x, ALL) ++ { ++ rtx x = *iter; ++ /* Don't re-split. */ ++ if (GET_CODE (x) == LO_SUM) ++ iter.skip_subrtxes (); ++ else if (small_symbolic_operand (x, Pmode)) ++ return true; ++ } ++ return false; ++} ++ ++rtx ++split_small_symbolic_operand (rtx x) ++{ ++ x = copy_insn (x); ++ subrtx_ptr_iterator::array_type array; ++ FOR_EACH_SUBRTX_PTR (iter, array, &x, ALL) ++ { ++ rtx *ptr = *iter; ++ rtx x = *ptr; ++ /* Don't re-split. */ ++ if (GET_CODE (x) == LO_SUM) ++ iter.skip_subrtxes (); ++ else if (small_symbolic_operand (x, Pmode)) ++ { ++ *ptr = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x); ++ iter.skip_subrtxes (); ++ } ++ } ++ return x; ++} ++ ++/* Indicate that INSN cannot be duplicated. This is true for any insn ++ that we've marked with gpdisp relocs, since those have to stay in ++ 1-1 correspondence with one another. ++ ++ Technically we could copy them if we could set up a mapping from one ++ sequence number to another, across the set of insns to be duplicated. ++ This seems overly complicated and error-prone since interblock motion ++ from sched-ebb could move one of the pair of insns to a different block. ++ ++ Also cannot allow call insns to be duplicated. If they throw exceptions, ++ then they'll be in a different block from their ldgp. Which could lead ++ the bb reorder code to think that it would be ok to copy just the block ++ containing the call and branch to the block containing the ldgp. */ ++ ++static bool ++sw_64_cannot_copy_insn_p (rtx_insn *insn) ++{ ++ if (!reload_completed || !TARGET_EXPLICIT_RELOCS) ++ return false; ++ if (recog_memoized (insn) >= 0) ++ return get_attr_cannot_copy (insn); ++ else ++ return false; ++} ++ ++/* Try a machine-dependent way of reloading an illegitimate address ++ operand. If we find one, push the reload and return the new rtx. */ ++ ++rtx ++sw_64_legitimize_reload_address (rtx x, machine_mode mode ATTRIBUTE_UNUSED, ++ int opnum, int type, ++ int ind_levels ATTRIBUTE_UNUSED) ++{ ++ /* We must recognize output that we have already generated ourselves. */ ++ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS ++ && REG_P (XEXP (XEXP (x, 0), 0)) && CONST_INT_P (XEXP (XEXP (x, 0), 1)) ++ && CONST_INT_P (XEXP (x, 1))) ++ { ++ push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, BASE_REG_CLASS, ++ GET_MODE (x), VOIDmode, 0, 0, opnum, ++ (enum reload_type) type); ++ return x; ++ } ++ ++ /* We wish to handle large displacements off a base register by ++ splitting the addend across an ldih and the mem insn. This ++ cuts number of extra insns needed from 3 to 1. */ ++ if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) ++ && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER ++ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0))) && CONST_INT_P (XEXP (x, 1))) ++ { ++ HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); ++ HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT high ++ = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ ++ /* Check for 32-bit overflow. */ ++ if (high + low != val) ++ return NULL_RTX; ++ ++ /* Reload the high part into a base reg; leave the low part ++ in the mem directly. */ ++ x = gen_rtx_PLUS (GET_MODE (x), ++ gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), ++ GEN_INT (high)), ++ GEN_INT (low)); ++ ++ push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, BASE_REG_CLASS, ++ GET_MODE (x), VOIDmode, 0, 0, opnum, ++ (enum reload_type) type); ++ return x; ++ } ++ ++ return NULL_RTX; ++} ++ ++/* Return the cost of moving between registers of various classes. Moving ++ between FLOAT_REGS and anything else except float regs is expensive. ++ In fact, we make it quite expensive because we really don't want to ++ do these moves unless it is clearly worth it. Optimizations may ++ reduce the impact of not being able to allocate a pseudo to a ++ hard register. */ ++ ++static int ++sw_64_register_move_cost (machine_mode mode, reg_class_t from_i, ++ reg_class_t to_i) ++{ ++ enum reg_class from = (enum reg_class) from_i; ++ enum reg_class to = (enum reg_class) to_i; ++ if (!flag_sw_rtx_cost) ++ { ++ if ((from == FLOAT_REGS) == (to == FLOAT_REGS)) ++ return 2; ++ if (TARGET_FIX) ++ return (from == FLOAT_REGS) ? 6 : 8; ++ return 4 + 2 * sw_64_memory_latency; ++ } ++ if (from == R0_REG || from == R24_REG || from == R25_REG || from == R27_REG) ++ from = GENERAL_REGS; ++ if (to == R0_REG || to == R24_REG || to == R25_REG || to == R27_REG) ++ to = GENERAL_REGS; ++ if (GET_MODE_SIZE (mode) == 32) ++ { ++ if (from == GENERAL_REGS && to == GENERAL_REGS) ++ return 1; ++ else if (from == GENERAL_REGS) ++ return 16; ++ else if (to == GENERAL_REGS) ++ return 16; ++ if (!TARGET_SW_SIMD) ++ return 34; ++ return 2; ++ } ++ if (from == GENERAL_REGS && to == GENERAL_REGS) ++ return 1; ++ else if (from == GENERAL_REGS) ++ return 4; ++ else if (to == GENERAL_REGS) ++ return 4; ++ return 2; ++} ++/* Return the cost of moving data of MODE from a register to ++ or from memory. On the Sw_64, bump this up a bit. */ ++ ++static int ++sw_64_memory_move_cost (machine_mode /*mode*/, reg_class_t /*regclass*/, ++ bool /*in*/) ++{ ++ if (flag_sw_rtx_cost) ++ return sw_64_memory_latency; ++ return 2 * sw_64_memory_latency; ++} ++ ++/* Compute a (partial) cost for rtx X. Return true if the complete ++ cost has been computed, and false if subexpressions should be ++ scanned. In either case, *TOTAL contains the cost result. */ ++ ++static bool ++sw_64_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, ++ bool speed) ++{ ++ int code = GET_CODE (x); ++ bool float_mode_p = FLOAT_MODE_P (mode); ++ const struct sw_64_rtx_cost_data *cost_data; ++ ++ if (!speed) ++ cost_data = &sw_64_rtx_cost_size; ++ else ++ if (flag_sw_rtx_cost) ++ cost_data = &sw_64_rtx_cost_data[1]; ++ else ++ cost_data = &sw_64_rtx_cost_data[sw_64_tune]; ++ ++ switch (code) ++ { ++ case CONST_INT: ++ /* If this is an 8-bit constant, return zero since it can be used ++ nearly anywhere with no cost. If it is a valid operand for an ++ ADD or AND, likewise return 0 if we know it will be used in that ++ context. Otherwise, return 2 since it might be used there later. ++ All other constants take at least two insns. */ ++ if (INTVAL (x) >= 0 && INTVAL (x) < 256) ++ { ++ *total = 0; ++ return true; ++ } ++ /* FALLTHRU */ ++ ++ case CONST_DOUBLE: ++ case CONST_WIDE_INT: ++ if (x == CONST0_RTX (mode)) ++ *total = 0; ++ else if ((outer_code == PLUS && add_operand (x, VOIDmode)) ++ || (outer_code == AND && and_operand (x, VOIDmode))) ++ *total = 0; ++ else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode)) ++ *total = 2; ++ else ++ *total = COSTS_N_INSNS (2); ++ return true; ++ ++ case CONST: ++ case SYMBOL_REF: ++ case LABEL_REF: ++ if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode)) ++ *total = COSTS_N_INSNS (outer_code != MEM); ++ else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode)) ++ *total = COSTS_N_INSNS (1 + (outer_code != MEM)); ++ else if (tls_symbolic_operand_type (x)) ++ /* ??? How many insns do we emit here? More than one... */ ++ *total = COSTS_N_INSNS (15); ++ else ++ /* Otherwise we do a load from the GOT. */ ++ *total = COSTS_N_INSNS (!speed ? 1 : sw_64_memory_latency); ++ return true; ++ ++ case HIGH: ++ /* This is effectively an add_operand. */ ++ *total = 2; ++ return true; ++ ++ case PLUS: ++ case MINUS: ++ if (float_mode_p) ++ *total = cost_data->fp_add; ++ else if (GET_CODE (XEXP (x, 0)) == ASHIFT ++ && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) ++ { ++ *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode, ++ (enum rtx_code) outer_code, opno, speed) ++ + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) outer_code, ++ opno, speed) ++ + COSTS_N_INSNS (1)); ++ return true; ++ } ++ return false; ++ ++ case MULT: ++ if (float_mode_p) ++ *total = cost_data->fp_mult; ++ else if (mode == DImode) ++ *total = cost_data->int_mult_di; ++ else ++ *total = cost_data->int_mult_si; ++ return false; ++ ++ case ASHIFT: ++ if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) <= 3) ++ { ++ *total = COSTS_N_INSNS (1); ++ return false; ++ } ++ /* FALLTHRU */ ++ ++ case ASHIFTRT: ++ case LSHIFTRT: ++ *total = cost_data->int_shift; ++ return false; ++ ++ case IF_THEN_ELSE: ++ if (float_mode_p) ++ *total = cost_data->fp_add; ++ else ++ *total = cost_data->int_cmov; ++ if (flag_sw_rtx_cost && float_mode_p) ++ *total = COSTS_N_INSNS (2); ++ return false; ++ ++ case DIV: ++ case UDIV: ++ case MOD: ++ case UMOD: ++ if (!float_mode_p) ++ *total = cost_data->int_div; ++ else if (mode == SFmode) ++ *total = cost_data->fp_div_sf; ++ else ++ *total = cost_data->fp_div_df; ++ return false; ++ ++ case MEM: ++ *total = COSTS_N_INSNS (!speed ? 1 : sw_64_memory_latency); ++ return true; ++ ++ case NEG: ++ if (!float_mode_p) ++ { ++ *total = COSTS_N_INSNS (1); ++ return false; ++ } ++ if (flag_sw_rtx_cost) ++ { ++ *total = COSTS_N_INSNS (2); ++ return false; ++ } ++ /* FALLTHRU */ ++ ++ case ABS: ++ if (!float_mode_p) ++ { ++ *total = COSTS_N_INSNS (1) + cost_data->int_cmov; ++ return false; ++ } ++ /* FALLTHRU */ ++ ++ case FLOAT: ++ case UNSIGNED_FLOAT: ++ case FIX: ++ case UNSIGNED_FIX: ++ if (flag_sw_rtx_cost) ++ { ++ *total = COSTS_N_INSNS (4); ++ return false; ++ } ++ case FLOAT_TRUNCATE: ++ *total = cost_data->fp_add; ++ return false; ++ ++ case FLOAT_EXTEND: ++ if (MEM_P (XEXP (x, 0))) ++ *total = 0; ++ else ++ *total = cost_data->fp_add; ++ return false; ++ ++ default: ++ return false; ++ } ++} ++ ++/* REF is an alignable memory location. Place an aligned SImode ++ reference into *PALIGNED_MEM and the number of bits to shift into ++ *PBITNUM. SCRATCH is a free register for use in reloading out ++ of range stack slots. */ ++ ++void ++get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum) ++{ ++ rtx base; ++ HOST_WIDE_INT disp, offset; ++ ++ gcc_assert (MEM_P (ref)); ++ ++ if (reload_in_progress) ++ { ++ base = find_replacement (&XEXP (ref, 0)); ++ gcc_assert (memory_address_p (GET_MODE (ref), base)); ++ } ++ else ++ base = XEXP (ref, 0); ++ ++ if (GET_CODE (base) == PLUS) ++ disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0); ++ else ++ disp = 0; ++ ++ /* Find the byte offset within an aligned word. If the memory itself is ++ claimed to be aligned, believe it. Otherwise, aligned_memory_operand ++ will have examined the base register and determined it is aligned, and ++ thus displacements from it are naturally alignable. */ ++ if (MEM_ALIGN (ref) >= 32) ++ offset = 0; ++ else ++ offset = disp & 3; ++ ++ /* The location should not cross aligned word boundary. */ ++ gcc_assert (offset + GET_MODE_SIZE (GET_MODE (ref)) ++ <= GET_MODE_SIZE (SImode)); ++ ++ /* Access the entire aligned word. */ ++ *paligned_mem = widen_memory_access (ref, SImode, -offset); ++ ++ /* Convert the byte offset within the word to a bit offset. */ ++ offset *= BITS_PER_UNIT; ++ *pbitnum = GEN_INT (offset); ++} ++ ++/* Similar, but just get the address. Handle the two reload cases. ++ Add EXTRA_OFFSET to the address we return. */ ++ ++rtx ++get_unaligned_address (rtx ref) ++{ ++ rtx base; ++ HOST_WIDE_INT offset = 0; ++ ++ gcc_assert (MEM_P (ref)); ++ ++ if (reload_in_progress) ++ { ++ base = find_replacement (&XEXP (ref, 0)); ++ gcc_assert (memory_address_p (GET_MODE (ref), base)); ++ } ++ else ++ base = XEXP (ref, 0); ++ ++ if (GET_CODE (base) == PLUS) ++ offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0); ++ ++ return plus_constant (Pmode, base, offset); ++} ++ ++/* Compute a value X, such that X & 7 == (ADDR + OFS) & 7. ++ X is always returned in a register. */ ++ ++rtx ++get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs) ++{ ++ if (GET_CODE (addr) == PLUS) ++ { ++ ofs += INTVAL (XEXP (addr, 1)); ++ addr = XEXP (addr, 0); ++ } ++ ++ return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7), NULL_RTX, 1, ++ OPTAB_LIB_WIDEN); ++} ++ ++/* On the Sw_64, all (non-symbolic) constants except zero go into ++ a floating-point register via memory. Note that we cannot ++ return anything that is not a subset of RCLASS, and that some ++ symbolic constants cannot be dropped to memory. */ ++ ++enum reg_class ++sw_64_preferred_reload_class (rtx x, enum reg_class rclass) ++{ ++ /* Zero is present in any register class. */ ++ if (x == CONST0_RTX (GET_MODE (x))) ++ return rclass; ++ ++ /* These sorts of constants we can easily drop to memory. */ ++ if (CONST_SCALAR_INT_P (x) || CONST_DOUBLE_P (x) ++ || GET_CODE (x) == CONST_VECTOR) ++ { ++ if (rclass == FLOAT_REGS) ++ return NO_REGS; ++ if (rclass == ALL_REGS) ++ return GENERAL_REGS; ++ return rclass; ++ } ++ ++ /* All other kinds of constants should not (and in the case of HIGH ++ cannot) be dropped to memory -- instead we use a GENERAL_REGS ++ secondary reload. */ ++ if (CONSTANT_P (x)) ++ return (rclass == ALL_REGS ? GENERAL_REGS : rclass); ++ ++ return rclass; ++} ++ ++/* Inform reload about cases where moving X with a mode MODE to a register in ++ RCLASS requires an extra scratch or immediate register. Return the class ++ needed for the immediate register. */ ++ ++static reg_class_t ++sw_64_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, ++ machine_mode mode, secondary_reload_info *sri) ++{ ++ enum reg_class rclass = (enum reg_class) rclass_i; ++ ++ /* Loading and storing HImode or QImode values to and from memory ++ usually requires a scratch register. */ ++ if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode)) ++ { ++ if (any_memory_operand (x, mode)) ++ { ++ if (in_p) ++ { ++ if (!aligned_memory_operand (x, mode)) ++ sri->icode = direct_optab_handler (reload_in_optab, mode); ++ } ++ else ++ sri->icode = direct_optab_handler (reload_out_optab, mode); ++ return NO_REGS; ++ } ++ } ++ ++ /* We also cannot do integral arithmetic into FP regs, as might result ++ from register elimination into a DImode fp register. */ ++ if (rclass == FLOAT_REGS) ++ { ++ if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND) ++ return GENERAL_REGS; ++ if (in_p && INTEGRAL_MODE_P (mode) && !MEM_P (x) && !REG_P (x) ++ && !CONST_INT_P (x)) ++ return GENERAL_REGS; ++ } ++ ++ return NO_REGS; ++} ++ ++/* Implement TARGET_SECONDARY_MEMORY_NEEDED. ++ ++ If we are copying between general and FP registers, we need a memory ++ location unless the FIX extension is available. */ ++ ++static bool ++sw_64_secondary_memory_needed (machine_mode, reg_class_t class1, ++ reg_class_t class2) ++{ ++ return (!TARGET_FIX ++ && ((class1 == FLOAT_REGS && class2 != FLOAT_REGS) ++ || (class2 == FLOAT_REGS && class1 != FLOAT_REGS))); ++} ++ ++/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE. If MODE is ++ floating-point, use it. Otherwise, widen to a word like the default. ++ This is needed because we always store integers in FP registers in ++ quadword format. This whole area is very tricky! */ ++ ++static machine_mode ++sw_64_secondary_memory_needed_mode (machine_mode mode) ++{ ++ if (GET_MODE_CLASS (mode) == MODE_FLOAT) ++ return mode; ++ if (GET_MODE_SIZE (mode) >= 4) ++ return mode; ++ return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require (); ++} ++ ++/* Given SEQ, which is an INSN list, look for any MEMs in either ++ a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and ++ volatile flags from REF into each of the MEMs found. If REF is not ++ a MEM, don't do anything. */ ++ ++void ++sw_64_set_memflags (rtx seq, rtx ref) ++{ ++ rtx_insn *insn; ++ ++ if (!MEM_P (ref)) ++ return; ++ ++ /* This is only called from sw_64.md, after having had something ++ generated from one of the insn patterns. So if everything is ++ zero, the pattern is already up-to-date. */ ++ if (!MEM_VOLATILE_P (ref) && !MEM_NOTRAP_P (ref) && !MEM_READONLY_P (ref)) ++ return; ++ ++ subrtx_var_iterator::array_type array; ++ for (insn = as_a (seq); insn; insn = NEXT_INSN (insn)) ++ if (INSN_P (insn)) ++ FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST) ++ { ++ rtx x = *iter; ++ if (MEM_P (x)) ++ { ++ MEM_VOLATILE_P (x) = MEM_VOLATILE_P (ref); ++ MEM_NOTRAP_P (x) = MEM_NOTRAP_P (ref); ++ MEM_READONLY_P (x) = MEM_READONLY_P (ref); ++ /* Sadly, we cannot use alias sets because the extra ++ aliasing produced by the AND interferes. Given that ++ two-byte quantities are the only thing we would be ++ able to differentiate anyway, there does not seem to ++ be any point in convoluting the early out of the ++ alias check. */ ++ iter.skip_subrtxes (); ++ } ++ } ++ else ++ gcc_unreachable (); ++} ++ ++static rtx ++sw_64_emit_set_const (rtx, machine_mode, HOST_WIDE_INT, int, bool); ++ ++/* Internal routine for sw_64_emit_set_const to check for N or below insns. ++ If NO_OUTPUT is true, then we only check to see if N insns are possible, ++ and return pc_rtx if successful. */ ++ ++static rtx ++sw_64_emit_set_const_1 (rtx target, machine_mode mode, HOST_WIDE_INT c, int n, ++ bool no_output) ++{ ++ HOST_WIDE_INT new_const; ++ int i, bits; ++ /* Use a pseudo if highly optimizing and still generating RTL. */ ++ rtx subtarget ++ = (flag_expensive_optimizations && can_create_pseudo_p () ? 0 : target); ++ rtx temp, insn; ++ ++ /* If this is a sign-extended 32-bit constant, we can do this in at most ++ three insns, so do it if we have enough insns left. */ ++ ++ if (c >> 31 == -1 || c >> 31 == 0) ++ { ++ HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT tmp1 = c - low; ++ HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT extra = 0; ++ ++ /* If HIGH will be interpreted as negative but the constant is ++ positive, we must adjust it to do two ldha insns. */ ++ ++ if ((high & 0x8000) != 0 && c >= 0) ++ { ++ extra = 0x4000; ++ tmp1 -= 0x40000000; ++ high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); ++ } ++ ++ if (c == low || (low == 0 && extra == 0)) ++ { ++ /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode) ++ but that meant that we can't handle INT_MIN on 32-bit machines ++ (like NT/Sw_64), because we recurse indefinitely through ++ emit_move_insn to gen_movdi. So instead, since we know exactly ++ what we want, create it explicitly. */ ++ ++ if (no_output) ++ return pc_rtx; ++ if (target == NULL) ++ target = gen_reg_rtx (mode); ++ emit_insn (gen_rtx_SET (target, GEN_INT (c))); ++ return target; ++ } ++ else if (n >= 2 + (extra != 0)) ++ { ++ if (no_output) ++ return pc_rtx; ++ if (!can_create_pseudo_p ()) ++ { ++ emit_insn (gen_rtx_SET (target, GEN_INT (high << 16))); ++ temp = target; ++ } ++ else ++ temp ++ = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode); ++ ++ /* As of 2002-02-23, addsi3 is only available when not optimizing. ++ This means that if we go through expand_binop, we'll try to ++ generate extensions, etc, which will require new pseudos, which ++ will fail during some split phases. The SImode add patterns ++ still exist, but are not named. So build the insns by hand. */ ++ ++ if (extra != 0) ++ { ++ if (!subtarget) ++ subtarget = gen_reg_rtx (mode); ++ insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16)); ++ insn = gen_rtx_SET (subtarget, insn); ++ emit_insn (insn); ++ temp = subtarget; ++ } ++ ++ if (target == NULL) ++ target = gen_reg_rtx (mode); ++ insn = gen_rtx_PLUS (mode, temp, GEN_INT (low)); ++ insn = gen_rtx_SET (target, insn); ++ emit_insn (insn); ++ return target; ++ } ++ } ++ ++ /* If we couldn't do it that way, try some other methods. But if we have ++ no instructions left, don't bother. Likewise, if this is SImode and ++ we can't make pseudos, we can't do anything since the expand_binop ++ and expand_unop calls will widen and try to make pseudos. */ ++ ++ if (n == 1 || (mode == SImode && !can_create_pseudo_p ())) ++ return 0; ++ ++ /* Next, see if we can load a related constant and then shift and possibly ++ negate it to get the constant we want. Try this once each increasing ++ numbers of insns. */ ++ ++ for (i = 1; i < n; i++) ++ { ++ /* First, see if minus some low bits, we've an easy load of ++ high bits. */ ++ ++ new_const = ((c & 0xffff) ^ 0x8000) - 0x8000; ++ if (new_const != 0) ++ { ++ temp = sw_64_emit_set_const (subtarget, mode, c - new_const, i, ++ no_output); ++ if (temp) ++ { ++ if (no_output) ++ return temp; ++ return expand_binop (mode, add_optab, temp, GEN_INT (new_const), ++ target, 0, OPTAB_WIDEN); ++ } ++ } ++ ++ /* Next try complementing. */ ++ temp = sw_64_emit_set_const (subtarget, mode, ~c, i, no_output); ++ if (temp) ++ { ++ if (no_output) ++ return temp; ++ return expand_unop (mode, one_cmpl_optab, temp, target, 0); ++ } ++ ++ /* Next try to form a constant and do a left shift. We can do this ++ if some low-order bits are zero; the exact_log2 call below tells ++ us that information. The bits we are shifting out could be any ++ value, but here we'll just try the 0- and sign-extended forms of ++ the constant. To try to increase the chance of having the same ++ constant in more than one insn, start at the highest number of ++ bits to shift, but try all possibilities in case a ZAPNOT will ++ be useful. */ ++ ++ bits = exact_log2 (c & -c); ++ if (bits > 0) ++ for (; bits > 0; bits--) ++ { ++ new_const = c >> bits; ++ temp ++ = sw_64_emit_set_const (subtarget, mode, new_const, i, no_output); ++ if (!temp && c < 0) ++ { ++ new_const = (unsigned HOST_WIDE_INT) c >> bits; ++ temp = sw_64_emit_set_const (subtarget, mode, new_const, i, ++ no_output); ++ } ++ if (temp) ++ { ++ if (no_output) ++ return temp; ++ return expand_binop (mode, ashl_optab, temp, GEN_INT (bits), ++ target, 0, OPTAB_WIDEN); ++ } ++ } ++ ++ /* Now try high-order zero bits. Here we try the shifted-in bits as ++ all zero and all ones. Be careful to avoid shifting outside the ++ mode and to avoid shifting outside the host wide int size. */ ++ ++ bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8) ++ - floor_log2 (c) - 1); ++ if (bits > 0) ++ for (; bits > 0; bits--) ++ { ++ new_const = c << bits; ++ temp ++ = sw_64_emit_set_const (subtarget, mode, new_const, i, no_output); ++ if (!temp) ++ { ++ new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1); ++ temp = sw_64_emit_set_const (subtarget, mode, new_const, i, ++ no_output); ++ } ++ if (temp) ++ { ++ if (no_output) ++ return temp; ++ return expand_binop (mode, lshr_optab, temp, GEN_INT (bits), ++ target, 1, OPTAB_WIDEN); ++ } ++ } ++ ++ /* Now try high-order 1 bits. We get that with a sign-extension. ++ But one bit isn't enough here. Be careful to avoid shifting outside ++ the mode and to avoid shifting outside the host wide int size. */ ++ ++ bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8) ++ - floor_log2 (~c) - 2); ++ if (bits > 0) ++ for (; bits > 0; bits--) ++ { ++ new_const = c << bits; ++ temp ++ = sw_64_emit_set_const (subtarget, mode, new_const, i, no_output); ++ if (!temp) ++ { ++ new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1); ++ temp = sw_64_emit_set_const (subtarget, mode, new_const, i, ++ no_output); ++ } ++ if (temp) ++ { ++ if (no_output) ++ return temp; ++ return expand_binop (mode, ashr_optab, temp, GEN_INT (bits), ++ target, 0, OPTAB_WIDEN); ++ } ++ } ++ } ++ ++ /* Finally, see if can load a value into the target that is the same as the ++ constant except that all bytes that are 0 are changed to be 0xff. If we ++ can, then we can do a ZAPNOT to obtain the desired constant. */ ++ ++ new_const = c; ++ for (i = 0; i < 64; i += 8) ++ if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0) ++ new_const |= (HOST_WIDE_INT) 0xff << i; ++ ++ /* We are only called for SImode and DImode. If this is SImode, ensure that ++ we are sign extended to a full word. */ ++ ++ if (mode == SImode) ++ new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ ++ if (new_const != c) ++ { ++ temp ++ = sw_64_emit_set_const (subtarget, mode, new_const, n - 1, no_output); ++ if (temp) ++ { ++ if (no_output) ++ return temp; ++ return expand_binop (mode, and_optab, temp, GEN_INT (c | ~new_const), ++ target, 0, OPTAB_WIDEN); ++ } ++ } ++ ++ return 0; ++} ++ ++/* Try to output insns to set TARGET equal to the constant C if it can be ++ done in less than N insns. Do all computations in MODE. Returns the place ++ where the output has been placed if it can be done and the insns have been ++ emitted. If it would take more than N insns, zero is returned and no ++ insns and emitted. */ ++ ++static rtx ++sw_64_emit_set_const (rtx target, machine_mode mode, HOST_WIDE_INT c, int n, ++ bool no_output) ++{ ++ machine_mode orig_mode = mode; ++ rtx orig_target = target; ++ rtx result = 0; ++ int i; ++ ++ /* If we can't make any pseudos, TARGET is an SImode hard register, we ++ can't load this constant in one insn, do this in DImode. */ ++ if (!can_create_pseudo_p () && mode == SImode && REG_P (target) ++ && REGNO (target) < FIRST_PSEUDO_REGISTER) ++ { ++ result = sw_64_emit_set_const_1 (target, mode, c, 1, no_output); ++ if (result) ++ return result; ++ ++ target = no_output ? NULL : gen_lowpart (DImode, target); ++ mode = DImode; ++ } ++ else if (mode == V8QImode || mode == V4HImode || mode == V2SImode) ++ { ++ target = no_output ? NULL : gen_lowpart (DImode, target); ++ mode = DImode; ++ } ++ ++ /* Try 1 insn, then 2, then up to N. */ ++ for (i = 1; i <= n; i++) ++ { ++ result = sw_64_emit_set_const_1 (target, mode, c, i, no_output); ++ if (result) ++ { ++ rtx_insn *insn; ++ rtx set; ++ ++ if (no_output) ++ return result; ++ ++ insn = get_last_insn (); ++ set = single_set (insn); ++ if (!CONSTANT_P (SET_SRC (set))) ++ set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c)); ++ break; ++ } ++ } ++ ++ /* Allow for the case where we changed the mode of TARGET. */ ++ if (result) ++ { ++ if (result == target) ++ result = orig_target; ++ else if (mode != orig_mode) ++ result = gen_lowpart (orig_mode, result); ++ } ++ ++ return result; ++} ++ ++/* Having failed to find a 3 insn sequence in sw_64_emit_set_const, ++ fall back to a straight forward decomposition. We do this to avoid ++ exponential run times encountered when looking for longer sequences ++ with sw_64_emit_set_const. */ ++ ++static rtx ++sw_64_emit_set_long_const (rtx target, HOST_WIDE_INT c1) ++{ ++ HOST_WIDE_INT d1, d2, d3, d4; ++ ++ /* Decompose the entire word */ ++ ++ d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; ++ c1 -= d1; ++ d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ c1 = (c1 - d2) >> 32; ++ d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; ++ c1 -= d3; ++ d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ gcc_assert (c1 == d4); ++ ++ /* Construct the high word */ ++ if (d4) ++ { ++ emit_move_insn (target, GEN_INT (d4)); ++ if (d3) ++ emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3))); ++ } ++ else ++ emit_move_insn (target, GEN_INT (d3)); ++ ++ /* Shift it into place */ ++ emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32))); ++ ++ /* Add in the low bits. */ ++ if (d2) ++ emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2))); ++ if (d1) ++ emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1))); ++ ++ return target; ++} ++ ++/* Given an integral CONST_INT or CONST_VECTOR, return the low 64 bits. */ ++ ++static HOST_WIDE_INT ++sw_64_extract_integer (rtx x) ++{ ++ if (GET_CODE (x) == CONST_VECTOR) ++ x = simplify_subreg (DImode, x, GET_MODE (x), 0); ++ ++ gcc_assert (CONST_INT_P (x)); ++ ++ return INTVAL (x); ++} ++ ++/* -fsw-rsqrt function BEGIN */ ++/************************************************* ++*** THE ALGORITHM : ++*** float fast_inverse_sqrt (float x) ++*** { ++*** float xhalf = 0.5f * x; ++*** int i = *(int *)&x ; ++*** i = 0x5f3759df - (i >> 1); // 0x5f3759df is a Magic Number ++*** x = *(float *)&i; ++*** x = x *(1.5f - xhalf * x *x); ++*** x = x *(1.5f - xhalf * x *x); // SPEC2006 435 need this ++*** return x; ++*** } ++*** ++******************************************************/ ++/* Load up a constant. all of the vector elements. */ ++static rtx ++sw_64_load_constant_and_splat (machine_mode mode, REAL_VALUE_TYPE dconst) ++{ ++ rtx reg; ++ ++ if (mode == SFmode || mode == DFmode) ++ { ++ rtx d = const_double_from_real_value (dconst, mode); ++ reg = force_reg (mode, d); ++ } ++ else ++ gcc_unreachable (); ++ ++ return reg; ++} ++ ++void ++sw_64_emit_rsqrt (rtx dst, rtx x, bool note_p) ++{ ++ machine_mode mode = GET_MODE (dst); ++ rtx one, xhalf, mhalf, i, magical, x0, x1, x2; ++ ++ enum insn_code code = optab_handler (smul_optab, mode); ++ insn_gen_fn gen_mul = GEN_FCN (code); ++ gcc_assert (code != CODE_FOR_nothing); ++ ++ enum insn_code code1 = optab_handler (sub_optab, SImode); ++ insn_gen_fn gen_sub = GEN_FCN (code1); ++ gcc_assert (code1 != CODE_FOR_nothing); ++ ++ enum insn_code code2 = optab_handler (fnma_optab, mode); ++ insn_gen_fn gen_fnma = GEN_FCN (code2); ++ gcc_assert (code2 != CODE_FOR_nothing); ++ ++ enum insn_code code3 = optab_handler (add_optab, mode); ++ insn_gen_fn gen_add = GEN_FCN (code3); ++ gcc_assert (code3 != CODE_FOR_nothing); ++ ++ one = sw_64_load_constant_and_splat (mode, dconst1); ++ mhalf = sw_64_load_constant_and_splat (mode, dconsthalf); ++ ++ /* xhalf = 0.5f * x */ ++ xhalf = gen_reg_rtx (mode); ++ emit_insn (gen_mul (xhalf, mhalf, x)); ++ ++ if (x == CONST0_RTX (mode)) ++ gcc_unreachable (); ++ ++ /* int i = *(int *)&x */ ++ rtx vreg = gen_rtx_REG (SFmode, 28); ++ emit_insn ( ++ gen_rtx_SET (vreg, gen_rtx_UNSPEC (mode, gen_rtvec (1, x), UNSPEC_FIMOVS))); ++ ++ /* i = i >> 1 */ ++ i = gen_reg_rtx (DImode); ++ rtx subreg = gen_rtx_SUBREG (SImode, vreg, 0); ++ emit_insn (gen_extendsidi2 (i, subreg)); ++ emit_insn (gen_ashrdi3 (i, i, const1_rtx)); ++ ++ /* magical number: 0x5f3759df */ ++ magical = gen_reg_rtx (SImode); ++ emit_insn (gen_rtx_SET (magical, GEN_INT (0x5f370000))); ++ emit_insn ( ++ gen_rtx_SET (magical, gen_rtx_PLUS (SImode, magical, GEN_INT (0x59df)))); ++ ++ /* x0 = 0x5f3759df - i */ ++ subreg = gen_rtx_SUBREG (SImode, i, 0); ++ x0 = gen_reg_rtx (SImode); ++ emit_insn (gen_sub (x0, magical, subreg)); ++ ++ /* x = *(float *)&x0 */ ++ x = gen_rtx_REG (mode, 60); ++ x0 = gen_rtx_SUBREG (SFmode, x0, 0); ++ emit_insn (gen_rtx_SET (x, x0)); ++ ++ /* x= x *(1.5f - xhalf * x *x) */ ++ rtx number = gen_reg_rtx (mode); ++ emit_insn (gen_add (number, one, mhalf)); ++ ++ x1 = gen_reg_rtx (mode); ++ emit_insn (gen_mul (x1, x, x)); ++ emit_insn (gen_fnma (x1, x1, xhalf, number)); ++ emit_insn (gen_mul (x1, x1, x)); ++ ++ /* second iteration, SPEC2006 435 need this */ ++ x2 = gen_reg_rtx (mode); ++ emit_insn (gen_mul (x2, x1, x1)); ++ emit_insn (gen_fnma (x2, x2, xhalf, number)); ++ emit_insn (gen_mul (dst, x2, x1)); ++} ++/* -fsw-rsqrt function END */ ++ ++/* Implement TARGET_LEGITIMATE_CONSTANT_P. This is all constants for which ++ we are willing to load the value into a register via a move pattern. ++ Normally this is all symbolic constants, integral constants that ++ take three or fewer instructions, and floating-point zero. */ ++ ++bool ++sw_64_legitimate_constant_p (machine_mode mode, rtx x) ++{ ++ HOST_WIDE_INT i0; ++ ++ switch (GET_CODE (x)) ++ { ++ case LABEL_REF: ++ case HIGH: ++ return true; ++ ++ case CONST: ++ if (GET_CODE (XEXP (x, 0)) == PLUS && CONST_INT_P (XEXP (XEXP (x, 0), 1))) ++ x = XEXP (XEXP (x, 0), 0); ++ else ++ return true; ++ ++ if (GET_CODE (x) != SYMBOL_REF) ++ return true; ++ /* FALLTHRU */ ++ ++ case SYMBOL_REF: ++ /* TLS symbols are never valid. */ ++ return SYMBOL_REF_TLS_MODEL (x) == 0; ++ ++ case CONST_WIDE_INT: ++ if (TARGET_BUILD_CONSTANTS) ++ return true; ++ if (x == CONST0_RTX (mode)) ++ return true; ++ mode = DImode; ++ gcc_assert (CONST_WIDE_INT_NUNITS (x) == 2); ++ i0 = CONST_WIDE_INT_ELT (x, 1); ++ if (sw_64_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) == NULL) ++ return false; ++ i0 = CONST_WIDE_INT_ELT (x, 0); ++ goto do_integer; ++ ++ case CONST_DOUBLE: ++ if (x == CONST0_RTX (mode)) ++ return true; ++ return false; ++ ++ case CONST_VECTOR: ++ if (x == CONST0_RTX (mode)) ++ return true; ++ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) ++ return false; ++ if (GET_MODE_SIZE (mode) != 8) ++ return false; ++ /* FALLTHRU */ ++ ++ case CONST_INT: ++ if (TARGET_BUILD_CONSTANTS) ++ return true; ++ i0 = sw_64_extract_integer (x); ++ do_integer: ++ return sw_64_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) != NULL; ++ ++ default: ++ return false; ++ } ++} ++ ++/* Operand 1 is known to be a constant, and should require more than one ++ instruction to load. Emit that multi-part load. */ ++ ++bool ++sw_64_split_const_mov (machine_mode mode, rtx *operands) ++{ ++ HOST_WIDE_INT i0; ++ rtx temp = NULL_RTX; ++ ++ i0 = sw_64_extract_integer (operands[1]); ++ ++ temp = sw_64_emit_set_const (operands[0], mode, i0, 3, false); ++ ++ if (!temp && TARGET_BUILD_CONSTANTS) ++ temp = sw_64_emit_set_long_const (operands[0], i0); ++ ++ if (temp) ++ { ++ if (!rtx_equal_p (operands[0], temp)) ++ emit_move_insn (operands[0], temp); ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Expand a move instruction; return true if all work is done. ++ We don't handle non-bwx subword loads here. */ ++ ++bool ++sw_64_expand_mov (machine_mode mode, rtx *operands) ++{ ++ rtx tmp; ++ ++ /* If the output is not a register, the input must be. */ ++ if (MEM_P (operands[0]) && !reg_or_0_operand (operands[1], mode)) ++ operands[1] = force_reg (mode, operands[1]); ++ ++ /* Allow legitimize_address to perform some simplifications. */ ++ if (mode == Pmode && symbolic_operand (operands[1], mode)) ++ { ++ tmp = sw_64_legitimize_address_1 (operands[1], operands[0], mode); ++ if (tmp) ++ { ++ if (tmp == operands[0]) ++ return true; ++ operands[1] = tmp; ++ return false; ++ } ++ } ++ ++ /* Early out for non-constants and valid constants. */ ++ if (!CONSTANT_P (operands[1]) || input_operand (operands[1], mode)) ++ return false; ++ ++ /* Split large integers. */ ++ if (CONST_INT_P (operands[1]) || GET_CODE (operands[1]) == CONST_VECTOR) ++ { ++ if (sw_64_split_const_mov (mode, operands)) ++ return true; ++ } ++ ++ /* Otherwise we've nothing left but to drop the thing to memory. */ ++ tmp = force_const_mem (mode, operands[1]); ++ ++ if (tmp == NULL_RTX) ++ return false; ++ ++ if (reload_in_progress) ++ { ++ emit_move_insn (operands[0], XEXP (tmp, 0)); ++ operands[1] = replace_equiv_address (tmp, operands[0]); ++ } ++ else ++ operands[1] = validize_mem (tmp); ++ return false; ++} ++ ++/* Expand a non-bwx QImode or HImode move instruction; ++ return true if all work is done. */ ++ ++bool ++sw_64_expand_mov_nobwx (machine_mode mode, rtx *operands) ++{ ++ rtx seq; ++ ++ /* If the output is not a register, the input must be. */ ++ if (MEM_P (operands[0])) ++ operands[1] = force_reg (mode, operands[1]); ++ ++ /* Handle four memory cases, unaligned and aligned for either the input ++ or the output. The only case where we can be called during reload is ++ for aligned loads; all other cases require temporaries. */ ++ ++ if (any_memory_operand (operands[1], mode)) ++ { ++ if (aligned_memory_operand (operands[1], mode)) ++ { ++ if (reload_in_progress) ++ { ++ seq = gen_reload_in_aligned (mode, operands[0], operands[1]); ++ emit_insn (seq); ++ } ++ else ++ { ++ rtx aligned_mem, bitnum; ++ rtx scratch = gen_reg_rtx (SImode); ++ rtx subtarget; ++ bool copyout; ++ ++ get_aligned_mem (operands[1], &aligned_mem, &bitnum); ++ ++ subtarget = operands[0]; ++ if (REG_P (subtarget)) ++ subtarget = gen_lowpart (DImode, subtarget), copyout = false; ++ else ++ subtarget = gen_reg_rtx (DImode), copyout = true; ++ ++ if (mode == QImode) ++ seq = gen_aligned_loadqi (subtarget, aligned_mem, bitnum, ++ scratch); ++ else ++ seq = gen_aligned_loadhi (subtarget, aligned_mem, bitnum, ++ scratch); ++ emit_insn (seq); ++ ++ if (copyout) ++ emit_move_insn (operands[0], gen_lowpart (mode, subtarget)); ++ } ++ } ++ else ++ { ++ /* Don't pass these as parameters since that makes the generated ++ code depend on parameter evaluation order which will cause ++ bootstrap failures. */ ++ ++ rtx temp1, temp2, subtarget, ua; ++ bool copyout; ++ ++ temp1 = gen_reg_rtx (DImode); ++ temp2 = gen_reg_rtx (DImode); ++ ++ subtarget = operands[0]; ++ if (REG_P (subtarget)) ++ subtarget = gen_lowpart (DImode, subtarget), copyout = false; ++ else ++ subtarget = gen_reg_rtx (DImode), copyout = true; ++ ++ ua = get_unaligned_address (operands[1]); ++ if (mode == QImode) ++ seq = gen_unaligned_loadqi (subtarget, ua, temp1, temp2); ++ else ++ seq = gen_unaligned_loadhi (subtarget, ua, temp1, temp2); ++ ++ sw_64_set_memflags (seq, operands[1]); ++ emit_insn (seq); ++ ++ if (copyout) ++ emit_move_insn (operands[0], gen_lowpart (mode, subtarget)); ++ } ++ return true; ++ } ++ ++ if (any_memory_operand (operands[0], mode)) ++ { ++ if (aligned_memory_operand (operands[0], mode)) ++ { ++ rtx aligned_mem, bitnum; ++ rtx temp1 = gen_reg_rtx (SImode); ++ rtx temp2 = gen_reg_rtx (SImode); ++ ++ get_aligned_mem (operands[0], &aligned_mem, &bitnum); ++ ++ emit_insn ( ++ gen_aligned_store (aligned_mem, operands[1], bitnum, temp1, temp2)); ++ } ++ else ++ { ++ rtx temp1 = gen_reg_rtx (DImode); ++ rtx temp2 = gen_reg_rtx (DImode); ++ rtx temp3 = gen_reg_rtx (DImode); ++ rtx ua = get_unaligned_address (operands[0]); ++ ++ seq ++ = gen_unaligned_store (mode, ua, operands[1], temp1, temp2, temp3); ++ ++ sw_64_set_memflags (seq, operands[0]); ++ emit_insn (seq); ++ } ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Implement the movmisalign patterns. One of the operands is a memory ++ that is not naturally aligned. Emit instructions to load it. */ ++ ++void ++sw_64_expand_movmisalign (machine_mode mode, rtx *operands) ++{ ++ /* Honor misaligned loads, for those we promised to do so. */ ++ if (MEM_P (operands[1])) ++ { ++ rtx tmp; ++ ++ if (register_operand (operands[0], mode)) ++ tmp = operands[0]; ++ else ++ tmp = gen_reg_rtx (mode); ++ ++ sw_64_expand_unaligned_load (tmp, operands[1], 8, 0, 0); ++ if (tmp != operands[0]) ++ emit_move_insn (operands[0], tmp); ++ } ++ else if (MEM_P (operands[0])) ++ { ++ if (!reg_or_0_operand (operands[1], mode)) ++ operands[1] = force_reg (mode, operands[1]); ++ sw_64_expand_unaligned_store (operands[0], operands[1], 8, 0); ++ } ++ else ++ gcc_unreachable (); ++} ++ ++/* Generate an unsigned DImode to FP conversion. This is the same code ++ optabs would emit if we didn't have TFmode patterns. ++ ++ For SFmode, this is the only construction I've found that can pass ++ gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode ++ intermediates will work, because you'll get intermediate rounding ++ that ruins the end result. Some of this could be fixed by turning ++ on round-to-positive-infinity, but that requires diddling the fpsr, ++ which kills performance. I tried turning this around and converting ++ to a negative number, so that I could turn on /m, but either I did ++ it wrong or there's something else cause I wound up with the exact ++ same single-bit error. There is a branch-less form of this same code: ++ ++ srl $16,1,$1 ++ and $16,1,$2 ++ cmplt $16,0,$3 ++ or $1,$2,$2 ++ cmovge $16,$16,$2 ++ ifmovd $3,$f10 ++ ifmovd $2,$f11 ++ cvtqs $f11,$f11 ++ adds $f11,$f11,$f0 ++ fcmoveq $f10,$f11,$f0 ++ ++ I'm not using it because it's the same number of instructions as ++ this branch-full form, and it has more serialized long latency ++ instructions on the critical path. ++ ++ For DFmode, we can avoid rounding errors by breaking up the word ++ into two pieces, converting them separately, and adding them back: ++ ++LC0: .long 0,0x5f800000 ++ ++ifmovd $16,$f11 ++ldi $2,LC0 ++cmplt $16,0,$1 ++cpyse $f11,$f31,$f10 ++cpyse $f31,$f11,$f11 ++s4addl $1,$2,$1 ++lds $f12,0($1) ++cvtqt $f10,$f10 ++cvtqt $f11,$f11 ++addt $f12,$f10,$f0 ++addt $f0,$f11,$f0 ++ ++This doesn't seem to be a clear-cut win over the optabs form. ++It probably all depends on the distribution of numbers being ++converted -- in the optabs form, all but high-bit-set has a ++much lower minimum execution time. */ ++ ++void ++sw_64_emit_floatuns (rtx operands[2]) ++{ ++ rtx neglab, donelab, i0, i1, f0, in, out; ++ machine_mode mode; ++ ++ out = operands[0]; ++ in = force_reg (DImode, operands[1]); ++ mode = GET_MODE (out); ++ neglab = gen_label_rtx (); ++ donelab = gen_label_rtx (); ++ i0 = gen_reg_rtx (DImode); ++ i1 = gen_reg_rtx (DImode); ++ f0 = gen_reg_rtx (mode); ++ ++ emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab); ++ ++ emit_insn (gen_rtx_SET (out, gen_rtx_FLOAT (mode, in))); ++ emit_jump_insn (gen_jump (donelab)); ++ emit_barrier (); ++ ++ emit_label (neglab); ++ ++ emit_insn (gen_lshrdi3 (i0, in, const1_rtx)); ++ emit_insn (gen_anddi3 (i1, in, const1_rtx)); ++ emit_insn (gen_iordi3 (i0, i0, i1)); ++ emit_insn (gen_rtx_SET (f0, gen_rtx_FLOAT (mode, i0))); ++ emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0))); ++ ++ emit_label (donelab); ++} ++ ++/* Generate the comparison for a conditional branch. */ ++ ++void ++sw_64_emit_conditional_branch (rtx operands[], machine_mode cmp_mode) ++{ ++ enum rtx_code cmp_code, branch_code; ++ machine_mode branch_mode = VOIDmode; ++ enum rtx_code code = GET_CODE (operands[0]); ++ rtx op0 = operands[1], op1 = operands[2]; ++ rtx tem; ++ ++ if (cmp_mode == TFmode) ++ { ++ op0 = sw_64_emit_xfloating_compare (&code, op0, op1); ++ op1 = const0_rtx; ++ cmp_mode = DImode; ++ } ++ ++ /* The general case: fold the comparison code to the types of compares ++ that we have, choosing the branch as necessary. */ ++ switch (code) ++ { ++ case EQ: ++ case LE: ++ case LT: ++ case LEU: ++ case LTU: ++ case UNORDERED: ++ /* We have these compares. */ ++ cmp_code = code, branch_code = NE; ++ break; ++ ++ case NE: ++ case ORDERED: ++ /* These must be reversed. */ ++ cmp_code = reverse_condition (code), branch_code = EQ; ++ break; ++ ++ case GE: ++ case GT: ++ case GEU: ++ case GTU: ++ /* For FP, we swap them, for INT, we reverse them. */ ++ if (cmp_mode == DFmode || (cmp_mode == SFmode && flag_sw_sf_cmpsel)) ++ { ++ cmp_code = swap_condition (code); ++ branch_code = NE; ++ std::swap (op0, op1); ++ } ++ else ++ { ++ cmp_code = reverse_condition (code); ++ branch_code = EQ; ++ } ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (cmp_mode == DFmode) ++ { ++ if (flag_unsafe_math_optimizations && cmp_code != UNORDERED) ++ { ++ /* When we are not as concerned about non-finite values, and we ++ are comparing against zero, we can branch directly. */ ++ if (op1 == CONST0_RTX (DFmode)) ++ cmp_code = UNKNOWN, branch_code = code; ++ else if (op0 == CONST0_RTX (DFmode)) ++ { ++ /* Undo the swap we probably did just above. */ ++ std::swap (op0, op1); ++ branch_code = swap_condition (cmp_code); ++ cmp_code = UNKNOWN; ++ } ++ } ++ else ++ { ++ /* ??? We mark the branch mode to be CCmode to prevent the ++ compare and branch from being combined, since the compare ++ insn follows IEEE rules that the branch does not. */ ++ branch_mode = CCmode; ++ } ++ } ++ else if (cmp_mode == SFmode && flag_sw_sf_cmpsel) ++ { ++ if (flag_unsafe_math_optimizations && cmp_code != UNORDERED) ++ { ++ /* When we are not as concerned about non-finite values, and we ++ are comparing against zero, we can branch directly. */ ++ if (op1 == CONST0_RTX (SFmode)) ++ cmp_code = UNKNOWN, branch_code = code; ++ else if (op0 == CONST0_RTX (SFmode)) ++ { ++ /* Undo the swap we probably did just above. */ ++ std::swap (op0, op1); ++ branch_code = swap_condition (cmp_code); ++ cmp_code = UNKNOWN; ++ } ++ } ++ ++ else ++ { ++ /* ??? We mark the branch mode to be CCmode to prevent the ++ compare and branch from being combined, since the compare ++ insn follows IEEE rules that the branch does not. */ ++ branch_mode = CCmode; ++ } ++ } ++ ++ else ++ { ++ /* The following optimizations are only for signed compares. */ ++ if (code != LEU && code != LTU && code != GEU && code != GTU) ++ { ++ /* Whee. Compare and branch against 0 directly. */ ++ if (op1 == const0_rtx) ++ cmp_code = UNKNOWN, branch_code = code; ++ ++ /* If the constants doesn't fit into an immediate, but can ++ be generated by ldi/ldih, we adjust the argument and ++ compare against zero, so we can use beq/bne directly. */ ++ /* ??? Don't do this when comparing against symbols, otherwise ++ we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will ++ be declared false out of hand (at least for non-weak). */ ++ else if (CONST_INT_P (op1) && (code == EQ || code == NE) ++ && !(symbolic_operand (op0, VOIDmode) ++ || (REG_P (op0) && REG_POINTER (op0)))) ++ { ++ rtx n_op1 = GEN_INT (-INTVAL (op1)); ++ ++ if (!satisfies_constraint_I (op1) ++ && (satisfies_constraint_K (n_op1) ++ || satisfies_constraint_L (n_op1))) ++ cmp_code = PLUS, branch_code = code, op1 = n_op1; ++ } ++ } ++ ++ if (!reg_or_0_operand (op0, DImode)) ++ op0 = force_reg (DImode, op0); ++ if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode)) ++ op1 = force_reg (DImode, op1); ++ } ++ ++ /* Emit an initial compare instruction, if necessary. */ ++ tem = op0; ++ if (cmp_code != UNKNOWN) ++ { ++ tem = gen_reg_rtx (cmp_mode); ++ emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)); ++ } ++ ++ /* Emit the branch instruction. */ ++ tem = gen_rtx_SET ( ++ pc_rtx, ++ gen_rtx_IF_THEN_ELSE (VOIDmode, ++ gen_rtx_fmt_ee (branch_code, branch_mode, tem, ++ CONST0_RTX (cmp_mode)), ++ gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx)); ++ emit_jump_insn (tem); ++} ++ ++/* Certain simplifications can be done to make invalid setcc operations ++ valid. Return the final comparison, or NULL if we can't work. */ ++ ++bool ++sw_64_emit_setcc (rtx operands[], machine_mode cmp_mode) ++{ ++ enum rtx_code cmp_code; ++ enum rtx_code code = GET_CODE (operands[1]); ++ rtx op0 = operands[2], op1 = operands[3]; ++ rtx tmp; ++ ++ if (cmp_mode == TFmode) ++ { ++ op0 = sw_64_emit_xfloating_compare (&code, op0, op1); ++ op1 = const0_rtx; ++ cmp_mode = DImode; ++ } ++ ++ if (cmp_mode == DFmode && !TARGET_FIX) ++ return 0; ++ ++ /* The general case: fold the comparison code to the types of compares ++ that we have, choosing the branch as necessary. */ ++ ++ cmp_code = UNKNOWN; ++ switch (code) ++ { ++ case EQ: ++ case LE: ++ case LT: ++ case LEU: ++ case LTU: ++ case UNORDERED: ++ /* We have these compares. */ ++ if (cmp_mode == DFmode) ++ cmp_code = code, code = NE; ++ break; ++ ++ case NE: ++ if (cmp_mode == DImode && op1 == const0_rtx) ++ break; ++ /* FALLTHRU */ ++ ++ case ORDERED: ++ cmp_code = reverse_condition (code); ++ code = EQ; ++ break; ++ ++ case GE: ++ case GT: ++ case GEU: ++ case GTU: ++ /* These normally need swapping, but for integer zero we have ++ special patterns that recognize swapped operands. */ ++ if (cmp_mode == DImode && op1 == const0_rtx) ++ break; ++ code = swap_condition (code); ++ if (cmp_mode == DFmode) ++ cmp_code = code, code = NE; ++ std::swap (op0, op1); ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (cmp_mode == DImode) ++ { ++ if (!register_operand (op0, DImode)) ++ op0 = force_reg (DImode, op0); ++ if (!reg_or_8bit_operand (op1, DImode)) ++ op1 = force_reg (DImode, op1); ++ } ++ ++ /* Emit an initial compare instruction, if necessary. */ ++ if (cmp_code != UNKNOWN) ++ { ++ tmp = gen_reg_rtx (cmp_mode); ++ emit_insn ( ++ gen_rtx_SET (tmp, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1))); ++ ++ op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp; ++ op1 = const0_rtx; ++ } ++ ++ /* Emit the setcc instruction. */ ++ emit_insn ( ++ gen_rtx_SET (operands[0], gen_rtx_fmt_ee (code, DImode, op0, op1))); ++ return true; ++} ++ ++/* Rewrite a comparison against zero CMP of the form ++ (CODE (cc0) (const_int 0)) so it can be written validly in ++ a conditional move (if_then_else CMP ...). ++ If both of the operands that set cc0 are nonzero we must emit ++ an insn to perform the compare (it can't be done within ++ the conditional move). */ ++ ++rtx ++sw_64_emit_conditional_move (rtx cmp, machine_mode mode) ++{ ++ enum rtx_code code = GET_CODE (cmp); ++ enum rtx_code cmov_code = NE; ++ rtx op0 = XEXP (cmp, 0); ++ rtx op1 = XEXP (cmp, 1); ++ machine_mode cmp_mode ++ = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0)); ++ machine_mode cmov_mode = VOIDmode; ++ int local_fast_math = flag_unsafe_math_optimizations; ++ rtx tem; ++ ++ if (cmp_mode == TFmode) ++ { ++ op0 = sw_64_emit_xfloating_compare (&code, op0, op1); ++ op1 = const0_rtx; ++ cmp_mode = DImode; ++ } ++ ++ gcc_assert (cmp_mode == DFmode || cmp_mode == DImode || cmp_mode == SFmode); ++ ++ if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode)) ++ { ++ enum rtx_code cmp_code; ++ ++ if (!TARGET_FIX) ++ return 0; ++ ++ /* If we have fp<->int register move instructions, do a cmov by ++ performing the comparison in fp registers, and move the ++ zero/nonzero value to integer registers, where we can then ++ use a normal cmov, or vice-versa. */ ++ ++ switch (code) ++ { ++ case EQ: ++ case LE: ++ case LT: ++ case LEU: ++ case LTU: ++ case UNORDERED: ++ /* We have these compares. */ ++ cmp_code = code, code = NE; ++ break; ++ ++ case NE: ++ case ORDERED: ++ /* These must be reversed. */ ++ cmp_code = reverse_condition (code), code = EQ; ++ break; ++ ++ case GE: ++ case GT: ++ case GEU: ++ case GTU: ++ /* These normally need swapping, but for integer zero we have ++ special patterns that recognize swapped operands. */ ++ if (cmp_mode == DImode && op1 == const0_rtx) ++ cmp_code = code, code = NE; ++ else ++ { ++ cmp_code = swap_condition (code); ++ code = NE; ++ std::swap (op0, op1); ++ } ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (cmp_mode == DImode) ++ { ++ if (!reg_or_0_operand (op0, DImode)) ++ op0 = force_reg (DImode, op0); ++ if (!reg_or_8bit_operand (op1, DImode)) ++ op1 = force_reg (DImode, op1); ++ } ++ ++ tem = gen_reg_rtx (cmp_mode); ++ emit_insn ( ++ gen_rtx_SET (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1))); ++ ++ cmp_mode = cmp_mode == DImode ? E_DFmode : E_DImode; ++ op0 = gen_lowpart (cmp_mode, tem); ++ op1 = CONST0_RTX (cmp_mode); ++ cmp = gen_rtx_fmt_ee (code, VOIDmode, op0, op1); ++ local_fast_math = 1; ++ } ++ ++ if (cmp_mode == DImode) ++ { ++ if (!reg_or_0_operand (op0, DImode)) ++ op0 = force_reg (DImode, op0); ++ if (!reg_or_8bit_operand (op1, DImode)) ++ op1 = force_reg (DImode, op1); ++ } ++ ++ /* We may be able to use a conditional move directly. ++ This avoids emitting spurious compares. */ ++ if (signed_comparison_operator (cmp, VOIDmode) ++ && (cmp_mode == DImode || local_fast_math) ++ && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode))) ++ return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); ++ ++ /* We can't put the comparison inside the conditional move; ++ emit a compare instruction and put that inside the ++ conditional move. Make sure we emit only comparisons we have; ++ swap or reverse as necessary. */ ++ ++ if (!can_create_pseudo_p ()) ++ return NULL_RTX; ++ ++ switch (code) ++ { ++ case EQ: ++ case LE: ++ case LT: ++ case LEU: ++ case LTU: ++ case UNORDERED: ++ /* We have these compares: */ ++ break; ++ ++ case NE: ++ case ORDERED: ++ /* These must be reversed. */ ++ code = reverse_condition (code); ++ cmov_code = EQ; ++ break; ++ ++ case GE: ++ case GT: ++ case GEU: ++ case GTU: ++ /* These normally need swapping, but for integer zero we have ++ special patterns that recognize swapped operands. */ ++ if (cmp_mode == DImode && op1 == const0_rtx) ++ break; ++ code = swap_condition (code); ++ std::swap (op0, op1); ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (cmp_mode == DImode) ++ { ++ if (!reg_or_0_operand (op0, DImode)) ++ op0 = force_reg (DImode, op0); ++ if (!reg_or_8bit_operand (op1, DImode)) ++ op1 = force_reg (DImode, op1); ++ } ++ ++ /* ??? We mark the branch mode to be CCmode to prevent the compare ++ and cmov from being combined, since the compare insn follows IEEE ++ rules that the cmov does not. */ ++ if (cmp_mode == DFmode && !local_fast_math) ++ cmov_mode = CCmode; ++ ++ tem = gen_reg_rtx (cmp_mode); ++ emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1)); ++ return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode)); ++} ++ ++/* Simplify a conditional move of two constants into a setcc with ++ arithmetic. This is done with a splitter since combine would ++ just undo the work if done during code generation. It also catches ++ cases we wouldn't have before cse. */ ++ ++int ++sw_64_split_conditional_move (enum rtx_code code, rtx dest, rtx cond, rtx t_rtx, ++ rtx f_rtx) ++{ ++ HOST_WIDE_INT t, f, diff; ++ machine_mode mode; ++ rtx target, subtarget, tmp; ++ ++ mode = GET_MODE (dest); ++ t = INTVAL (t_rtx); ++ f = INTVAL (f_rtx); ++ diff = t - f; ++ ++ if (((code == NE || code == EQ) && diff < 0) || (code == GE || code == GT)) ++ { ++ code = reverse_condition (code); ++ std::swap (t, f); ++ diff = -diff; ++ } ++ ++ subtarget = target = dest; ++ if (mode != DImode) ++ { ++ target = gen_lowpart (DImode, dest); ++ if (can_create_pseudo_p ()) ++ subtarget = gen_reg_rtx (DImode); ++ else ++ subtarget = target; ++ } ++ /* Below, we must be careful to use copy_rtx on target and subtarget ++ in intermediate insns, as they may be a subreg rtx, which may not ++ be shared. */ ++ ++ if (f == 0 && exact_log2 (diff) > 0 ++ && (diff <= 8 || sw_64_tune == PROCESSOR_SW6 ++ || sw_64_tune == PROCESSOR_SW8)) ++ { ++ tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); ++ emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp)); ++ ++ tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget), ++ GEN_INT (exact_log2 (t))); ++ emit_insn (gen_rtx_SET (target, tmp)); ++ } ++ else if (f == 0 && t == -1) ++ { ++ tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); ++ emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp)); ++ ++ emit_insn (gen_negdi2 (target, copy_rtx (subtarget))); ++ } ++ else if (diff == 1 || diff == 4 || diff == 8) ++ { ++ rtx add_op; ++ ++ tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx); ++ emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp)); ++ ++ if (diff == 1) ++ emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f))); ++ else ++ { ++ add_op = GEN_INT (f); ++ if (sext_add_operand (add_op, mode)) ++ { ++ // in sw_64 sxsubw is ra*x + rb ++ tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget), GEN_INT (diff)); ++ tmp = gen_rtx_PLUS (DImode, tmp, add_op); ++ emit_insn (gen_rtx_SET (target, tmp)); ++ } ++ else ++ return 0; ++ } ++ } ++ else ++ return 0; ++ ++ return 1; ++} ++ ++/* Look up the function X_floating library function name for the ++ given operation. */ ++ ++struct GTY (()) xfloating_op ++{ ++ const enum rtx_code code; ++ const char *const GTY ((skip)) osf_func; ++ const char *const GTY ((skip)) vms_func; ++ rtx libcall; ++}; ++ ++static GTY (()) struct xfloating_op xfloating_ops[] ++ = {{PLUS, "_OtsAddX", "OTS$ADD_X", 0}, ++ {MINUS, "_OtsSubX", "OTS$SUB_X", 0}, ++ {MULT, "_OtsMulX", "OTS$MUL_X", 0}, ++ {DIV, "_OtsDivX", "OTS$DIV_X", 0}, ++ {EQ, "_OtsEqlX", "OTS$EQL_X", 0}, ++ {NE, "_OtsNeqX", "OTS$NEQ_X", 0}, ++ {LT, "_OtsLssX", "OTS$LSS_X", 0}, ++ {LE, "_OtsLeqX", "OTS$LEQ_X", 0}, ++ {GT, "_OtsGtrX", "OTS$GTR_X", 0}, ++ {GE, "_OtsGeqX", "OTS$GEQ_X", 0}, ++ {FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0}, ++ {FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0}, ++ {UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0}, ++ {FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0}, ++ {FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0}}; ++ ++static GTY (()) struct xfloating_op vax_cvt_ops[] ++ = {{FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0}, ++ {FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0}}; ++ ++static rtx ++sw_64_lookup_xfloating_lib_func (enum rtx_code code) ++{ ++ struct xfloating_op *ops = xfloating_ops; ++ long n = ARRAY_SIZE (xfloating_ops); ++ long i; ++ ++ gcc_assert (TARGET_HAS_XFLOATING_LIBS); ++ ++ /* How irritating. Nothing to key off for the main table. */ ++ if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE)) ++ { ++ ops = vax_cvt_ops; ++ n = ARRAY_SIZE (vax_cvt_ops); ++ } ++ ++ for (i = 0; i < n; ++i, ++ops) ++ if (ops->code == code) ++ { ++ rtx func = ops->libcall; ++ if (!func) ++ { ++ func = init_one_libfunc (ops->osf_func); ++ ops->libcall = func; ++ } ++ return func; ++ } ++ ++ gcc_unreachable (); ++} ++ ++/* Most X_floating operations take the rounding mode as an argument. ++ Compute that here. */ ++ ++static int ++sw_64_compute_xfloating_mode_arg (enum rtx_code code, ++ enum sw_64_fp_rounding_mode round) ++{ ++ int mode; ++ ++ switch (round) ++ { ++ case SW_64_FPRM_NORM: ++ mode = 2; ++ break; ++ case SW_64_FPRM_MINF: ++ mode = 1; ++ break; ++ case SW_64_FPRM_CHOP: ++ mode = 0; ++ break; ++ case SW_64_FPRM_DYN: ++ mode = 4; ++ break; ++ default: ++ gcc_unreachable (); ++ ++ /* XXX For reference, round to +inf is mode = 3. */ ++ } ++ ++ if (code == FLOAT_TRUNCATE && sw_64_fptm == SW_64_FPTM_N) ++ mode |= 0x10000; ++ ++ return mode; ++} ++ ++/* Emit an X_floating library function call. ++ ++ Note that these functions do not follow normal calling conventions: ++ TFmode arguments are passed in two integer registers (as opposed to ++ indirect); TFmode return values appear in R16+R17. ++ ++ FUNC is the function to call. ++ TARGET is where the output belongs. ++ OPERANDS are the inputs. ++ NOPERANDS is the count of inputs. ++ EQUIV is the expression equivalent for the function. ++ */ ++ ++static void ++sw_64_emit_xfloating_libcall (rtx func, rtx target, rtx operands[], ++ int noperands, rtx equiv) ++{ ++ rtx usage = NULL_RTX, reg; ++ int regno = 16, i; ++ ++ start_sequence (); ++ ++ for (i = 0; i < noperands; ++i) ++ { ++ switch (GET_MODE (operands[i])) ++ { ++ case E_TFmode: ++ reg = gen_rtx_REG (TFmode, regno); ++ regno += 2; ++ break; ++ ++ case E_DFmode: ++ reg = gen_rtx_REG (DFmode, regno + 32); ++ regno += 1; ++ break; ++ ++ case E_VOIDmode: ++ gcc_assert (CONST_INT_P (operands[i])); ++ /* FALLTHRU */ ++ case E_DImode: ++ reg = gen_rtx_REG (DImode, regno); ++ regno += 1; ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ emit_move_insn (reg, operands[i]); ++ use_reg (&usage, reg); ++ } ++ ++ switch (GET_MODE (target)) ++ { ++ case E_TFmode: ++ reg = gen_rtx_REG (TFmode, 16); ++ break; ++ case E_DFmode: ++ reg = gen_rtx_REG (DFmode, 32); ++ break; ++ case E_DImode: ++ reg = gen_rtx_REG (DImode, 0); ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ rtx mem = gen_rtx_MEM (QImode, func); ++ rtx_insn *tmp = emit_call_insn ( ++ gen_call_value (reg, mem, const0_rtx, const0_rtx, const0_rtx)); ++ CALL_INSN_FUNCTION_USAGE (tmp) = usage; ++ RTL_CONST_CALL_P (tmp) = 1; ++ ++ tmp = get_insns (); ++ end_sequence (); ++ ++ emit_libcall_block (tmp, target, reg, equiv); ++} ++ ++/* Emit an X_floating library function call for arithmetic (+,-,*,/). */ ++ ++void ++sw_64_emit_xfloating_arith (enum rtx_code code, rtx operands[]) ++{ ++ rtx func; ++ int mode; ++ rtx out_operands[3]; ++ ++ func = sw_64_lookup_xfloating_lib_func (code); ++ mode = sw_64_compute_xfloating_mode_arg (code, sw_64_fprm); ++ ++ out_operands[0] = operands[1]; ++ out_operands[1] = operands[2]; ++ out_operands[2] = GEN_INT (mode); ++ sw_64_emit_xfloating_libcall (func, operands[0], out_operands, 3, ++ gen_rtx_fmt_ee (code, TFmode, operands[1], ++ operands[2])); ++} ++ ++/* Emit an X_floating library function call for a comparison. */ ++ ++static rtx ++sw_64_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1) ++{ ++ enum rtx_code cmp_code, res_code; ++ rtx func, out, operands[2], note; ++ ++ /* X_floating library comparison functions return ++ -1 unordered ++ 0 false ++ 1 true ++ Convert the compare against the raw return value. */ ++ ++ cmp_code = *pcode; ++ switch (cmp_code) ++ { ++ case UNORDERED: ++ cmp_code = EQ; ++ res_code = LT; ++ break; ++ case ORDERED: ++ cmp_code = EQ; ++ res_code = GE; ++ break; ++ case NE: ++ res_code = NE; ++ break; ++ case EQ: ++ case LT: ++ case GT: ++ case LE: ++ case GE: ++ res_code = GT; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ *pcode = res_code; ++ ++ func = sw_64_lookup_xfloating_lib_func (cmp_code); ++ ++ operands[0] = op0; ++ operands[1] = op1; ++ out = gen_reg_rtx (DImode); ++ ++ /* What's actually returned is -1,0,1, not a proper boolean value. */ ++ note = gen_rtx_fmt_ee (cmp_code, VOIDmode, op0, op1); ++ note = gen_rtx_UNSPEC (DImode, gen_rtvec (1, note), UNSPEC_XFLT_COMPARE); ++ sw_64_emit_xfloating_libcall (func, out, operands, 2, note); ++ ++ return out; ++} ++ ++/* Emit an X_floating library function call for a conversion. */ ++ ++void ++sw_64_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[]) ++{ ++ int noperands = 1, mode; ++ rtx out_operands[2]; ++ rtx func; ++ enum rtx_code code = orig_code; ++ ++ if (code == UNSIGNED_FIX) ++ code = FIX; ++ ++ func = sw_64_lookup_xfloating_lib_func (code); ++ ++ out_operands[0] = operands[1]; ++ ++ switch (code) ++ { ++ case FIX: ++ mode = sw_64_compute_xfloating_mode_arg (code, SW_64_FPRM_CHOP); ++ out_operands[1] = GEN_INT (mode); ++ noperands = 2; ++ break; ++ case FLOAT_TRUNCATE: ++ mode = sw_64_compute_xfloating_mode_arg (code, sw_64_fprm); ++ out_operands[1] = GEN_INT (mode); ++ noperands = 2; ++ break; ++ default: ++ break; ++ } ++ ++ sw_64_emit_xfloating_libcall (func, operands[0], out_operands, noperands, ++ gen_rtx_fmt_e (orig_code, ++ GET_MODE (operands[0]), ++ operands[1])); ++} ++ ++/* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of ++ DImode moves from OP[2,3] to OP[0,1]. If FIXUP_OVERLAP is true, ++ guarantee that the sequence ++ set (OP[0] OP[2]) ++ set (OP[1] OP[3]) ++ is valid. Naturally, output operand ordering is little-endian. ++ This is used by *movtf_internal and *movti_internal. */ ++ ++void ++sw_64_split_tmode_pair (rtx operands[4], machine_mode mode, bool fixup_overlap) ++{ ++ switch (GET_CODE (operands[1])) ++ { ++ case REG: ++ operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1); ++ operands[2] = gen_rtx_REG (DImode, REGNO (operands[1])); ++ break; ++ ++ case MEM: ++ operands[3] = adjust_address (operands[1], DImode, 8); ++ operands[2] = adjust_address (operands[1], DImode, 0); ++ break; ++ ++ CASE_CONST_SCALAR_INT: ++ case CONST_DOUBLE: ++ gcc_assert (operands[1] == CONST0_RTX (mode)); ++ operands[2] = operands[3] = const0_rtx; ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ switch (GET_CODE (operands[0])) ++ { ++ case REG: ++ operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1); ++ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); ++ break; ++ ++ case MEM: ++ operands[1] = adjust_address (operands[0], DImode, 8); ++ operands[0] = adjust_address (operands[0], DImode, 0); ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3])) ++ { ++ std::swap (operands[0], operands[1]); ++ std::swap (operands[2], operands[3]); ++ } ++} ++ ++/* Implement negtf2 or abstf2. Op0 is destination, op1 is source, ++ op2 is a register containing the sign bit, operation is the ++ logical operation to be performed. */ ++ ++void ++sw_64_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx)) ++{ ++ rtx high_bit = operands[2]; ++ rtx scratch; ++ int move; ++ ++ sw_64_split_tmode_pair (operands, TFmode, false); ++ ++ /* Detect three flavors of operand overlap. */ ++ move = 1; ++ if (rtx_equal_p (operands[0], operands[2])) ++ move = 0; ++ else if (rtx_equal_p (operands[1], operands[2])) ++ { ++ if (rtx_equal_p (operands[0], high_bit)) ++ move = 2; ++ else ++ move = -1; ++ } ++ ++ if (move < 0) ++ emit_move_insn (operands[0], operands[2]); ++ ++ /* ??? If the destination overlaps both source tf and high_bit, then ++ assume source tf is dead in its entirety and use the other half ++ for a scratch register. Otherwise "scratch" is just the proper ++ destination register. */ ++ scratch = operands[move < 2 ? 1 : 3]; ++ ++ emit_insn ((*operation) (scratch, high_bit, operands[3])); ++ ++ if (move > 0) ++ { ++ emit_move_insn (operands[0], operands[2]); ++ if (move > 1) ++ emit_move_insn (operands[1], scratch); ++ } ++} ++ ++/* Use ext[wlq][lh] as the Architecture Handbook describes for extracting ++ unaligned data: ++ ++ unsigned: signed: ++ word: ldl_u r1,X(r11) ldl_u r1,X(r11) ++ ldl_u r2,X+1(r11) ldl_u r2,X+1(r11) ++ ldi r3,X(r11) ldi r3,X+2(r11) ++ exthl r1,r3,r1 extll r1,r3,r1 ++ exthh r2,r3,r2 extlh r2,r3,r2 ++ or r1.r2.r1 or r1,r2,r1 ++ sra r1,48,r1 ++ ++ long: ldl_u r1,X(r11) ldq_u r1,X(r11) ++ ldl_u r2,X+3(r11) ldq_u r2,X+3(r11) ++ ldi r3,X(r11) lda r3,X(r11) ++ extll r1,r3,r1 extll r1,r3,r1 ++ extlh r2,r3,r2 extlh r2,r3,r2 ++ or r1.r2.r1 addl r1,r2,r1 ++ ++ quad: ldl_u r1,X(r11) ++ ldl_u r2,X+7(r11) ++ ldi r3,X(r11) ++ extll r1,r3,r1 ++ extlh r2,r3,r2 ++ or r1.r2.r1 ++ */ ++ ++void ++sw_64_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size, ++ HOST_WIDE_INT ofs, int sign) ++{ ++ rtx meml, memh, addr, extl, exth, tmp, mema; ++ machine_mode mode; ++ ++ if (TARGET_BWX && size == 2) ++ { ++ meml = adjust_address (mem, QImode, ofs); ++ memh = adjust_address (mem, QImode, ofs + 1); ++ extl = gen_reg_rtx (DImode); ++ exth = gen_reg_rtx (DImode); ++ emit_insn (gen_zero_extendqidi2 (extl, meml)); ++ emit_insn (gen_zero_extendqidi2 (exth, memh)); ++ exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8), NULL, 1, ++ OPTAB_LIB_WIDEN); ++ addr = expand_simple_binop (DImode, IOR, extl, exth, NULL, 1, ++ OPTAB_LIB_WIDEN); ++ ++ if (sign && GET_MODE (tgt) != HImode) ++ { ++ addr = gen_lowpart (HImode, addr); ++ emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0)); ++ } ++ else ++ { ++ if (GET_MODE (tgt) != DImode) ++ addr = gen_lowpart (GET_MODE (tgt), addr); ++ emit_move_insn (tgt, addr); ++ } ++ return; ++ } ++ ++ meml = gen_reg_rtx (DImode); ++ memh = gen_reg_rtx (DImode); ++ addr = gen_reg_rtx (DImode); ++ extl = gen_reg_rtx (DImode); ++ exth = gen_reg_rtx (DImode); ++ ++ mema = XEXP (mem, 0); ++ rtx mema_const, mema_ptr; ++ if (GET_CODE (mema) == LO_SUM) ++ mema = force_reg (Pmode, mema); ++ ++ // TODO: split const ptr ++ if (GET_CODE (mema) == PLUS) ++ { ++ mema_ptr = XEXP (mema, 0); ++ mema_const = XEXP (mema, 1); ++ } ++ /* AND addresses cannot be in any alias set, since they may implicitly ++ alias surrounding code. Ideally we'd have some alias set that ++ covered all types except those with alignment 8 or higher. */ ++ ++ tmp = change_address (mem, DImode, ++ gen_rtx_AND (DImode, plus_constant (DImode, mema, ofs), ++ GEN_INT (-8))); ++ set_mem_alias_set (tmp, 0); ++ emit_move_insn (meml, tmp); ++ ++ tmp ++ = change_address (mem, DImode, ++ gen_rtx_AND (DImode, ++ plus_constant (DImode, mema, ofs + size - 1), ++ GEN_INT (-8))); ++ set_mem_alias_set (tmp, 0); ++ emit_move_insn (memh, tmp); ++ ++ if (sign && size == 2) ++ { ++ emit_move_insn (addr, plus_constant (Pmode, mema, ofs + 2)); ++ ++ emit_insn (gen_extql (extl, meml, addr)); ++ emit_insn (gen_extqh (exth, memh, addr)); ++ ++ /* We must use tgt here for the target. Sw_64 port fails if we use ++ addr for the target, because addr is marked as a pointer and combine ++ knows that pointers are always sign-extended 32-bit values. */ ++ addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN); ++ addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48), addr, 1, ++ OPTAB_WIDEN); ++ } ++ else ++ { ++ if (GET_CODE (mema) == PLUS && CONST_INT_P (mema_const) ++ && (!add_operand (mema_const, VOIDmode))) ++ { ++ rtx tmpreg = gen_reg_rtx (DImode); ++ tmpreg = sw_64_emit_set_const ( ++ tmpreg, DImode, INTVAL (plus_constant (Pmode, mema_const, ofs)), 2, ++ false); ++ emit_insn (gen_adddi3 (addr, mema_ptr, tmpreg)); ++ } ++ else ++ { ++ emit_move_insn (addr, plus_constant (Pmode, mema, ofs)); ++ } ++ emit_insn (gen_extxl (extl, meml, GEN_INT (size * 8), addr)); ++ switch ((int) size) ++ { ++ case 2: ++ emit_insn (gen_extwh (exth, memh, addr)); ++ mode = HImode; ++ break; ++ case 4: ++ emit_insn (gen_extlh (exth, memh, addr)); ++ mode = SImode; ++ break; ++ case 8: ++ emit_insn (gen_extqh (exth, memh, addr)); ++ mode = DImode; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl), ++ gen_lowpart (mode, exth), gen_lowpart (mode, tgt), ++ sign, OPTAB_WIDEN); ++ } ++ ++ if (addr != tgt) ++ emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr)); ++} ++ ++/* Similarly, use ins and msk instructions to perform unaligned stores. */ ++ ++void ++sw_64_expand_unaligned_store (rtx dst, rtx src, HOST_WIDE_INT size, ++ HOST_WIDE_INT ofs) ++{ ++ rtx dstl, dsth, addr, insl, insh, meml, memh, dsta; ++ ++ if (TARGET_BWX && size == 2) ++ { ++ if (src != const0_rtx) ++ { ++ dstl = gen_lowpart (QImode, src); ++ dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8), NULL, ++ 1, OPTAB_LIB_WIDEN); ++ dsth = gen_lowpart (QImode, dsth); ++ } ++ else ++ dstl = dsth = const0_rtx; ++ ++ meml = adjust_address (dst, QImode, ofs); ++ memh = adjust_address (dst, QImode, ofs + 1); ++ ++ emit_move_insn (meml, dstl); ++ emit_move_insn (memh, dsth); ++ return; ++ } ++ ++ dstl = gen_reg_rtx (DImode); ++ dsth = gen_reg_rtx (DImode); ++ insl = gen_reg_rtx (DImode); ++ insh = gen_reg_rtx (DImode); ++ ++ dsta = XEXP (dst, 0); ++ if (GET_CODE (dsta) == LO_SUM) ++ dsta = force_reg (Pmode, dsta); ++ ++ /* AND addresses cannot be in any alias set, since they may implicitly ++ alias surrounding code. Ideally we'd have some alias set that ++ covered all types except those with alignment 8 or higher. */ ++ ++ meml = change_address (dst, DImode, ++ gen_rtx_AND (DImode, plus_constant (DImode, dsta, ofs), ++ GEN_INT (-8))); ++ set_mem_alias_set (meml, 0); ++ ++ memh ++ = change_address (dst, DImode, ++ gen_rtx_AND (DImode, ++ plus_constant (DImode, dsta, ofs + size - 1), ++ GEN_INT (-8))); ++ set_mem_alias_set (memh, 0); ++ ++ emit_move_insn (dsth, memh); ++ emit_move_insn (dstl, meml); ++ ++ addr = copy_addr_to_reg (plus_constant (Pmode, dsta, ofs)); ++ ++ if (src != CONST0_RTX (GET_MODE (src))) ++ { ++ emit_insn ( ++ gen_insxh (insh, gen_lowpart (DImode, src), GEN_INT (size * 8), addr)); ++ ++ switch ((int) size) ++ { ++ case 2: ++ emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr)); ++ break; ++ case 4: ++ emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr)); ++ break; ++ case 8: ++ emit_insn (gen_insql (insl, gen_lowpart (DImode, src), addr)); ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ } ++ ++ emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size * 8), addr)); ++ ++ switch ((int) size) ++ { ++ case 2: ++ emit_insn (gen_mskwl (dstl, dstl, addr)); ++ break; ++ case 4: ++ emit_insn (gen_mskll (dstl, dstl, addr)); ++ break; ++ case 8: ++ emit_insn (gen_mskql (dstl, dstl, addr)); ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ if (src != CONST0_RTX (GET_MODE (src))) ++ { ++ dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN); ++ dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN); ++ } ++ ++ /* Must store high before low for degenerate case of aligned. */ ++ emit_move_insn (memh, dsth); ++ emit_move_insn (meml, dstl); ++} ++ ++/* The block move code tries to maximize speed by separating loads and ++ stores at the expense of register pressure: we load all of the data ++ before we store it back out. There are two secondary effects worth ++ mentioning, that this speeds copying to/from aligned and unaligned ++ buffers, and that it makes the code significantly easier to write. */ ++ ++#define MAX_MOVE_WORDS 8 ++ ++/* Load an integral number of consecutive unaligned quadwords. */ ++ ++static void ++sw_64_expand_unaligned_load_words (rtx *out_regs, rtx smem, HOST_WIDE_INT words, ++ HOST_WIDE_INT ofs) ++{ ++ rtx const im8 = GEN_INT (-8); ++ rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS + 1]; ++ rtx sreg, areg, tmp, smema; ++ HOST_WIDE_INT i; ++ ++ smema = XEXP (smem, 0); ++ if (GET_CODE (smema) == LO_SUM) ++ smema = force_reg (Pmode, smema); ++ ++ /* Generate all the tmp registers we need. */ ++ for (i = 0; i < words; ++i) ++ { ++ data_regs[i] = out_regs[i]; ++ ext_tmps[i] = gen_reg_rtx (DImode); ++ } ++ data_regs[words] = gen_reg_rtx (DImode); ++ ++ if (ofs != 0) ++ smem = adjust_address (smem, GET_MODE (smem), ofs); ++ ++ /* Load up all of the source data. */ ++ for (i = 0; i < words; ++i) ++ { ++ tmp = change_address (smem, DImode, ++ gen_rtx_AND (DImode, ++ plus_constant (DImode, smema, 8 * i), ++ im8)); ++ set_mem_alias_set (tmp, 0); ++ emit_move_insn (data_regs[i], tmp); ++ } ++ ++ tmp = change_address ( ++ smem, DImode, ++ gen_rtx_AND (DImode, plus_constant (DImode, smema, 8 * words - 1), im8)); ++ set_mem_alias_set (tmp, 0); ++ emit_move_insn (data_regs[words], tmp); ++ ++ /* Extract the half-word fragments. Unfortunately DEC decided to make ++ extxh with offset zero a noop instead of zeroing the register, so ++ we must take care of that edge condition ourselves with cmov. */ ++ ++ sreg = copy_addr_to_reg (smema); ++ areg ++ = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL, 1, OPTAB_WIDEN); ++ for (i = 0; i < words; ++i) ++ { ++ emit_insn (gen_extql (data_regs[i], data_regs[i], sreg)); ++ emit_insn (gen_extqh (ext_tmps[i], data_regs[i + 1], sreg)); ++ emit_insn (gen_rtx_SET ( ++ ext_tmps[i], ++ gen_rtx_IF_THEN_ELSE (DImode, gen_rtx_EQ (DImode, areg, const0_rtx), ++ const0_rtx, ext_tmps[i]))); ++ } ++ ++ /* Merge the half-words into whole words. */ ++ for (i = 0; i < words; ++i) ++ { ++ out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i], ext_tmps[i], ++ data_regs[i], 1, OPTAB_WIDEN); ++ } ++} ++ ++/* Store an integral number of consecutive unaligned quadwords. DATA_REGS ++ may be NULL to store zeros. */ ++ ++static void ++sw_64_expand_unaligned_store_words (rtx *data_regs, rtx dmem, ++ HOST_WIDE_INT words, HOST_WIDE_INT ofs) ++{ ++ rtx const im8 = GEN_INT (-8); ++ rtx ins_tmps[MAX_MOVE_WORDS]; ++ rtx st_tmp_1, st_tmp_2, dreg; ++ rtx st_addr_1, st_addr_2, dmema; ++ HOST_WIDE_INT i; ++ ++ dmema = XEXP (dmem, 0); ++ if (GET_CODE (dmema) == LO_SUM) ++ dmema = force_reg (Pmode, dmema); ++ ++ /* Generate all the tmp registers we need. */ ++ if (data_regs != NULL) ++ for (i = 0; i < words; ++i) ++ ins_tmps[i] = gen_reg_rtx (DImode); ++ st_tmp_1 = gen_reg_rtx (DImode); ++ st_tmp_2 = gen_reg_rtx (DImode); ++ ++ if (ofs != 0) ++ dmem = adjust_address (dmem, GET_MODE (dmem), ofs); ++ ++ st_addr_2 = change_address ( ++ dmem, DImode, ++ gen_rtx_AND (DImode, plus_constant (DImode, dmema, words * 8 - 1), im8)); ++ set_mem_alias_set (st_addr_2, 0); ++ ++ st_addr_1 = change_address (dmem, DImode, gen_rtx_AND (DImode, dmema, im8)); ++ set_mem_alias_set (st_addr_1, 0); ++ ++ /* Load up the destination end bits. */ ++ emit_move_insn (st_tmp_2, st_addr_2); ++ emit_move_insn (st_tmp_1, st_addr_1); ++ ++ /* Shift the input data into place. */ ++ dreg = copy_addr_to_reg (dmema); ++ if (data_regs != NULL) ++ { ++ for (i = words - 1; i >= 0; --i) ++ { ++ emit_insn (gen_insqh (ins_tmps[i], data_regs[i], dreg)); ++ emit_insn (gen_insql (data_regs[i], data_regs[i], dreg)); ++ } ++ for (i = words - 1; i > 0; --i) ++ { ++ ins_tmps[i - 1] ++ = expand_binop (DImode, ior_optab, data_regs[i], ins_tmps[i - 1], ++ ins_tmps[i - 1], 1, OPTAB_WIDEN); ++ } ++ } ++ ++ /* Split and merge the ends with the destination data. */ ++ emit_insn (gen_mskqh (st_tmp_2, st_tmp_2, dreg)); ++ emit_insn (gen_mskql (st_tmp_1, st_tmp_1, dreg)); ++ ++ if (data_regs != NULL) ++ { ++ st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words - 1], ++ st_tmp_2, 1, OPTAB_WIDEN); ++ st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0], ++ st_tmp_1, 1, OPTAB_WIDEN); ++ } ++ ++ /* Store it all. */ ++ emit_move_insn (st_addr_2, st_tmp_2); ++ for (i = words - 1; i > 0; --i) ++ { ++ rtx tmp = change_address ( ++ dmem, DImode, ++ gen_rtx_AND (DImode, plus_constant (DImode, dmema, i * 8), im8)); ++ set_mem_alias_set (tmp, 0); ++ emit_move_insn (tmp, data_regs ? ins_tmps[i - 1] : const0_rtx); ++ } ++ emit_move_insn (st_addr_1, st_tmp_1); ++} ++ ++/* Expand string/block move operations. ++ ++ operands[0] is the pointer to the destination. ++ operands[1] is the pointer to the source. ++ operands[2] is the number of bytes to move. ++ operands[3] is the alignment. */ ++ ++int ++sw_64_expand_block_move (rtx operands[]) ++{ ++ rtx bytes_rtx = operands[2]; ++ rtx align_rtx = operands[3]; ++ HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx); ++ HOST_WIDE_INT bytes = orig_bytes; ++ HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT; ++ HOST_WIDE_INT dst_align = src_align; ++ rtx orig_src = operands[1]; ++ rtx orig_dst = operands[0]; ++ rtx data_regs[2 * MAX_MOVE_WORDS + 16]; ++ rtx tmp; ++ unsigned int i, words, ofs, nregs = 0; ++ ++ if (orig_bytes <= 0) ++ return 1; ++ else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD) ++ return 0; ++ ++ /* Look for additional alignment information from recorded register info. */ ++ ++ tmp = XEXP (orig_src, 0); ++ if (REG_P (tmp)) ++ src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp))); ++ else if (GET_CODE (tmp) == PLUS && REG_P (XEXP (tmp, 0)) ++ && CONST_INT_P (XEXP (tmp, 1))) ++ { ++ unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); ++ unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); ++ ++ if (a > src_align) ++ { ++ if (a >= 64 && c % 8 == 0) ++ src_align = 64; ++ else if (a >= 32 && c % 4 == 0) ++ src_align = 32; ++ else if (a >= 16 && c % 2 == 0) ++ src_align = 16; ++ } ++ } ++ ++ tmp = XEXP (orig_dst, 0); ++ if (REG_P (tmp)) ++ dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp))); ++ else if (GET_CODE (tmp) == PLUS && REG_P (XEXP (tmp, 0)) ++ && CONST_INT_P (XEXP (tmp, 1))) ++ { ++ unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); ++ unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); ++ ++ if (a > dst_align) ++ { ++ if (a >= 64 && c % 8 == 0) ++ dst_align = 64; ++ else if (a >= 32 && c % 4 == 0) ++ dst_align = 32; ++ else if (a >= 16 && c % 2 == 0) ++ dst_align = 16; ++ } ++ } ++ ++ ofs = 0; ++ if (src_align >= 64 && bytes >= 8) ++ { ++ words = bytes / 8; ++ ++ for (i = 0; i < words; ++i) ++ data_regs[nregs + i] = gen_reg_rtx (DImode); ++ ++ for (i = 0; i < words; ++i) ++ emit_move_insn (data_regs[nregs + i], ++ adjust_address (orig_src, DImode, ofs + i * 8)); ++ ++ nregs += words; ++ bytes -= words * 8; ++ ofs += words * 8; ++ } ++ ++ if (src_align >= 32 && bytes >= 4) ++ { ++ words = bytes / 4; ++ ++ for (i = 0; i < words; ++i) ++ data_regs[nregs + i] = gen_reg_rtx (SImode); ++ ++ for (i = 0; i < words; ++i) ++ emit_move_insn (data_regs[nregs + i], ++ adjust_address (orig_src, SImode, ofs + i * 4)); ++ ++ nregs += words; ++ bytes -= words * 4; ++ ofs += words * 4; ++ } ++ ++ if (bytes >= 8) ++ { ++ words = bytes / 8; ++ ++ for (i = 0; i < words + 1; ++i) ++ data_regs[nregs + i] = gen_reg_rtx (DImode); ++ ++ sw_64_expand_unaligned_load_words (data_regs + nregs, orig_src, words, ++ ofs); ++ ++ nregs += words; ++ bytes -= words * 8; ++ ofs += words * 8; ++ } ++ ++ if (!TARGET_BWX && bytes >= 4) ++ { ++ data_regs[nregs++] = tmp = gen_reg_rtx (SImode); ++ sw_64_expand_unaligned_load (tmp, orig_src, 4, ofs, 0); ++ bytes -= 4; ++ ofs += 4; ++ } ++ ++ if (bytes >= 2) ++ { ++ if (src_align >= 16) ++ { ++ do ++ { ++ data_regs[nregs++] = tmp = gen_reg_rtx (HImode); ++ emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs)); ++ bytes -= 2; ++ ofs += 2; ++ } while (bytes >= 2); ++ } ++ else if (!TARGET_BWX) ++ { ++ data_regs[nregs++] = tmp = gen_reg_rtx (HImode); ++ sw_64_expand_unaligned_load (tmp, orig_src, 2, ofs, 0); ++ bytes -= 2; ++ ofs += 2; ++ } ++ } ++ ++ while (bytes > 0) ++ { ++ data_regs[nregs++] = tmp = gen_reg_rtx (QImode); ++ emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs)); ++ bytes -= 1; ++ ofs += 1; ++ } ++ ++ gcc_assert (nregs <= ARRAY_SIZE (data_regs)); ++ ++ /* Now save it back out again. */ ++ ++ i = 0, ofs = 0; ++ ++ /* Write out the data in whatever chunks reading the source allowed. */ ++ if (dst_align >= 64) ++ { ++ while (i < nregs && GET_MODE (data_regs[i]) == DImode) ++ { ++ emit_move_insn (adjust_address (orig_dst, DImode, ofs), data_regs[i]); ++ ofs += 8; ++ i++; ++ } ++ } ++ ++ if (dst_align >= 32) ++ { ++ /* If the source has remaining DImode regs, write them out in ++ two pieces. */ ++ while (i < nregs && GET_MODE (data_regs[i]) == DImode) ++ { ++ tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32), ++ NULL_RTX, 1, OPTAB_WIDEN); ++ ++ emit_move_insn (adjust_address (orig_dst, SImode, ofs), ++ gen_lowpart (SImode, data_regs[i])); ++ emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4), ++ gen_lowpart (SImode, tmp)); ++ ofs += 8; ++ i++; ++ } ++ ++ while (i < nregs && GET_MODE (data_regs[i]) == SImode) ++ { ++ emit_move_insn (adjust_address (orig_dst, SImode, ofs), data_regs[i]); ++ ofs += 4; ++ i++; ++ } ++ } ++ ++ if (i < nregs && GET_MODE (data_regs[i]) == DImode) ++ { ++ /* Write out a remaining block of words using unaligned methods. */ ++ ++ for (words = 1; i + words < nregs; words++) ++ if (GET_MODE (data_regs[i + words]) != DImode) ++ break; ++ ++ if (words == 1) ++ sw_64_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs); ++ else ++ sw_64_expand_unaligned_store_words (data_regs + i, orig_dst, words, ++ ofs); ++ ++ i += words; ++ ofs += words * 8; ++ } ++ ++ /* Due to the above, this won't be aligned. */ ++ /* ??? If we have more than one of these, consider constructing full ++ words in registers and using sw_64_expand_unaligned_store_words. */ ++ while (i < nregs && GET_MODE (data_regs[i]) == SImode) ++ { ++ sw_64_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs); ++ ofs += 4; ++ i++; ++ } ++ ++ if (dst_align >= 16) ++ while (i < nregs && GET_MODE (data_regs[i]) == HImode) ++ { ++ emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]); ++ i++; ++ ofs += 2; ++ } ++ else ++ while (i < nregs && GET_MODE (data_regs[i]) == HImode) ++ { ++ sw_64_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs); ++ i++; ++ ofs += 2; ++ } ++ ++ /* The remainder must be byte copies. */ ++ while (i < nregs) ++ { ++ gcc_assert (GET_MODE (data_regs[i]) == QImode); ++ emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]); ++ i++; ++ ofs += 1; ++ } ++ ++ return 1; ++} ++ ++int ++sw_64_expand_block_clear (rtx operands[]) ++{ ++ rtx bytes_rtx = operands[1]; ++ rtx align_rtx = operands[3]; ++ HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx); ++ HOST_WIDE_INT bytes = orig_bytes; ++ HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT; ++ HOST_WIDE_INT alignofs = 0; ++ rtx orig_dst = operands[0]; ++ rtx tmp; ++ int i, words, ofs = 0; ++ ++ if (orig_bytes <= 0) ++ return 1; ++ if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD) ++ return 0; ++ ++ /* Look for stricter alignment. */ ++ tmp = XEXP (orig_dst, 0); ++ if (REG_P (tmp)) ++ align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp))); ++ else if (GET_CODE (tmp) == PLUS && REG_P (XEXP (tmp, 0)) ++ && CONST_INT_P (XEXP (tmp, 1))) ++ { ++ HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1)); ++ int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0))); ++ ++ if (a > align) ++ { ++ if (a >= 64) ++ align = a, alignofs = 8 - c % 8; ++ else if (a >= 32) ++ align = a, alignofs = 4 - c % 4; ++ else if (a >= 16) ++ align = a, alignofs = 2 - c % 2; ++ } ++ } ++ ++ /* Handle an unaligned prefix first. */ ++ ++ if (alignofs > 0) ++ { ++ /* Given that alignofs is bounded by align, the only time BWX could ++ generate three stores is for a 7 byte fill. Prefer two individual ++ stores over a load/mask/store sequence. */ ++ if ((!TARGET_BWX || alignofs == 7) && align >= 32 ++ && !(alignofs == 4 && bytes >= 4)) ++ { ++ machine_mode mode = (align >= 64 ? DImode : SImode); ++ int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs; ++ rtx mem, tmp; ++ HOST_WIDE_INT mask; ++ ++ mem = adjust_address (orig_dst, mode, ofs - inv_alignofs); ++ set_mem_alias_set (mem, 0); ++ ++ mask = ~(HOST_WIDE_INT_M1U << (inv_alignofs * 8)); ++ if (bytes < alignofs) ++ { ++ mask |= HOST_WIDE_INT_M1U << ((inv_alignofs + bytes) * 8); ++ ofs += bytes; ++ bytes = 0; ++ } ++ else ++ { ++ bytes -= alignofs; ++ ofs += alignofs; ++ } ++ alignofs = 0; ++ ++ tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask), NULL_RTX, 1, ++ OPTAB_WIDEN); ++ ++ emit_move_insn (mem, tmp); ++ } ++ ++ if (TARGET_BWX && (alignofs & 1) && bytes >= 1) ++ { ++ emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx); ++ bytes -= 1; ++ ofs += 1; ++ alignofs -= 1; ++ } ++ if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2) ++ { ++ emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx); ++ bytes -= 2; ++ ofs += 2; ++ alignofs -= 2; ++ } ++ if (alignofs == 4 && bytes >= 4) ++ { ++ emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx); ++ bytes -= 4; ++ ofs += 4; ++ alignofs = 0; ++ } ++ ++ /* If we've not used the extra lead alignment information by now, ++ we won't be able to. Downgrade align to match what's left over. */ ++ if (alignofs > 0) ++ { ++ alignofs = alignofs & -alignofs; ++ align = MIN (align, alignofs * BITS_PER_UNIT); ++ } ++ } ++ ++ /* Handle a block of contiguous long-words. */ ++ ++ if (align >= 64 && bytes >= 8) ++ { ++ words = bytes / 8; ++ ++ for (i = 0; i < words; ++i) ++ emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8), ++ const0_rtx); ++ ++ bytes -= words * 8; ++ ofs += words * 8; ++ } ++ ++ /* If the block is large and appropriately aligned, emit a single ++ store followed by a sequence of stl_u insns. */ ++ ++ if (align >= 32 && bytes > 16) ++ { ++ rtx orig_dsta; ++ ++ emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx); ++ bytes -= 4; ++ ofs += 4; ++ ++ orig_dsta = XEXP (orig_dst, 0); ++ if (GET_CODE (orig_dsta) == LO_SUM) ++ orig_dsta = force_reg (Pmode, orig_dsta); ++ ++ words = bytes / 8; ++ for (i = 0; i < words; ++i) ++ { ++ rtx mem = change_address ( ++ orig_dst, DImode, ++ gen_rtx_AND (DImode, plus_constant (DImode, orig_dsta, ofs + i * 8), ++ GEN_INT (-8))); ++ set_mem_alias_set (mem, 0); ++ emit_move_insn (mem, const0_rtx); ++ } ++ ++ /* Depending on the alignment, the first stl_u may have overlapped ++ with the initial stl, which means that the last stl_u didn't ++ write as much as it would appear. Leave those questionable bytes ++ unaccounted for. */ ++ bytes -= words * 8 - 4; ++ ofs += words * 8 - 4; ++ } ++ ++ /* Handle a smaller block of aligned words. */ ++ ++ if ((align >= 64 && bytes == 4) || (align == 32 && bytes >= 4)) ++ { ++ words = bytes / 4; ++ ++ for (i = 0; i < words; ++i) ++ emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4), ++ const0_rtx); ++ ++ bytes -= words * 4; ++ ofs += words * 4; ++ } ++ ++ /* An unaligned block uses stl_u stores for as many as possible. */ ++ ++ if (bytes >= 8) ++ { ++ words = bytes / 8; ++ ++ sw_64_expand_unaligned_store_words (NULL, orig_dst, words, ofs); ++ ++ bytes -= words * 8; ++ ofs += words * 8; ++ } ++ ++ /* Next clean up any trailing pieces. */ ++ ++ /* Count the number of bits in BYTES for which aligned stores could ++ be emitted. */ ++ words = 0; ++ for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align; i <<= 1) ++ if (bytes & i) ++ words += 1; ++ ++ /* If we have appropriate alignment (and it wouldn't take too many ++ instructions otherwise), mask out the bytes we need. */ ++ if (TARGET_BWX ? words > 2 : bytes > 0) ++ { ++ if (align >= 64) ++ { ++ rtx mem, tmp; ++ HOST_WIDE_INT mask; ++ ++ mem = adjust_address (orig_dst, DImode, ofs); ++ set_mem_alias_set (mem, 0); ++ ++ mask = HOST_WIDE_INT_M1U << (bytes * 8); ++ ++ tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask), NULL_RTX, ++ 1, OPTAB_WIDEN); ++ ++ emit_move_insn (mem, tmp); ++ return 1; ++ } ++ else if (align >= 32 && bytes < 4) ++ { ++ rtx mem, tmp; ++ HOST_WIDE_INT mask; ++ ++ mem = adjust_address (orig_dst, SImode, ofs); ++ set_mem_alias_set (mem, 0); ++ ++ mask = HOST_WIDE_INT_M1U << (bytes * 8); ++ ++ tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask), NULL_RTX, ++ 1, OPTAB_WIDEN); ++ ++ emit_move_insn (mem, tmp); ++ return 1; ++ } ++ } ++ ++ if (!TARGET_BWX && bytes >= 4) ++ { ++ sw_64_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs); ++ bytes -= 4; ++ ofs += 4; ++ } ++ ++ if (bytes >= 2) ++ { ++ if (align >= 16) ++ { ++ do ++ { ++ emit_move_insn (adjust_address (orig_dst, HImode, ofs), ++ const0_rtx); ++ bytes -= 2; ++ ofs += 2; ++ } while (bytes >= 2); ++ } ++ else if (!TARGET_BWX) ++ { ++ sw_64_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs); ++ bytes -= 2; ++ ofs += 2; ++ } ++ } ++ ++ while (bytes > 0) ++ { ++ emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx); ++ bytes -= 1; ++ ofs += 1; ++ } ++ ++ return 1; ++} ++ ++/* Returns a mask so that zap (x, value) == x & mask. */ ++ ++rtx ++sw_64_expand_zap_mask (HOST_WIDE_INT value) ++{ ++ rtx result; ++ int i; ++ HOST_WIDE_INT mask = 0; ++ ++ for (i = 7; i >= 0; --i) ++ { ++ mask <<= 8; ++ if (!((value >> i) & 1)) ++ mask |= 0xff; ++ } ++ ++ result = gen_int_mode (mask, DImode); ++ return result; ++} ++ ++void ++sw_64_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx), ++ machine_mode mode, rtx op0, rtx op1, rtx op2) ++{ ++ op0 = gen_lowpart (mode, op0); ++ ++ if (op1 == const0_rtx) ++ op1 = CONST0_RTX (mode); ++ else ++ op1 = gen_lowpart (mode, op1); ++ ++ if (op2 == const0_rtx) ++ op2 = CONST0_RTX (mode); ++ else ++ op2 = gen_lowpart (mode, op2); ++ ++ emit_insn ((*gen) (op0, op1, op2)); ++} ++ ++/* A subroutine of the atomic operation splitters. Jump to LABEL if ++ COND is true. Mark the jump as unlikely to be taken. */ ++ ++static void ++emit_unlikely_jump (rtx cond, rtx label) ++{ ++ rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx); ++ rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x)); ++ add_reg_br_prob_note (insn, profile_probability::very_unlikely ()); ++} ++ ++/* Subroutines of the atomic operation splitters. Emit barriers ++ as needed for the memory MODEL. */ ++ ++static void ++sw_64_pre_atomic_barrier (enum memmodel model) ++{ ++ if (need_atomic_barrier_p (model, true)) ++ emit_insn (gen_memory_barrier ()); ++} ++ ++static void ++sw_64_post_atomic_barrier (enum memmodel model) ++{ ++ if (need_atomic_barrier_p (model, false)) ++ emit_insn (gen_memory_barrier ()); ++} ++ ++/* A subroutine of the atomic operation splitters. Emit an insxl ++ instruction in MODE. */ ++ ++static rtx ++emit_insxl (machine_mode mode, rtx op1, rtx op2) ++{ ++ rtx ret = gen_reg_rtx (DImode); ++ rtx (*fn) (rtx, rtx, rtx); ++ ++ switch (mode) ++ { ++ case E_QImode: ++ fn = gen_insbl; ++ break; ++ case E_HImode: ++ fn = gen_inswl; ++ break; ++ case E_SImode: ++ fn = gen_insll; ++ break; ++ case E_DImode: ++ fn = gen_insql; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ op1 = force_reg (mode, op1); ++ emit_insn (fn (ret, op1, op2)); ++ ++ return ret; ++} ++ ++rtx ++gen_move_reg (rtx x) ++{ ++ rtx temp = gen_reg_rtx (GET_MODE (x)); ++ emit_move_insn (temp, x); ++ return temp; ++} ++ ++/* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P, ++ * * add a reg_note saying that this was a division. Support both scalar ++ * and ++ * * vector divide. Assumes no trapping math and finite arguments. */ ++ ++void ++sw_64_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p) ++{ ++ machine_mode mode = GET_MODE (dst); ++ rtx one, x0, e0, x1, x2, xprev, eprev, xnext, enext, u, v; ++ int i; ++ ++ int passes = flag_sw_recip_precision ? 2 : 1; ++ if (mode == DFmode) ++ passes += 2; ++ ++ enum insn_code code = optab_handler (smul_optab, mode); ++ insn_gen_fn gen_mul = GEN_FCN (code); ++ gcc_assert (code != CODE_FOR_nothing); ++ ++ enum insn_code code1 = optab_handler (fma_optab, mode); ++ insn_gen_fn gen_fma = GEN_FCN (code1); ++ gcc_assert (code1 != CODE_FOR_nothing); ++ ++ enum insn_code code2 = optab_handler (fnma_optab, mode); ++ insn_gen_fn gen_fnma = GEN_FCN (code2); ++ gcc_assert (code2 != CODE_FOR_nothing); ++ ++ one = sw_64_load_constant_and_splat (mode, dconst1); ++ ++ /* x0 = 1./d estimate */ ++ x0 = gen_reg_rtx (mode); ++ emit_insn ( ++ gen_rtx_SET (x0, gen_rtx_UNSPEC (mode, gen_rtvec (1, d), UNSPEC_FRECX))); ++ ++ /* Each iteration but the last calculates x_(i+1) = x_i * (2 - d * x_i). */ ++ if (passes > 1) ++ { ++ /* e0 = 1. - d * x0 */ ++ e0 = gen_reg_rtx (mode); ++ emit_insn (gen_fnma (e0, d, x0, one)); ++ ++ /* x1 = x0 + e0 * x0 */ ++ x1 = gen_reg_rtx (mode); ++ emit_insn (gen_fma (x1, x0, e0, x0)); ++ ++ for (i = 0, xprev = x1, eprev = e0; i < passes - 2; ++ ++i, xprev = xnext, eprev = enext) ++ { ++ /* enext = eprev * eprev */ ++ enext = gen_reg_rtx (mode); ++ emit_insn (gen_mul (enext, eprev, eprev)); ++ ++ /* xnext = xprev + enext * xprev */ ++ xnext = gen_reg_rtx (mode); ++ emit_insn (gen_fma (xnext, xprev, enext, xprev)); ++ } ++ } ++ else ++ xprev = x0; ++ ++ /* The last iteration calculates x_(i+1) = n * x_i * (2 - d * x_i). */ ++ /* u = n * xprev */ ++ u = gen_reg_rtx (mode); ++ emit_insn (gen_mul (u, n, xprev)); ++ ++ /* v = n - (d * u) */ ++ v = gen_reg_rtx (mode); ++ emit_insn (gen_fnma (v, d, u, n)); ++ ++ /* dst = (v * xprev) + u */ ++ emit_insn (gen_fma (dst, v, xprev, u)); ++} ++ ++/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation ++ to perform. MEM is the memory on which to operate. VAL is the second ++ operand of the binary operator. BEFORE and AFTER are optional locations to ++ return the value of MEM either before of after the operation. SCRATCH is ++ a scratch register. */ ++ ++void ++sw_64_split_atomic_op (enum rtx_code code, rtx mem, rtx val, rtx before, ++ rtx after, rtx scratch, enum memmodel model) ++{ ++ machine_mode mode = GET_MODE (mem); ++ rtx label, x, cond = gen_rtx_REG (DImode, REGNO (scratch)); ++ ++ if (flag_sw_delmemb == 0) ++ sw_64_pre_atomic_barrier (model); ++ label = gen_label_rtx (); ++ emit_label (label); ++ label = gen_rtx_LABEL_REF (DImode, label); ++ ++ if (before == NULL) ++ before = scratch; ++ emit_insn (gen_load_locked (mode, before, mem)); ++ if (!TARGET_SW8A) ++ { ++ if (after) ++ { ++ rtx cond1 = gen_rtx_REG (DImode, REGNO (after)); ++ emit_insn (gen_rtx_SET (cond1, const1_rtx)); ++ emit_insn (gen_builtin_wr_f (cond1)); ++ } ++ else ++ { ++ rtx cond2 = gen_rtx_REG (DImode, 28); ++ emit_insn (gen_rtx_SET (cond2, const1_rtx)); ++ emit_insn (gen_builtin_wr_f (cond2)); ++ } ++ } ++ if (code == NOT) ++ { ++ x = gen_rtx_AND (mode, before, val); ++ emit_insn (gen_rtx_SET (val, x)); ++ ++ x = gen_rtx_NOT (mode, val); ++ } ++ else ++ x = gen_rtx_fmt_ee (code, mode, before, val); ++ if (after) ++ emit_insn (gen_rtx_SET (after, copy_rtx (x))); ++ emit_insn (gen_rtx_SET (scratch, x)); ++ ++ emit_insn (gen_store_conditional (mode, cond, mem, scratch)); ++ if (!TARGET_SW8A) ++ emit_insn (gen_builtin_rd_f (cond)); ++ ++ ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ emit_unlikely_jump (x, label); ++} ++ ++/* Expand a compare and swap operation. */ ++ ++void ++sw_64_split_compare_and_swap (rtx operands[]) ++{ ++ rtx cond, retval, mem, oldval, newval; ++ bool is_weak; ++ enum memmodel mod_s, mod_f; ++ machine_mode mode; ++ rtx label1, label2, x; ++ ++ rtx imust = operands[8]; ++ cond = operands[0]; ++ retval = operands[1]; ++ mem = operands[2]; ++ oldval = operands[3]; ++ newval = operands[4]; ++ is_weak = (operands[5] != const0_rtx); ++ mod_s = memmodel_from_int (INTVAL (operands[6])); ++ mod_f = memmodel_from_int (INTVAL (operands[7])); ++ mode = GET_MODE (mem); ++ ++ if (flag_sw_delmemb == 0) ++ sw_64_pre_atomic_barrier (mod_s); ++ ++ label1 = NULL_RTX; ++ if (!is_weak) ++ { ++ label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); ++ emit_label (XEXP (label1, 0)); ++ } ++ label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); ++ ++ emit_insn (gen_load_locked (mode, retval, mem)); ++ x = gen_lowpart (DImode, retval); ++ rtx imust1; ++ if (TARGET_SW8A) ++ { ++ if (oldval == const0_rtx) ++ { ++ emit_move_insn (cond, const0_rtx); ++ x = gen_rtx_NE (DImode, x, const0_rtx); ++ } ++ else ++ { ++ x = gen_rtx_EQ (DImode, x, oldval); ++ emit_insn (gen_rtx_SET (cond, x)); ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ } ++ emit_unlikely_jump (x, label2); ++ } ++ else ++ { ++ x = gen_rtx_EQ (DImode, x, oldval); ++ imust1 = gen_lowpart (DImode, imust); ++ emit_insn (gen_rtx_SET (imust1, x)); ++ emit_insn (gen_builtin_wr_f (imust1)); ++ } ++ ++ emit_move_insn (cond, newval); ++ emit_insn (gen_store_conditional (mode, cond, mem, gen_lowpart (mode, cond))); ++ ++ if (!TARGET_SW8A) ++ { ++ emit_insn (gen_builtin_rd_f (cond)); ++ imust1 = gen_rtx_EQ (DImode, imust1, const0_rtx); ++ emit_unlikely_jump (imust1, label2); ++ } ++ if (!is_weak) ++ { ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ emit_unlikely_jump (x, label1); ++ } ++ ++ if (!is_mm_relaxed (mod_f)) ++ emit_label (XEXP (label2, 0)); ++ ++ if (is_mm_relaxed (mod_f)) ++ emit_label (XEXP (label2, 0)); ++} ++ ++void ++sw_64_expand_compare_and_swap_12 (rtx operands[]) ++{ ++ rtx cond, dst, mem, oldval, newval, is_weak, mod_s, mod_f; ++ machine_mode mode; ++ rtx addr, align, wdst; ++ rtx imust; ++ ++ cond = operands[0]; ++ dst = operands[1]; ++ mem = operands[2]; ++ oldval = operands[3]; ++ newval = operands[4]; ++ is_weak = operands[5]; ++ mod_s = operands[6]; ++ mod_f = operands[7]; ++ mode = GET_MODE (mem); ++ bool use_cas = GET_MODE_SIZE (mode) >= 32 && flag_sw_use_cas; ++ if (!use_cas) ++ imust = operands[8]; ++ ++ /* We forced the address into a register via mem_noofs_operand. */ ++ addr = XEXP (mem, 0); ++ gcc_assert (register_operand (addr, DImode)); ++ ++ align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8), NULL_RTX, 1, ++ OPTAB_DIRECT); ++ ++ if (oldval != const0_rtx && TARGET_SW8A && use_cas) ++ oldval = emit_insxl (mode, oldval, addr); ++ oldval = convert_modes (DImode, mode, oldval, 1); ++ ++ if (newval != const0_rtx) ++ newval = emit_insxl (mode, newval, addr); ++ ++ wdst = gen_reg_rtx (DImode); ++ if (TARGET_SW8A && use_cas) ++ emit_insn (gen_atomic_compare_and_swap_1_target_sw8a ( ++ mode, cond, wdst, mem, oldval, newval, align, is_weak, mod_s, mod_f)); ++ else ++ emit_insn (gen_atomic_compare_and_swap_1 (mode, cond, wdst, mem, oldval, ++ newval, align, is_weak, mod_s, ++ mod_f, imust)); ++ emit_move_insn (dst, gen_lowpart (mode, wdst)); ++} ++ ++void ++sw_64_split_compare_and_swap_12 (rtx operands[]) ++{ ++ rtx cond, dest, orig_mem, oldval, newval, align, scratch; ++ machine_mode mode; ++ bool is_weak; ++ enum memmodel mod_s, mod_f; ++ rtx label1, label2, mem, addr, width, mask, x; ++ rtx imust; ++ ++ cond = operands[0]; ++ dest = operands[1]; ++ orig_mem = operands[2]; ++ oldval = operands[3]; ++ newval = operands[4]; ++ align = operands[5]; ++ is_weak = (operands[6] != const0_rtx); ++ mod_s = memmodel_from_int (INTVAL (operands[7])); ++ mod_f = memmodel_from_int (INTVAL (operands[8])); ++ imust = operands[9]; ++ scratch = operands[10]; ++ mode = GET_MODE (orig_mem); ++ addr = XEXP (orig_mem, 0); ++ ++ mem = gen_rtx_MEM (DImode, align); ++ MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); ++ if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER) ++ set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); ++ ++ if (flag_sw_delmemb == 0) ++ sw_64_pre_atomic_barrier (mod_s); ++ ++ label1 = NULL_RTX; ++ if (!is_weak) ++ { ++ label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); ++ emit_label (XEXP (label1, 0)); ++ } ++ label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); ++ ++ emit_insn (gen_load_locked (DImode, scratch, mem)); ++ ++ width = GEN_INT (GET_MODE_BITSIZE (mode)); ++ mask = GEN_INT (mode == QImode ? 0xff : 0xffff); ++ emit_insn (gen_extxl (dest, scratch, width, addr)); ++ ++ rtx imust1; ++ if (TARGET_SW8A) ++ { ++ if (oldval == const0_rtx) ++ { ++ emit_move_insn (cond, const0_rtx); ++ x = gen_rtx_NE (DImode, dest, const0_rtx); ++ } ++ else ++ { ++ x = gen_rtx_EQ (DImode, dest, oldval); ++ emit_insn (gen_rtx_SET (cond, x)); ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ } ++ emit_unlikely_jump (x, label2); ++ } ++ else ++ { ++ x = gen_rtx_EQ (DImode, dest, oldval); ++ imust1 = gen_lowpart (DImode, imust); ++ emit_insn (gen_rtx_SET (imust1, x)); ++ emit_insn (gen_builtin_wr_f (imust1)); ++ } ++ emit_insn (gen_mskxl (cond, scratch, mask, addr)); ++ ++ if (newval != const0_rtx) ++ emit_insn (gen_iordi3 (cond, cond, newval)); ++ ++ emit_insn (gen_store_conditional (DImode, cond, mem, cond)); ++ if (!TARGET_SW8A) ++ { ++ emit_insn (gen_builtin_rd_f (cond)); ++ imust1 = gen_rtx_EQ (DImode, imust1, const0_rtx); ++ emit_unlikely_jump (imust1, label2); ++ } ++ ++ if (!is_weak) ++ { ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ emit_unlikely_jump (x, label1); ++ } ++ ++ if (!is_mm_relaxed (mod_f)) ++ emit_label (XEXP (label2, 0)); ++ ++ if (is_mm_relaxed (mod_f)) ++ emit_label (XEXP (label2, 0)); ++} ++ ++/* Expand an atomic exchange operation. */ ++ ++void ++sw_64_split_atomic_exchange (rtx operands[]) ++{ ++ rtx retval, mem, val, scratch; ++ enum memmodel model; ++ machine_mode mode; ++ rtx label, x, cond; ++ ++ retval = operands[0]; ++ mem = operands[1]; ++ val = operands[2]; ++ model = (enum memmodel) INTVAL (operands[3]); ++ scratch = operands[4]; ++ mode = GET_MODE (mem); ++ cond = gen_lowpart (DImode, scratch); ++ ++ if (flag_sw_delmemb == 0) ++ sw_64_pre_atomic_barrier (model); ++ label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); ++ emit_label (XEXP (label, 0)); ++ ++ emit_insn (gen_load_locked (mode, retval, mem)); ++ if (!TARGET_SW8A) ++ { ++ emit_insn (gen_rtx_SET (cond, const1_rtx)); ++ emit_insn (gen_builtin_wr_f (cond)); ++ } ++ emit_move_insn (scratch, val); ++ emit_insn (gen_store_conditional (mode, cond, mem, scratch)); ++ if (!TARGET_SW8A) ++ emit_insn (gen_builtin_rd_f (cond)); ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ emit_unlikely_jump (x, label); ++} ++ ++/* Emit an atomic compare-and-swap operation. SI and larger modes */ ++void ++sw_64_split_atomic_cas (rtx operands[]) ++{ ++ rtx cond, retval, mem, oldval, newval; ++ rtx (*gen) (rtx, rtx, rtx); ++ enum memmodel mod_s; ++ machine_mode mode; ++ ++ cond = operands[0]; ++ retval = operands[1]; ++ mem = operands[2]; ++ oldval = operands[3]; ++ newval = operands[4]; ++ ++ mod_s = memmodel_from_int (INTVAL (operands[6])); ++ mode = GET_MODE (mem); ++ ++ if (GET_MODE (mem) == SImode && GET_MODE (oldval) == DImode ++ && GET_MODE (newval) == DImode) ++ { ++ oldval = gen_rtx_REG (SImode, REGNO (oldval)); ++ newval = gen_rtx_REG (SImode, REGNO (newval)); ++ } ++ ++ switch (mode) ++ { ++ case E_SImode: ++ gen = gen_sw_64_atomic_cassi; ++ break; ++ case E_DImode: ++ gen = gen_sw_64_atomic_casdi; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ emit_insn (gen_rtx_SET (retval, newval)); ++ emit_insn (gen (oldval, mem, retval)); ++ ++ rtx x = gen_lowpart (DImode, retval); ++ rtx x1 = gen_lowpart (DImode, oldval); ++ x = gen_rtx_EQ (DImode, x, x1); ++ emit_insn (gen_rtx_SET (cond, x)); ++} ++ ++/* Emit an atomic compare-and-swap operation. HI and smaller modes */ ++void ++sw_64_split_atomic_cas_12 (rtx operands[]) ++{ ++ rtx cond, dest, orig_mem, oldval, newval, align, scratch; ++ machine_mode mode; ++ bool is_weak; ++ enum memmodel mod_s, mod_f; ++ rtx label1, label2, mem, addr, width, mask, x; ++ ++ cond = operands[0]; ++ dest = operands[1]; ++ orig_mem = operands[2]; ++ oldval = operands[3]; ++ newval = operands[4]; ++ align = operands[5]; ++ is_weak = (operands[6] != const0_rtx); ++ mod_s = memmodel_from_int (INTVAL (operands[7])); ++ mod_f = memmodel_from_int (INTVAL (operands[8])); ++ scratch = operands[9]; ++ mode = GET_MODE (orig_mem); ++ addr = XEXP (orig_mem, 0); ++ ++ mem = gen_rtx_MEM (DImode, align); ++ MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); ++ if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER) ++ set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); ++ ++ emit_move_insn (scratch, mem); ++ ++ width = GEN_INT (GET_MODE_BITSIZE (mode)); ++ mask = GEN_INT (mode == QImode ? 0xff : 0xffff); ++ emit_insn (gen_extxl (dest, scratch, width, addr)); ++ emit_insn (gen_mskxl (cond, scratch, mask, addr)); ++ ++ rtx scratch2 = operands[10]; ++ if (newval != const0_rtx) ++ emit_insn (gen_iordi3 (scratch2, cond, newval)); ++ ++ if (oldval == const0_rtx) ++ { ++ emit_move_insn (cond, const0_rtx); ++ x = gen_rtx_NE (DImode, dest, const0_rtx); ++ } ++ else ++ { ++ emit_insn (gen_iordi3 (scratch, cond, oldval)); ++ emit_insn (gen_sw_64_atomic_casdi (scratch, mem, scratch2)); ++ ++ x = gen_rtx_EQ (DImode, scratch2, scratch); ++ emit_insn (gen_rtx_SET (cond, x)); ++ x = gen_rtx_EQ (DImode, cond, const0_rtx); ++ } ++} ++ ++void ++sw_64_expand_atomic_exchange_12 (rtx operands[]) ++{ ++ rtx dst, mem, val, model; ++ machine_mode mode; ++ rtx addr, align, wdst; ++ ++ dst = operands[0]; ++ mem = operands[1]; ++ val = operands[2]; ++ model = operands[3]; ++ mode = GET_MODE (mem); ++ ++ /* We forced the address into a register via mem_noofs_operand. */ ++ addr = XEXP (mem, 0); ++ gcc_assert (register_operand (addr, DImode)); ++ ++ align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8), NULL_RTX, 1, ++ OPTAB_DIRECT); ++ ++ /* Insert val into the correct byte location within the word. */ ++ if (val != const0_rtx) ++ val = emit_insxl (mode, val, addr); ++ ++ wdst = gen_reg_rtx (DImode); ++ emit_insn (gen_atomic_exchange_1 (mode, wdst, mem, val, align, model)); ++ emit_move_insn (dst, gen_lowpart (mode, wdst)); ++} ++ ++void ++sw_64_split_atomic_exchange_12 (rtx operands[]) ++{ ++ rtx dest, orig_mem, addr, val, align, scratch; ++ rtx label, mem, width, mask, x; ++ machine_mode mode; ++ enum memmodel model; ++ ++ dest = operands[0]; ++ orig_mem = operands[1]; ++ val = operands[2]; ++ align = operands[3]; ++ model = (enum memmodel) INTVAL (operands[4]); ++ scratch = operands[5]; ++ mode = GET_MODE (orig_mem); ++ addr = XEXP (orig_mem, 0); ++ ++ mem = gen_rtx_MEM (DImode, align); ++ MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); ++ if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER) ++ set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); ++ ++ if (flag_sw_delmemb == 0) ++ sw_64_pre_atomic_barrier (model); ++ label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ()); ++ emit_label (XEXP (label, 0)); ++ ++ emit_insn (gen_load_locked (DImode, scratch, mem)); ++ if (!TARGET_SW8A) ++ { ++ emit_insn (gen_rtx_SET (dest, const1_rtx)); ++ emit_insn (gen_builtin_wr_f (dest)); ++ } ++ ++ width = GEN_INT (GET_MODE_BITSIZE (mode)); ++ mask = GEN_INT (mode == QImode ? 0xff : 0xffff); ++ emit_insn (gen_extxl (dest, scratch, width, addr)); ++ emit_insn (gen_mskxl (scratch, scratch, mask, addr)); ++ if (val != const0_rtx) ++ emit_insn (gen_iordi3 (scratch, scratch, val)); ++ ++ emit_insn (gen_store_conditional (DImode, scratch, mem, scratch)); ++ if (!TARGET_SW8A) ++ emit_insn (gen_builtin_rd_f (scratch)); ++ ++ x = gen_rtx_EQ (DImode, scratch, const0_rtx); ++ emit_unlikely_jump (x, label); ++} ++ ++/* Adjust the cost of a scheduling dependency. Return the new cost of ++ a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ ++ ++static int ++sw_64_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, ++ unsigned int) ++{ ++ enum attr_type dep_insn_type; ++ ++ /* If the dependence is an anti-dependence, there is no cost. For an ++ output dependence, there is sometimes a cost, but it doesn't seem ++ worth handling those few cases. */ ++ if (dep_type != 0) ++ return cost; ++ ++ /* If we can't recognize the insns, we can't really do anything. */ ++ if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0) ++ return cost; ++ ++ dep_insn_type = get_attr_type (dep_insn); ++ ++ /* Bring in the user-defined memory latency. */ ++ if (dep_insn_type == TYPE_ILD || dep_insn_type == TYPE_FLD ++ || dep_insn_type == TYPE_LDSYM) ++ cost += sw_64_memory_latency - 1; ++ ++ /* Everything else handled in DFA bypasses now. */ ++ ++ return cost; ++} ++ ++/* The number of instructions that can be issued per cycle. */ ++ ++static int ++sw_64_issue_rate (void) ++{ ++ return ((sw_64_tune == PROCESSOR_SW6 || sw_64_tune == PROCESSOR_SW8) ? 4 : 2); ++} ++ ++/* How many alternative schedules to try. This should be as wide as the ++ scheduling freedom in the DFA, but no wider. Making this value too ++ large results extra work for the scheduler.*/ ++ ++static int ++sw_64_multipass_dfa_lookahead (void) ++{ ++ return ((sw_64_tune == PROCESSOR_SW6 || sw_64_tune == PROCESSOR_SW8) ? 4 : 2); ++} ++ ++/* Machine-specific function data. */ ++ ++struct GTY (()) sw_64_links; ++ ++/* Information about a function's frame layout. */ ++struct GTY (()) sw_64_frame_info ++{ ++ /* The size of the frame in bytes. */ ++ HOST_WIDE_INT frame_size; ++ ++ /* Bit X is set if the function saves or restores GPR X. */ ++ unsigned HOST_WIDE_INT sa_mask; ++ ++ /* The size of the saved callee-save int/FP registers. */ ++ HOST_WIDE_INT saved_regs_size; ++ ++ /* The number of extra stack bytes taken up by register varargs. */ ++ HOST_WIDE_INT saved_varargs_size; ++ ++ /* Offset of virtual frame pointer from stack pointer/frame bottom */ ++ HOST_WIDE_INT callee_offset; ++ ++ /* Offset of hard frame pointer from stack pointer/frame bottom */ ++ HOST_WIDE_INT hard_frame_pointer_offset; ++ ++ HOST_WIDE_INT local_offset; ++ ++ /* The offset of arg_pointer_rtx from the bottom of the frame. */ ++ HOST_WIDE_INT arg_pointer_offset; ++ ++ bool emit_frame_pointer; ++}; ++ ++struct GTY (()) machine_function ++{ ++ unsigned HOST_WIDE_INT sa_mask; ++ HOST_WIDE_INT sa_size; ++ HOST_WIDE_INT frame_size; ++ ++ /* For flag_reorder_blocks_and_partition. */ ++ rtx gp_save_rtx; ++ ++ bool uses_condition_handler; ++ ++ struct sw_64_frame_info frame; ++ ++ /* Linkage entries. */ ++ hash_map *links; ++}; ++ ++/* How to allocate a 'struct machine_function'. */ ++ ++static struct machine_function * ++sw_64_init_machine_status (void) ++{ ++ return ggc_cleared_alloc (); ++} ++ ++/* Start the ball rolling with RETURN_ADDR_RTX. */ ++ ++rtx ++sw_64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) ++{ ++ if (count != 0) ++ return const0_rtx; ++ ++ return get_hard_reg_initial_val (Pmode, REG_RA); ++} ++ ++/* Return or create a memory slot containing the gp value for the current ++ function. Needed only if TARGET_LD_BUGGY_LDGP. */ ++ ++rtx ++sw_64_gp_save_rtx (void) ++{ ++ rtx_insn *seq; ++ rtx m = cfun->machine->gp_save_rtx; ++ ++ if (m == NULL) ++ { ++ start_sequence (); ++ ++ m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD); ++ m = validize_mem (m); ++ emit_move_insn (m, pic_offset_table_rtx); ++ ++ seq = get_insns (); ++ end_sequence (); ++ ++ /* We used to simply emit the sequence after entry_of_function. ++ However this breaks the CFG if the first instruction in the ++ first block is not the NOTE_INSN_BASIC_BLOCK, for example a ++ label. Emit the sequence properly on the edge. We are only ++ invoked from dw2_build_landing_pads and finish_eh_generation ++ will call commit_edge_insertions thanks to a kludge. */ ++ insert_insn_on_edge (seq, ++ single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); ++ ++ cfun->machine->gp_save_rtx = m; ++ } ++ ++ return m; ++} ++ ++static void ++sw_64_instantiate_decls (void) ++{ ++ if (cfun->machine->gp_save_rtx != NULL_RTX) ++ instantiate_decl_rtl (cfun->machine->gp_save_rtx); ++} ++ ++static int ++sw_64_ra_ever_killed (void) ++{ ++ rtx_insn *top; ++ ++ if (!has_hard_reg_initial_val (Pmode, REG_RA)) ++ return (int) df_regs_ever_live_p (REG_RA); ++ ++ push_topmost_sequence (); ++ top = get_insns (); ++ pop_topmost_sequence (); ++ ++ return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL); ++} ++ ++/* Return the trap mode suffix applicable to the current ++ instruction, or NULL. */ ++ ++static const char * ++get_trap_mode_suffix (void) ++{ ++ enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn); ++ ++ switch (s) ++ { ++ case TRAP_SUFFIX_NONE: ++ return NULL; ++ ++ case TRAP_SUFFIX_SU: ++ if (sw_64_fptm >= SW_64_FPTM_SU) ++ return "su"; ++ return NULL; ++ ++ case TRAP_SUFFIX_SUI: ++ if (sw_64_fptm >= SW_64_FPTM_SUI) ++ return "sui"; ++ return NULL; ++ ++ case TRAP_SUFFIX_V_SV: ++ switch (sw_64_fptm) ++ { ++ case SW_64_FPTM_N: ++ return NULL; ++ case SW_64_FPTM_U: ++ return "v"; ++ case SW_64_FPTM_SU: ++ case SW_64_FPTM_SUI: ++ return "sv"; ++ default: ++ gcc_unreachable (); ++ } ++ ++ case TRAP_SUFFIX_V_SV_SVI: ++ switch (sw_64_fptm) ++ { ++ case SW_64_FPTM_N: ++ return NULL; ++ case SW_64_FPTM_U: ++ return "v"; ++ case SW_64_FPTM_SU: ++ return "sv"; ++ case SW_64_FPTM_SUI: ++ return "svi"; ++ default: ++ gcc_unreachable (); ++ } ++ break; ++ ++ case TRAP_SUFFIX_U_SU_SUI: ++ switch (sw_64_fptm) ++ { ++ case SW_64_FPTM_N: ++ return NULL; ++ case SW_64_FPTM_U: ++ return "u"; ++ case SW_64_FPTM_SU: ++ return "su"; ++ case SW_64_FPTM_SUI: ++ return "sui"; ++ default: ++ gcc_unreachable (); ++ } ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ gcc_unreachable (); ++} ++ ++/* Return the rounding mode suffix applicable to the current ++ instruction, or NULL. */ ++ ++static const char * ++get_round_mode_suffix (void) ++{ ++ enum attr_round_suffix s = get_attr_round_suffix (current_output_insn); ++ ++ switch (s) ++ { ++ case ROUND_SUFFIX_NONE: ++ return NULL; ++ case ROUND_SUFFIX_NORMAL: ++ switch (sw_64_fprm) ++ { ++ case SW_64_FPRM_NORM: ++ return NULL; ++ case SW_64_FPRM_MINF: ++ return "m"; ++ case SW_64_FPRM_CHOP: ++ return "c"; ++ case SW_64_FPRM_DYN: ++ return "d"; ++ default: ++ gcc_unreachable (); ++ } ++ break; ++ ++ case ROUND_SUFFIX_C: ++ return "c"; ++ ++ default: ++ gcc_unreachable (); ++ } ++ gcc_unreachable (); ++} ++ ++/* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */ ++ ++static bool ++sw_64_print_operand_punct_valid_p (unsigned char code) ++{ ++ return (code == '/' || code == ',' || code == '-' || code == '~' ++ || code == '#' || code == '*' || code == '&'); ++} ++ ++/* Implement TARGET_PRINT_OPERAND. The sw_64-specific ++ operand codes are documented below. */ ++ ++static const char * ++get_round_mode_suffix_sw (void) ++{ ++ enum attr_round_suffix s = get_attr_round_suffix (current_output_insn); ++ ++ switch (s) ++ { ++ case ROUND_SUFFIX_NONE: ++ return NULL; ++ case ROUND_SUFFIX_NORMAL: ++ switch (sw_64_fprm) ++ { ++ case SW_64_FPRM_NORM: ++ return "_g"; ++ case SW_64_FPRM_MINF: ++ return "_p"; ++ case SW_64_FPRM_CHOP: ++ return "_z"; ++ case SW_64_FPRM_DYN: ++ return "_n"; ++ default: ++ gcc_unreachable (); ++ } ++ break; ++ ++ case ROUND_SUFFIX_C: ++ return "_z"; ++ ++ default: ++ gcc_unreachable (); ++ } ++ gcc_unreachable (); ++} ++static void ++sw_64_print_operand (FILE *file, rtx x, int code) ++{ ++ int i; ++ ++ switch (code) ++ { ++ case '~': ++ /* Print the assembler name of the current function. */ ++ assemble_name (file, sw_64_fnname); ++ break; ++ ++ case '&': ++ if (const char *name = get_some_local_dynamic_name ()) ++ assemble_name (file, name); ++ else ++ output_operand_lossage ("'%%&' used without any " ++ "local dynamic TLS references"); ++ break; ++ ++ case '/': ++ /* Generates the instruction suffix. The TRAP_SUFFIX and ROUND_SUFFIX ++ attributes are examined to determine what is appropriate. */ ++ { ++ const char *trap = get_trap_mode_suffix (); ++ const char *round = get_round_mode_suffix (); ++ ++ break; ++ } ++ ++ case 'T': { ++ const char *round_sw = get_round_mode_suffix_sw (); ++ ++ if (round_sw) ++ fprintf (file, "%s", (round_sw ? round_sw : "")); ++ break; ++ } ++ case ',': ++ /* Generates single precision suffix for floating point ++ instructions (s for IEEE, f for VAX). */ ++ fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file); ++ break; ++ ++ case '-': ++ /* Generates double precision suffix for floating point ++ instructions (t for IEEE, g for VAX). */ ++ fputc ((TARGET_FLOAT_VAX ? 'g' : 'd'), file); ++ break; ++ ++ case '#': ++ if (sw_64_this_literal_sequence_number == 0) ++ sw_64_this_literal_sequence_number = sw_64_next_sequence_number++; ++ fprintf (file, "%d", sw_64_this_literal_sequence_number); ++ break; ++ ++ case '*': ++ if (sw_64_this_gpdisp_sequence_number == 0) ++ sw_64_this_gpdisp_sequence_number = sw_64_next_sequence_number++; ++ fprintf (file, "%d", sw_64_this_gpdisp_sequence_number); ++ break; ++ ++ case 'J': { ++ const char *lituse; ++ ++ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL) ++ { ++ x = XVECEXP (x, 0, 0); ++ lituse = "lituse_tlsgd"; ++ } ++ else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL) ++ { ++ x = XVECEXP (x, 0, 0); ++ lituse = "lituse_tlsldm"; ++ } ++ else if (CONST_INT_P (x)) ++ lituse = "lituse_jsr"; ++ else ++ { ++ output_operand_lossage ("invalid %%J value"); ++ break; ++ } ++ ++ if (x != const0_rtx) ++ fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x)); ++ } ++ break; ++ ++ case 'j': { ++ const char *lituse; ++ ++#ifdef HAVE_AS_JSRDIRECT_RELOCS ++ lituse = "lituse_jsrdirect"; ++#else ++ lituse = "lituse_jsr"; ++#endif ++ ++ gcc_assert (INTVAL (x) != 0); ++ fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x)); ++ } ++ break; ++ case 'r': ++ /* If this operand is the constant zero, write it as "$31". */ ++ if (REG_P (x)) ++ fprintf (file, "%s", reg_names[REGNO (x)]); ++ else if (x == CONST0_RTX (GET_MODE (x))) ++ fprintf (file, "$31"); ++ else ++ output_operand_lossage ("invalid %%r value"); ++ break; ++ ++ case 'R': ++ /* Similar, but for floating-point. */ ++ if (REG_P (x)) ++ fprintf (file, "%s", reg_names[REGNO (x)]); ++ else if (x == CONST0_RTX (GET_MODE (x))) ++ fprintf (file, "$f31"); ++ else ++ output_operand_lossage ("invalid %%R value"); ++ break; ++ ++ case 'N': ++ /* Write the 1's complement of a constant. */ ++ if (!CONST_INT_P (x)) ++ output_operand_lossage ("invalid %%N value"); ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~INTVAL (x)); ++ break; ++ ++ case 'P': ++ /* Write 1 << C, for a constant C. */ ++ if (!CONST_INT_P (x)) ++ output_operand_lossage ("invalid %%P value"); ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, HOST_WIDE_INT_1 << INTVAL (x)); ++ break; ++ ++ case 'h': ++ /* Write the high-order 16 bits of a constant, sign-extended. */ ++ if (!CONST_INT_P (x)) ++ output_operand_lossage ("invalid %%h value"); ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16); ++ break; ++ ++ case 'L': ++ /* Write the low-order 16 bits of a constant, sign-extended. */ ++ if (!CONST_INT_P (x)) ++ output_operand_lossage ("invalid %%L value"); ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, ++ (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000)); ++ break; ++ ++ case 'm': ++ /* Write mask for ZAP insn. */ ++ if (CONST_INT_P (x)) ++ { ++ HOST_WIDE_INT mask = 0, value = INTVAL (x); ++ ++ for (i = 0; i < 8; i++, value >>= 8) ++ if (value & 0xff) ++ mask |= (1 << i); ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask); ++ } ++ else ++ output_operand_lossage ("invalid %%m value"); ++ break; ++ ++ case 'M': ++ /* 'b', 'w', 'l', or 'q' as the value of the constant. */ ++ if (!mode_width_operand (x, VOIDmode)) ++ output_operand_lossage ("invalid %%M value"); ++ ++ fprintf (file, "%s", ++ (INTVAL (x) == 8 ? "b" ++ : INTVAL (x) == 16 ? "w" ++ : INTVAL (x) == 32 ? "l" ++ : "q")); ++ break; ++ ++ case 'U': ++ /* Similar, except do it from the mask. */ ++ if (CONST_INT_P (x)) ++ { ++ HOST_WIDE_INT value = INTVAL (x); ++ ++ if (value == 0xff) ++ { ++ fputc ('b', file); ++ break; ++ } ++ if (value == 0xffff) ++ { ++ fputc ('w', file); ++ break; ++ } ++ if (value == 0xffffffff) ++ { ++ fputc ('l', file); ++ break; ++ } ++ if (value == -1) ++ { ++ fputc ('q', file); ++ break; ++ } ++ } ++ /* Write "_a" for AUTO_INC_DEC access. */ ++ if (MEM_P (x) ++ && (GET_CODE (XEXP (x, 0)) == POST_INC ++ || GET_CODE (XEXP (x, 0)) == POST_DEC ++ || GET_CODE (XEXP (x, 0)) == POST_MODIFY)) ++ { ++ fprintf (file, "_a"); ++ break; ++ } ++ break; ++ ++ case 's': ++ /* Write the constant value divided by 8. */ ++ if (!CONST_INT_P (x) || (unsigned HOST_WIDE_INT) INTVAL (x) >= 64 ++ || (INTVAL (x) & 7) != 0) ++ output_operand_lossage ("invalid %%s value"); ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8); ++ break; ++ ++ case 'C': ++ case 'D': ++ case 'c': ++ case 'd': ++ /* Write out comparison name. */ ++ { ++ enum rtx_code c = GET_CODE (x); ++ ++ if (!COMPARISON_P (x)) ++ output_operand_lossage ("invalid %%C value"); ++ ++ else if (code == 'D') ++ c = reverse_condition (c); ++ else if (code == 'c') ++ c = swap_condition (c); ++ else if (code == 'd') ++ c = swap_condition (reverse_condition (c)); ++ ++ if (c == LEU) ++ fprintf (file, "ule"); ++ else if (c == LTU) ++ fprintf (file, "ult"); ++ else if (c == UNORDERED) ++ fprintf (file, "un"); ++ else ++ fprintf (file, "%s", GET_RTX_NAME (c)); ++ } ++ break; ++ ++ case 'E': ++ /* Write the divide or modulus operator. */ ++ switch (GET_CODE (x)) ++ { ++ case DIV: ++ fprintf (file, "div%s", GET_MODE (x) == SImode ? "w" : "l"); ++ break; ++ case UDIV: ++ fprintf (file, "div%su", GET_MODE (x) == SImode ? "w" : "l"); ++ break; ++ case MOD: ++ fprintf (file, "rem%s", GET_MODE (x) == SImode ? "w" : "l"); ++ break; ++ case UMOD: ++ fprintf (file, "rem%su", GET_MODE (x) == SImode ? "w" : "l"); ++ break; ++ default: ++ output_operand_lossage ("invalid %%E value"); ++ break; ++ } ++ break; ++ ++ case 'A': ++ /* Write "_u" for unaligned access. */ ++ if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND) ++ fprintf (file, "_u"); ++ break; ++ ++ case 0: ++ if (REG_P (x)) ++ fprintf (file, "%s", reg_names[REGNO (x)]); ++ else if (MEM_P (x)) ++ { ++ if (GET_CODE (XEXP (x, 0)) == POST_INC) ++ fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)), ++ reg_names[REGNO (XEXP (XEXP (x, 0), 0))]); ++ else if (GET_CODE (XEXP (x, 0)) == POST_DEC) ++ fprintf (file, "%d(%s)", -GET_MODE_SIZE (GET_MODE (x)), ++ reg_names[REGNO (XEXP (XEXP (x, 0), 0))]); ++ else if (GET_CODE (XEXP (x, 0)) == POST_MODIFY) ++ output_address (GET_MODE (x), XEXP (XEXP (x, 0), 1)); ++ else ++ output_address (GET_MODE (x), XEXP (x, 0)); ++ } ++ else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC) ++ { ++ switch (XINT (XEXP (x, 0), 1)) ++ { ++ case UNSPEC_DTPREL: ++ case UNSPEC_TPREL: ++ output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0)); ++ break; ++ default: ++ output_operand_lossage ("unknown relocation unspec"); ++ break; ++ } ++ } ++ else ++ output_addr_const (file, x); ++ break; ++ ++ default: ++ output_operand_lossage ("invalid %%xn code"); ++ } ++} ++ ++/* Implement TARGET_PRINT_OPERAND_ADDRESS. */ ++ ++static void ++sw_64_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr) ++{ ++ int basereg = 31; ++ HOST_WIDE_INT offset = 0; ++ ++ if (GET_CODE (addr) == AND) ++ addr = XEXP (addr, 0); ++ ++ if (GET_CODE (addr) == PLUS && CONST_INT_P (XEXP (addr, 1))) ++ { ++ offset = INTVAL (XEXP (addr, 1)); ++ addr = XEXP (addr, 0); ++ } ++ ++ if (GET_CODE (addr) == LO_SUM) ++ { ++ const char *reloc16, *reloclo; ++ rtx op1 = XEXP (addr, 1); ++ ++ if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC) ++ { ++ op1 = XEXP (op1, 0); ++ switch (XINT (op1, 1)) ++ { ++ case UNSPEC_DTPREL: ++ reloc16 = NULL; ++ reloclo = (sw_64_tls_size == 16 ? "dtprel" : "dtprello"); ++ break; ++ case UNSPEC_TPREL: ++ reloc16 = NULL; ++ reloclo = (sw_64_tls_size == 16 ? "tprel" : "tprello"); ++ break; ++ default: ++ output_operand_lossage ("unknown relocation unspec"); ++ return; ++ } ++ ++ output_addr_const (file, XVECEXP (op1, 0, 0)); ++ } ++ else ++ { ++ reloc16 = "gprel"; ++ reloclo = "gprellow"; ++ output_addr_const (file, op1); ++ } ++ ++ if (offset) ++ fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset); ++ ++ addr = XEXP (addr, 0); ++ switch (GET_CODE (addr)) ++ { ++ case REG: ++ basereg = REGNO (addr); ++ break; ++ ++ case SUBREG: ++ basereg = subreg_regno (addr); ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ fprintf (file, "($%d)\t\t!%s", basereg, ++ (basereg == 29 ? reloc16 : reloclo)); ++ return; ++ } ++ ++ switch (GET_CODE (addr)) ++ { ++ case REG: ++ basereg = REGNO (addr); ++ break; ++ ++ case SUBREG: ++ basereg = subreg_regno (addr); ++ break; ++ ++ case CONST_INT: ++ offset = INTVAL (addr); ++ break; ++ ++ case SYMBOL_REF: ++ gcc_assert (this_is_asm_operands); ++ fprintf (file, "%s", XSTR (addr, 0)); ++ return; ++ ++ case CONST: ++ gcc_assert (this_is_asm_operands); ++ gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS ++ && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF); ++ fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC, ++ XSTR (XEXP (XEXP (addr, 0), 0), 0), ++ INTVAL (XEXP (XEXP (addr, 0), 1))); ++ return; ++ ++ default: ++ output_operand_lossage ("invalid operand address"); ++ return; ++ } ++ ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg); ++} ++ ++/* Emit RTL insns to initialize the variable parts of a trampoline at ++ M_TRAMP. FNDECL is target function's decl. CHAIN_VALUE is an rtx ++ for the static chain value for the function. */ ++ ++static void ++sw_64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) ++{ ++ rtx fnaddr, mem, word1, word2; ++ ++ fnaddr = XEXP (DECL_RTL (fndecl), 0); ++ ++#ifdef POINTERS_EXTEND_UNSIGNED ++ fnaddr = convert_memory_address (Pmode, fnaddr); ++ chain_value = convert_memory_address (Pmode, chain_value); ++#endif ++ ++ /* These 4 instructions are: ++ ldq $1,24($27) ++ ldq $27,16($27) ++ jmp $31,($27),0 ++ nop ++ We don't bother setting the HINT field of the jump; the nop ++ is merely there for padding. */ ++ word1 = GEN_INT (HOST_WIDE_INT_C (0x8f7b00108c3b0018)); ++ word2 = GEN_INT (HOST_WIDE_INT_C (0x43ff075f0ffb0000)); ++ ++ /* Store the first two words, as computed above. */ ++ mem = adjust_address (m_tramp, DImode, 0); ++ emit_move_insn (mem, word1); ++ mem = adjust_address (m_tramp, DImode, 8); ++ emit_move_insn (mem, word2); ++ ++ /* Store function address and static chain value. */ ++ mem = adjust_address (m_tramp, Pmode, 16); ++ emit_move_insn (mem, fnaddr); ++ mem = adjust_address (m_tramp, Pmode, 24); ++ emit_move_insn (mem, chain_value); ++ ++ emit_insn (gen_imb ()); ++#ifdef HAVE_ENABLE_EXECUTE_STACK ++ emit_library_call (init_one_libfunc ("__enable_execute_stack"), ++ LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode); ++#endif ++} ++ ++/* Determine where to put an argument to a function. ++ Value is zero to push the argument on the stack, ++ or a hard register in which to store the argument. ++ ++ CUM is a variable of type CUMULATIVE_ARGS which gives info about ++ the preceding args and about the function being called. ++ ++ ARG is a description of the argument. ++ On Sw_64 the first 6 words of args are normally in registers ++ and the rest are pushed. */ ++ ++static rtx ++sw_64_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) ++{ ++ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); ++ int basereg; ++ int num_args; ++ ++ /* Don't get confused and pass small structures in FP registers. */ ++ if (arg.aggregate_type_p ()) ++ basereg = 16; ++ else ++ { ++ /* With sw_64_split_complex_arg, we shouldn't see any raw complex ++ values here. */ ++ gcc_checking_assert (!COMPLEX_MODE_P (arg.mode)); ++ ++ /* Set up defaults for FP operands passed in FP registers, and ++ integral operands passed in integer registers. */ ++ if (TARGET_FPREGS && GET_MODE_CLASS (arg.mode) == MODE_FLOAT) ++ basereg = 32 + 16; ++ else ++ basereg = 16; ++ } ++ ++ /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for ++ the two platforms, so we can't avoid conditional compilation. */ ++ { ++ if (*cum >= 6) ++ return NULL_RTX; ++ num_args = *cum; ++ ++ if (arg.end_marker_p ()) ++ basereg = 16; ++ else if (targetm.calls.must_pass_in_stack (arg)) ++ return NULL_RTX; ++ } ++ ++ return gen_rtx_REG (arg.mode, num_args + basereg); ++} ++ ++/* Update the data in CUM to advance over an argument ARG. */ ++ ++static void ++sw_64_function_arg_advance (cumulative_args_t cum_v, ++ const function_arg_info &arg) ++{ ++ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); ++ bool onstack = targetm.calls.must_pass_in_stack (arg); ++ int increment = onstack ? 6 : SW_64_ARG_SIZE (arg.mode, arg.type); ++ ++ *cum += increment; ++} ++ ++static int ++sw_64_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg) ++{ ++ int words = 0; ++ CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED = get_cumulative_args (cum_v); ++ ++ if (*cum < 6 && 6 < *cum + SW_64_ARG_SIZE (arg.mode, arg.type)) ++ words = 6 - *cum; ++ ++ return words * UNITS_PER_WORD; ++} ++ ++/* Return true if ARG must be returned in memory, instead of in registers. */ ++ ++static bool ++sw_64_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) ++{ ++ machine_mode mode = VOIDmode; ++ int size; ++ ++ if (type) ++ { ++ mode = TYPE_MODE (type); ++ ++ if (AGGREGATE_TYPE_P (type)) ++ return true; ++ } ++ ++ size = GET_MODE_SIZE (mode); ++ switch (GET_MODE_CLASS (mode)) ++ { ++ case MODE_VECTOR_FLOAT: ++ /* Pass all float vectors in memory, like an aggregate. */ ++ return true; ++ ++ case MODE_COMPLEX_FLOAT: ++ /* We judge complex floats on the size of their element, ++ not the size of the whole type. */ ++ size = GET_MODE_UNIT_SIZE (mode); ++ break; ++ ++ case MODE_INT: ++ case MODE_FLOAT: ++ case MODE_COMPLEX_INT: ++ case MODE_VECTOR_INT: ++ break; ++ ++ default: ++ /* ??? We get called on all sorts of random stuff from ++ aggregate_value_p. We must return something, but it's not ++ clear what's safe to return. Pretend it's a struct I ++ guess. */ ++ return true; ++ } ++ ++ /* Otherwise types must fit in one register. */ ++ return size > UNITS_PER_WORD; ++} ++ ++/* Return true if TYPE should be passed by invisible reference. */ ++ ++static bool ++sw_64_pass_by_reference (cumulative_args_t, const function_arg_info &arg) ++{ ++ /* Pass float and _Complex float variable arguments by reference. ++ This avoids 64-bit store from a FP register to a pretend args save area ++ and subsequent 32-bit load from the saved location to a FP register. ++ ++ Note that 32-bit loads and stores to/from a FP register on sw_64 reorder ++ bits to form a canonical 64-bit value in the FP register. This fact ++ invalidates compiler assumption that 32-bit FP value lives in the lower ++ 32-bits of the passed 64-bit FP value, so loading the 32-bit value from ++ the stored 64-bit location using 32-bit FP load is invalid on sw_64. ++ ++ This introduces sort of ABI incompatibility, but until _Float32 was ++ introduced, C-family languages promoted 32-bit float variable arg to ++ a 64-bit double, and it was not allowed to pass float as a varible ++ argument. Passing _Complex float as a variable argument never ++ worked on sw_64. Thus, we have no backward compatibility issues ++ to worry about, and passing unpromoted _Float32 and _Complex float ++ as a variable argument will actually work in the future. */ ++ ++ if (arg.mode == SFmode || arg.mode == SCmode) ++ return !arg.named; ++ ++ return arg.mode == TFmode || arg.mode == TCmode; ++} ++ ++/* Define how to find the value returned by a function. VALTYPE is the ++ data type of the value (as a tree). If the precise function being ++ called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. ++ MODE is set instead of VALTYPE for libcalls. ++ ++ On Sw_64 the value is found in $0 for integer functions and ++ $f0 for floating-point functions. */ ++ ++static rtx ++sw_64_function_value_1 (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, ++ machine_mode mode) ++{ ++ unsigned int regnum, dummy ATTRIBUTE_UNUSED; ++ enum mode_class mclass; ++ ++ gcc_assert (!valtype || !sw_64_return_in_memory (valtype, func)); ++ ++ if (valtype) ++ mode = TYPE_MODE (valtype); ++ ++ mclass = GET_MODE_CLASS (mode); ++ switch (mclass) ++ { ++ case MODE_INT: ++ /* Do the same thing as PROMOTE_MODE except for libcalls, ++ where we have them returning both SImode and DImode. */ ++ PROMOTE_MODE (mode, dummy, valtype); ++ /* FALLTHRU */ ++ ++ case MODE_COMPLEX_INT: ++ case MODE_VECTOR_INT: ++ regnum = 0; ++ break; ++ ++ case MODE_FLOAT: ++ regnum = 32; ++ break; ++ ++ case MODE_COMPLEX_FLOAT: { ++ machine_mode cmode = GET_MODE_INNER (mode); ++ ++ return gen_rtx_PARALLEL ( ++ VOIDmode, ++ gen_rtvec (2, ++ gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32), ++ const0_rtx), ++ gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33), ++ GEN_INT (GET_MODE_SIZE (cmode))))); ++ } ++ ++ case MODE_RANDOM: ++ default: ++ gcc_unreachable (); ++ } ++ ++ return gen_rtx_REG (mode, regnum); ++} ++ ++/* Implement TARGET_FUNCTION_VALUE. */ ++ ++static rtx ++sw_64_function_value (const_tree valtype, const_tree fn_decl_or_type, ++ bool /*outgoing*/) ++{ ++ return sw_64_function_value_1 (valtype, fn_decl_or_type, VOIDmode); ++} ++ ++/* Implement TARGET_LIBCALL_VALUE. */ ++ ++static rtx ++sw_64_libcall_value (machine_mode mode, const_rtx /*fun*/) ++{ ++ return sw_64_function_value_1 (NULL_TREE, NULL_TREE, mode); ++} ++ ++/* Implement TARGET_FUNCTION_VALUE_REGNO_P. ++ ++ On the Sw_64, $0 $1 and $f0 $f1 are the only register thus used. */ ++ ++static bool ++sw_64_function_value_regno_p (const unsigned int regno) ++{ ++ return (regno == 0 || regno == 1 || regno == 32 || regno == 33); ++} ++ ++/* TCmode complex values are passed by invisible reference. We ++ should not split these values. */ ++ ++static bool ++sw_64_split_complex_arg (const_tree type) ++{ ++ return TYPE_MODE (type) != TCmode; ++} ++ ++static tree ++sw_64_build_builtin_va_list (void) ++{ ++ tree base, ofs, space, record, type_decl; ++ ++ record = (*lang_hooks.types.make_type) (RECORD_TYPE); ++ type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, ++ get_identifier ("__va_list_tag"), record); ++ TYPE_STUB_DECL (record) = type_decl; ++ TYPE_NAME (record) = type_decl; ++ ++ /* C++? SET_IS_AGGR_TYPE (record, 1); */ ++ ++ /* Dummy field to prevent alignment warnings. */ ++ space ++ = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, integer_type_node); ++ DECL_FIELD_CONTEXT (space) = record; ++ DECL_ARTIFICIAL (space) = 1; ++ DECL_IGNORED_P (space) = 1; ++ ++ ofs = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("__offset"), ++ integer_type_node); ++ DECL_FIELD_CONTEXT (ofs) = record; ++ DECL_CHAIN (ofs) = space; ++ ++ base = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("__base"), ++ ptr_type_node); ++ DECL_FIELD_CONTEXT (base) = record; ++ DECL_CHAIN (base) = ofs; ++ ++ TYPE_FIELDS (record) = base; ++ layout_type (record); ++ ++ va_list_gpr_counter_field = ofs; ++ return record; ++} ++ ++/* Helper function for sw_64_stdarg_optimize_hook. Skip over casts ++ and constant additions. */ ++ ++static gimple * ++va_list_skip_additions (tree lhs) ++{ ++ gimple *stmt; ++ ++ for (;;) ++ { ++ enum tree_code code; ++ ++ stmt = SSA_NAME_DEF_STMT (lhs); ++ ++ if (gimple_code (stmt) == GIMPLE_PHI) ++ return stmt; ++ ++ if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs) ++ return NULL; ++ ++ if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME) ++ return stmt; ++ code = gimple_assign_rhs_code (stmt); ++ if (!CONVERT_EXPR_CODE_P (code) ++ && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR) ++ || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST ++ || !tree_fits_uhwi_p (gimple_assign_rhs2 (stmt)))) ++ return stmt; ++ ++ lhs = gimple_assign_rhs1 (stmt); ++ } ++} ++ ++/* Check if LHS = RHS statement is ++ LHS = *(ap.__base + ap.__offset + cst) ++ or ++ LHS = *(ap.__base ++ + ((ap.__offset + cst <= 47) ++ ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2). ++ If the former, indicate that GPR registers are needed, ++ if the latter, indicate that FPR registers are needed. ++ ++ Also look for LHS = (*ptr).field, where ptr is one of the forms ++ listed above. ++ ++ On sw_64, cfun->va_list_gpr_size is used as size of the needed ++ regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR ++ registers are needed and bit 1 set if FPR registers are needed. ++ Return true if va_list references should not be scanned for the ++ current statement. */ ++ ++static bool ++sw_64_stdarg_optimize_hook (struct stdarg_info *si, const gimple *stmt) ++{ ++ tree base, offset, rhs; ++ int offset_arg = 1; ++ gimple *base_stmt; ++ ++ if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) != GIMPLE_SINGLE_RHS) ++ return false; ++ ++ rhs = gimple_assign_rhs1 (stmt); ++ while (handled_component_p (rhs)) ++ rhs = TREE_OPERAND (rhs, 0); ++ if (TREE_CODE (rhs) != MEM_REF ++ || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME) ++ return false; ++ ++ stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0)); ++ if (stmt == NULL || !is_gimple_assign (stmt) ++ || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR) ++ return false; ++ ++ base = gimple_assign_rhs1 (stmt); ++ if (TREE_CODE (base) == SSA_NAME) ++ { ++ base_stmt = va_list_skip_additions (base); ++ if (base_stmt && is_gimple_assign (base_stmt) ++ && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF) ++ base = gimple_assign_rhs1 (base_stmt); ++ } ++ ++ if (TREE_CODE (base) != COMPONENT_REF ++ || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node)) ++ { ++ base = gimple_assign_rhs2 (stmt); ++ if (TREE_CODE (base) == SSA_NAME) ++ { ++ base_stmt = va_list_skip_additions (base); ++ if (base_stmt && is_gimple_assign (base_stmt) ++ && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF) ++ base = gimple_assign_rhs1 (base_stmt); ++ } ++ ++ if (TREE_CODE (base) != COMPONENT_REF ++ || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node)) ++ return false; ++ ++ offset_arg = 0; ++ } ++ ++ base = get_base_address (base); ++ if (TREE_CODE (base) != VAR_DECL ++ || !bitmap_bit_p (si->va_list_vars, DECL_UID (base) + num_ssa_names)) ++ return false; ++ ++ offset = gimple_op (stmt, 1 + offset_arg); ++ if (TREE_CODE (offset) == SSA_NAME) ++ { ++ gimple *offset_stmt = va_list_skip_additions (offset); ++ ++ if (offset_stmt && gimple_code (offset_stmt) == GIMPLE_PHI) ++ { ++ HOST_WIDE_INT sub; ++ gimple *arg1_stmt, *arg2_stmt; ++ tree arg1, arg2; ++ enum tree_code code1, code2; ++ ++ if (gimple_phi_num_args (offset_stmt) != 2) ++ goto escapes; ++ ++ arg1_stmt ++ = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0)); ++ arg2_stmt ++ = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1)); ++ if (arg1_stmt == NULL || !is_gimple_assign (arg1_stmt) ++ || arg2_stmt == NULL || !is_gimple_assign (arg2_stmt)) ++ goto escapes; ++ ++ code1 = gimple_assign_rhs_code (arg1_stmt); ++ code2 = gimple_assign_rhs_code (arg2_stmt); ++ if (code1 == COMPONENT_REF ++ && (code2 == MINUS_EXPR || code2 == PLUS_EXPR)) ++ /* Do nothing. */; ++ else if (code2 == COMPONENT_REF ++ && (code1 == MINUS_EXPR || code1 == PLUS_EXPR)) ++ { ++ std::swap (arg1_stmt, arg2_stmt); ++ code2 = code1; ++ } ++ else ++ goto escapes; ++ ++ if (!tree_fits_shwi_p (gimple_assign_rhs2 (arg2_stmt))) ++ goto escapes; ++ ++ sub = tree_to_shwi (gimple_assign_rhs2 (arg2_stmt)); ++ if (code2 == MINUS_EXPR) ++ sub = -sub; ++ if (sub < -48 || sub > -32) ++ goto escapes; ++ ++ arg1 = gimple_assign_rhs1 (arg1_stmt); ++ arg2 = gimple_assign_rhs1 (arg2_stmt); ++ if (TREE_CODE (arg2) == SSA_NAME) ++ { ++ arg2_stmt = va_list_skip_additions (arg2); ++ if (arg2_stmt == NULL || !is_gimple_assign (arg2_stmt) ++ || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF) ++ goto escapes; ++ arg2 = gimple_assign_rhs1 (arg2_stmt); ++ } ++ if (arg1 != arg2) ++ goto escapes; ++ ++ if (TREE_CODE (arg1) != COMPONENT_REF ++ || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field ++ || get_base_address (arg1) != base) ++ goto escapes; ++ ++ /* Need floating point regs. */ ++ cfun->va_list_fpr_size |= 2; ++ return false; ++ } ++ if (offset_stmt && is_gimple_assign (offset_stmt) ++ && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF) ++ offset = gimple_assign_rhs1 (offset_stmt); ++ } ++ if (TREE_CODE (offset) != COMPONENT_REF ++ || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field ++ || get_base_address (offset) != base) ++ goto escapes; ++ else ++ /* Need general regs. */ ++ cfun->va_list_fpr_size |= 1; ++ return false; ++ ++escapes: ++ si->va_list_escapes = true; ++ return false; ++} ++ ++/* Perform any needed actions needed for a function that is receiving a ++ variable number of arguments. */ ++ ++static void ++sw_64_setup_incoming_varargs (cumulative_args_t pcum, ++ const function_arg_info &arg, int *pretend_size, ++ int no_rtl) ++{ ++ CUMULATIVE_ARGS cum = *get_cumulative_args (pcum); ++ ++ /* Skip the current argument. */ ++ targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg); ++ ++ /* On SYSV and friends, we allocate space for all 12 arg registers, but ++ only push those that are remaining. However, if NO registers need to ++ be saved, don't allocate any space. This is not only because we won't ++ need the space, but because AP includes the current_pretend_args_size ++ and we don't want to mess up any ap-relative addresses already made. ++ ++ If we are not to use the floating-point registers, save the integer ++ registers where we would put the floating-point registers. This is ++ not the most efficient way to implement varargs with just one register ++ class, but it isn't worth doing anything more efficient in this rare ++ case. */ ++ if (cum >= 6) ++ return; ++ ++ if (!no_rtl) ++ { ++ int count; ++ alias_set_type set = get_varargs_alias_set (); ++ rtx tmp; ++ ++ count = cfun->va_list_gpr_size / UNITS_PER_WORD; ++ if (count > 6 - cum) ++ count = 6 - cum; ++ ++ /* Detect whether integer registers or floating-point registers ++ are needed by the detected va_arg statements. See above for ++ how these values are computed. Note that the "escape" value ++ is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of ++ these bits set. */ ++ gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3); ++ ++ if (cfun->va_list_fpr_size & 1) ++ { ++ tmp = gen_rtx_MEM (BLKmode, ++ plus_constant (Pmode, virtual_incoming_args_rtx, ++ (cum + 6) * UNITS_PER_WORD)); ++ MEM_NOTRAP_P (tmp) = 1; ++ set_mem_alias_set (tmp, set); ++ move_block_from_reg (16 + cum, tmp, count); ++ } ++ ++ if (cfun->va_list_fpr_size & 2) ++ { ++ tmp = gen_rtx_MEM (BLKmode, ++ plus_constant (Pmode, virtual_incoming_args_rtx, ++ cum * UNITS_PER_WORD)); ++ MEM_NOTRAP_P (tmp) = 1; ++ set_mem_alias_set (tmp, set); ++ move_block_from_reg (16 + cum + TARGET_FPREGS * 32, tmp, count); ++ } ++ } ++#ifdef SW_64_ENABLE_FULL_ASAN ++ cfun->machine->frame.saved_varargs_size = 12 * UNITS_PER_WORD; ++#else ++ *pretend_size = 12 * UNITS_PER_WORD; ++#endif ++} ++ ++static void ++sw_64_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) ++{ ++ HOST_WIDE_INT offset; ++ tree t, offset_field, base_field; ++ ++ if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK) ++ return; ++ ++ /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base ++ up by 48, storing fp arg registers in the first 48 bytes, and the ++ integer arg registers in the next 48 bytes. This is only done, ++ however, if any integer registers need to be stored. ++ ++ If no integer registers need be stored, then we must subtract 48 ++ in order to account for the integer arg registers which are counted ++ in argsize above, but which are not actually stored on the stack. ++ Must further be careful here about structures straddling the last ++ integer argument register; that futzes with pretend_args_size, ++ which changes the meaning of AP. */ ++ ++ if (NUM_ARGS < 6) ++ offset = 6 * UNITS_PER_WORD; ++ else ++#ifdef SW_64_ENABLE_FULL_ASAN ++ offset = -6 * UNITS_PER_WORD + cfun->machine->frame.saved_varargs_size ++ + crtl->args.pretend_args_size; ++#else ++ offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size; ++#endif ++ ++ base_field = TYPE_FIELDS (TREE_TYPE (valist)); ++ offset_field = DECL_CHAIN (base_field); ++ ++ base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field), valist, ++ base_field, NULL_TREE); ++ offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field), valist, ++ offset_field, NULL_TREE); ++ ++ t = make_tree (ptr_type_node, virtual_incoming_args_rtx); ++ t = fold_build_pointer_plus_hwi (t, offset); ++ t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t); ++ TREE_SIDE_EFFECTS (t) = 1; ++ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); ++ ++ t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD); ++ t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t); ++ TREE_SIDE_EFFECTS (t) = 1; ++ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); ++} ++ ++static tree ++sw_64_gimplify_va_arg_1 (tree type, tree base, tree offset, gimple_seq *pre_p) ++{ ++ tree type_size, ptr_type, addend, t, addr; ++ gimple_seq internal_post; ++ ++ /* If the type could not be passed in registers, skip the block ++ reserved for the registers. */ ++ if (must_pass_va_arg_in_stack (type)) ++ { ++ t = build_int_cst (TREE_TYPE (offset), 6 * 8); ++ gimplify_assign (offset, build2 (MAX_EXPR, TREE_TYPE (offset), offset, t), ++ pre_p); ++ } ++ ++ addend = offset; ++ ptr_type = build_pointer_type_for_mode (type, ptr_mode, true); ++ ++ if (TREE_CODE (type) == COMPLEX_TYPE) ++ { ++ tree real_part, imag_part, real_temp; ++ ++ real_part ++ = sw_64_gimplify_va_arg_1 (TREE_TYPE (type), base, offset, pre_p); ++ ++ /* Copy the value into a new temporary, lest the formal temporary ++ be reused out from under us. */ ++ real_temp = get_initialized_tmp_var (real_part, pre_p, NULL); ++ ++ imag_part ++ = sw_64_gimplify_va_arg_1 (TREE_TYPE (type), base, offset, pre_p); ++ ++ return build2 (COMPLEX_EXPR, type, real_temp, imag_part); ++ } ++ else if (TREE_CODE (type) == REAL_TYPE) ++ { ++ tree fpaddend, cond, fourtyeight; ++ ++ fourtyeight = build_int_cst (TREE_TYPE (addend), 6 * 8); ++ fpaddend ++ = fold_build2 (MINUS_EXPR, TREE_TYPE (addend), addend, fourtyeight); ++ cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight); ++ addend ++ = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond, fpaddend, addend); ++ } ++ ++ /* Build the final address and force that value into a temporary. */ ++ addr = fold_build_pointer_plus (fold_convert (ptr_type, base), addend); ++ internal_post = NULL; ++ gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue); ++ gimple_seq_add_seq (pre_p, internal_post); ++ ++ /* Update the offset field. */ ++ type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type)); ++ if (type_size == NULL || TREE_OVERFLOW (type_size)) ++ t = size_zero_node; ++ else ++ { ++ t = size_binop (PLUS_EXPR, type_size, size_int (7)); ++ t = size_binop (TRUNC_DIV_EXPR, t, size_int (8)); ++ t = size_binop (MULT_EXPR, t, size_int (8)); ++ } ++ t = fold_convert (TREE_TYPE (offset), t); ++ gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t), ++ pre_p); ++ ++ return build_va_arg_indirect_ref (addr); ++} ++ ++static tree ++sw_64_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, ++ gimple_seq *post_p) ++{ ++ tree offset_field, base_field, offset, base, t, r; ++ bool indirect; ++ ++ base_field = TYPE_FIELDS (va_list_type_node); ++ offset_field = DECL_CHAIN (base_field); ++ base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field), valist, ++ base_field, NULL_TREE); ++ offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field), valist, ++ offset_field, NULL_TREE); ++ ++ /* Pull the fields of the structure out into temporaries. Since we never ++ modify the base field, we can use a formal temporary. Sign-extend the ++ offset field so that it's the proper width for pointer arithmetic. */ ++ base = get_formal_tmp_var (base_field, pre_p); ++ ++ t = fold_convert (build_nonstandard_integer_type (64, 0), offset_field); ++ offset = get_initialized_tmp_var (t, pre_p, NULL); ++ ++ indirect = pass_va_arg_by_reference (type); ++ ++ if (indirect) ++ { ++ if (TREE_CODE (type) == COMPLEX_TYPE ++ && targetm.calls.split_complex_arg (type)) ++ { ++ tree real_part, imag_part, real_temp; ++ ++ tree ptr_type ++ = build_pointer_type_for_mode (TREE_TYPE (type), ptr_mode, true); ++ ++ real_part = sw_64_gimplify_va_arg_1 (ptr_type, base, offset, pre_p); ++ real_part = build_va_arg_indirect_ref (real_part); ++ ++ /* Copy the value into a new temporary, lest the formal temporary ++ be reused out from under us. */ ++ real_temp = get_initialized_tmp_var (real_part, pre_p, NULL); ++ ++ imag_part = sw_64_gimplify_va_arg_1 (ptr_type, base, offset, pre_p); ++ imag_part = build_va_arg_indirect_ref (imag_part); ++ ++ r = build2 (COMPLEX_EXPR, type, real_temp, imag_part); ++ ++ /* Stuff the offset temporary back into its field. */ ++ gimplify_assign (unshare_expr (offset_field), ++ fold_convert (TREE_TYPE (offset_field), offset), ++ pre_p); ++ return r; ++ } ++ else ++ type = build_pointer_type_for_mode (type, ptr_mode, true); ++ } ++ ++ /* Find the value. Note that this will be a stable indirection, or ++ a composite of stable indirections in the case of complex. */ ++ r = sw_64_gimplify_va_arg_1 (type, base, offset, pre_p); ++ ++ /* Stuff the offset temporary back into its field. */ ++ gimplify_assign (unshare_expr (offset_field), ++ fold_convert (TREE_TYPE (offset_field), offset), pre_p); ++ ++ if (indirect) ++ r = build_va_arg_indirect_ref (r); ++ ++ return r; ++} ++ ++/* Builtins. */ ++ ++enum sw_64_builtin ++{ ++ SW_64_BUILTIN_CMPBGE, ++ SW_64_BUILTIN_EXTBL, ++ SW_64_BUILTIN_EXTWL, ++ SW_64_BUILTIN_EXTLL, ++ SW_64_BUILTIN_EXTQL, ++ SW_64_BUILTIN_EXTWH, ++ SW_64_BUILTIN_EXTLH, ++ SW_64_BUILTIN_EXTQH, ++ SW_64_BUILTIN_INSBL, ++ SW_64_BUILTIN_INSWL, ++ SW_64_BUILTIN_INSLL, ++ SW_64_BUILTIN_INSQL, ++ SW_64_BUILTIN_INSWH, ++ SW_64_BUILTIN_INSLH, ++ SW_64_BUILTIN_INSQH, ++ SW_64_BUILTIN_MSKBL, ++ SW_64_BUILTIN_MSKWL, ++ SW_64_BUILTIN_MSKLL, ++ SW_64_BUILTIN_MSKQL, ++ SW_64_BUILTIN_MSKWH, ++ SW_64_BUILTIN_MSKLH, ++ SW_64_BUILTIN_MSKQH, ++ SW_64_BUILTIN_UMULH, ++ SW_64_BUILTIN_ZAP, ++ SW_64_BUILTIN_ZAPNOT, ++ SW_64_BUILTIN_AMASK, ++ SW_64_BUILTIN_IMPLVER, ++ SW_64_BUILTIN_RPCC, ++ ++ /* TARGET_MAX */ ++ SW_64_BUILTIN_MINUB8, ++ SW_64_BUILTIN_MINSB8, ++ SW_64_BUILTIN_MINUW4, ++ SW_64_BUILTIN_MINSW4, ++ SW_64_BUILTIN_MAXUB8, ++ SW_64_BUILTIN_MAXSB8, ++ SW_64_BUILTIN_MAXUW4, ++ SW_64_BUILTIN_MAXSW4, ++ SW_64_BUILTIN_PERR, ++ SW_64_BUILTIN_PKLB, ++ SW_64_BUILTIN_PKWB, ++ SW_64_BUILTIN_UNPKBL, ++ SW_64_BUILTIN_UNPKBW, ++ ++ /* TARGET_CIX */ ++ SW_64_BUILTIN_CTTZ, ++ SW_64_BUILTIN_CTLZ, ++ SW_64_BUILTIN_CTPOP, ++ ++ SW_64_BUILTIN_max ++}; ++ ++static enum insn_code const code_for_builtin[SW_64_BUILTIN_max] ++ = {CODE_FOR_builtin_cmpbge, CODE_FOR_extbl, CODE_FOR_extwl, CODE_FOR_extll, ++ CODE_FOR_extql, CODE_FOR_extwh, CODE_FOR_extlh, CODE_FOR_extqh, ++ CODE_FOR_builtin_insbl, CODE_FOR_builtin_inswl, CODE_FOR_builtin_insll, ++ CODE_FOR_insql, CODE_FOR_inswh, CODE_FOR_inslh, CODE_FOR_insqh, ++ CODE_FOR_mskbl, CODE_FOR_mskwl, CODE_FOR_mskll, CODE_FOR_mskql, ++ CODE_FOR_mskwh, CODE_FOR_msklh, CODE_FOR_mskqh, CODE_FOR_umuldi3_highpart, ++ CODE_FOR_builtin_zap, CODE_FOR_builtin_zapnot, CODE_FOR_builtin_amask, ++ CODE_FOR_builtin_implver, CODE_FOR_builtin_rpcc, ++ ++ /* TARGET_MAX */ ++ CODE_FOR_builtin_minub8, CODE_FOR_builtin_minsb8, CODE_FOR_builtin_minuw4, ++ CODE_FOR_builtin_minsw4, CODE_FOR_builtin_maxub8, CODE_FOR_builtin_maxsb8, ++ CODE_FOR_builtin_maxuw4, CODE_FOR_builtin_maxsw4, CODE_FOR_builtin_perr, ++ CODE_FOR_builtin_pklb, CODE_FOR_builtin_pkwb, CODE_FOR_builtin_unpkbl, ++ CODE_FOR_builtin_unpkbw, ++ ++ /* TARGET_CIX */ ++ CODE_FOR_ctzdi2, CODE_FOR_clzdi2, CODE_FOR_popcountdi2}; ++ ++struct sw_64_builtin_def ++{ ++ const char *name; ++ enum sw_64_builtin code; ++ unsigned int target_mask; ++ bool is_const; ++}; ++ ++static struct sw_64_builtin_def const zero_arg_builtins[] ++ = {{"__builtin_sw_64_implver", SW_64_BUILTIN_IMPLVER, 0, true}, ++ {"__builtin_sw_64_rpcc", SW_64_BUILTIN_RPCC, 0, false}}; ++ ++static struct sw_64_builtin_def const one_arg_builtins[] ++ = {{"__builtin_sw_64_amask", SW_64_BUILTIN_AMASK, 0, true}, ++ {"__builtin_sw_64_pklb", SW_64_BUILTIN_PKLB, MASK_MAX, true}, ++ {"__builtin_sw_64_pkwb", SW_64_BUILTIN_PKWB, MASK_MAX, true}, ++ {"__builtin_sw_64_unpkbl", SW_64_BUILTIN_UNPKBL, MASK_MAX, true}, ++ {"__builtin_sw_64_unpkbw", SW_64_BUILTIN_UNPKBW, MASK_MAX, true}, ++ {"__builtin_sw_64_cttz", SW_64_BUILTIN_CTTZ, MASK_CIX, true}, ++ {"__builtin_sw_64_ctlz", SW_64_BUILTIN_CTLZ, MASK_CIX, true}, ++ {"__builtin_sw_64_ctpop", SW_64_BUILTIN_CTPOP, MASK_CIX, true}}; ++ ++static struct sw_64_builtin_def const two_arg_builtins[] ++ = {{"__builtin_sw_64_cmpbge", SW_64_BUILTIN_CMPBGE, 0, true}, ++ {"__builtin_sw_64_extbl", SW_64_BUILTIN_EXTBL, 0, true}, ++ {"__builtin_sw_64_extwl", SW_64_BUILTIN_EXTWL, 0, true}, ++ {"__builtin_sw_64_extll", SW_64_BUILTIN_EXTLL, 0, true}, ++ {"__builtin_sw_64_extql", SW_64_BUILTIN_EXTQL, 0, true}, ++ {"__builtin_sw_64_extwh", SW_64_BUILTIN_EXTWH, 0, true}, ++ {"__builtin_sw_64_extlh", SW_64_BUILTIN_EXTLH, 0, true}, ++ {"__builtin_sw_64_extqh", SW_64_BUILTIN_EXTQH, 0, true}, ++ {"__builtin_sw_64_insbl", SW_64_BUILTIN_INSBL, 0, true}, ++ {"__builtin_sw_64_inswl", SW_64_BUILTIN_INSWL, 0, true}, ++ {"__builtin_sw_64_insll", SW_64_BUILTIN_INSLL, 0, true}, ++ {"__builtin_sw_64_insql", SW_64_BUILTIN_INSQL, 0, true}, ++ {"__builtin_sw_64_inswh", SW_64_BUILTIN_INSWH, 0, true}, ++ {"__builtin_sw_64_inslh", SW_64_BUILTIN_INSLH, 0, true}, ++ {"__builtin_sw_64_insqh", SW_64_BUILTIN_INSQH, 0, true}, ++ {"__builtin_sw_64_mskbl", SW_64_BUILTIN_MSKBL, 0, true}, ++ {"__builtin_sw_64_mskwl", SW_64_BUILTIN_MSKWL, 0, true}, ++ {"__builtin_sw_64_mskll", SW_64_BUILTIN_MSKLL, 0, true}, ++ {"__builtin_sw_64_mskql", SW_64_BUILTIN_MSKQL, 0, true}, ++ {"__builtin_sw_64_mskwh", SW_64_BUILTIN_MSKWH, 0, true}, ++ {"__builtin_sw_64_msklh", SW_64_BUILTIN_MSKLH, 0, true}, ++ {"__builtin_sw_64_mskqh", SW_64_BUILTIN_MSKQH, 0, true}, ++ {"__builtin_sw_64_umulh", SW_64_BUILTIN_UMULH, 0, true}, ++ {"__builtin_sw_64_zap", SW_64_BUILTIN_ZAP, 0, true}, ++ {"__builtin_sw_64_zapnot", SW_64_BUILTIN_ZAPNOT, 0, true}, ++ {"__builtin_sw_64_minub8", SW_64_BUILTIN_MINUB8, MASK_MAX, true}, ++ {"__builtin_sw_64_minsb8", SW_64_BUILTIN_MINSB8, MASK_MAX, true}, ++ {"__builtin_sw_64_minuw4", SW_64_BUILTIN_MINUW4, MASK_MAX, true}, ++ {"__builtin_sw_64_minsw4", SW_64_BUILTIN_MINSW4, MASK_MAX, true}, ++ {"__builtin_sw_64_maxub8", SW_64_BUILTIN_MAXUB8, MASK_MAX, true}, ++ {"__builtin_sw_64_maxsb8", SW_64_BUILTIN_MAXSB8, MASK_MAX, true}, ++ {"__builtin_sw_64_maxuw4", SW_64_BUILTIN_MAXUW4, MASK_MAX, true}, ++ {"__builtin_sw_64_maxsw4", SW_64_BUILTIN_MAXSW4, MASK_MAX, true}, ++ {"__builtin_sw_64_perr", SW_64_BUILTIN_PERR, MASK_MAX, true}}; ++ ++static GTY (()) tree sw_64_dimode_u; ++static GTY (()) tree sw_64_v8qi_u; ++static GTY (()) tree sw_64_v8qi_s; ++static GTY (()) tree sw_64_v4hi_u; ++static GTY (()) tree sw_64_v4hi_s; ++ ++static GTY (()) tree sw_64_builtins[(int) SW_64_BUILTIN_max]; ++ ++/* Return the sw_64 builtin for CODE. */ ++ ++static tree ++sw_64_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) ++{ ++ if (code >= SW_64_BUILTIN_max) ++ return error_mark_node; ++ return sw_64_builtins[code]; ++} ++ ++/* Helper function of sw_64_init_builtins. Add the built-in specified ++ by NAME, TYPE, CODE, and ECF. */ ++ ++static void ++sw_64_builtin_function (const char *name, tree ftype, enum sw_64_builtin code, ++ unsigned ecf) ++{ ++ tree decl = add_builtin_function (name, ftype, (int) code, BUILT_IN_MD, NULL, ++ NULL_TREE); ++ ++ if (ecf & ECF_CONST) ++ TREE_READONLY (decl) = 1; ++ if (ecf & ECF_NOTHROW) ++ TREE_NOTHROW (decl) = 1; ++ ++ sw_64_builtins[(int) code] = decl; ++} ++ ++/* Helper function of sw_64_init_builtins. Add the COUNT built-in ++ functions pointed to by P, with function type FTYPE. */ ++ ++static void ++sw_64_add_builtins (const struct sw_64_builtin_def *p, size_t count, tree ftype) ++{ ++ size_t i; ++ ++ for (i = 0; i < count; ++i, ++p) ++ if ((target_flags & p->target_mask) == p->target_mask) ++ sw_64_builtin_function (p->name, ftype, p->code, ++ (p->is_const ? ECF_CONST : 0) | ECF_NOTHROW); ++} ++ ++static void ++sw_64_init_builtins (void) ++{ ++ tree ftype; ++ ++ sw_64_dimode_u = lang_hooks.types.type_for_mode (DImode, 1); ++ sw_64_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8); ++ sw_64_v8qi_s = build_vector_type (intQI_type_node, 8); ++ sw_64_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4); ++ sw_64_v4hi_s = build_vector_type (intHI_type_node, 4); ++ ++ ftype = build_function_type_list (sw_64_dimode_u, NULL_TREE); ++ sw_64_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins), ftype); ++ ++ ftype = build_function_type_list (sw_64_dimode_u, sw_64_dimode_u, NULL_TREE); ++ sw_64_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins), ftype); ++ ++ ftype = build_function_type_list (sw_64_dimode_u, sw_64_dimode_u, ++ sw_64_dimode_u, NULL_TREE); ++ sw_64_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype); ++ ++} ++ ++/* Expand an expression EXP that calls a built-in function, ++ with result going to TARGET if that's convenient ++ (and in mode MODE if that's convenient). ++ SUBTARGET may be used as the target for computing one of EXP's operands. ++ IGNORE is nonzero if the value is to be ignored. */ ++ ++static rtx ++sw_64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, ++ machine_mode mode ATTRIBUTE_UNUSED, ++ int ignore ATTRIBUTE_UNUSED) ++{ ++#define MAX_ARGS 2 ++ ++ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); ++ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); ++ tree arg; ++ call_expr_arg_iterator iter; ++ enum insn_code icode; ++ rtx op[MAX_ARGS], pat; ++ int arity; ++ bool nonvoid; ++ ++ if (fcode >= SW_64_BUILTIN_max) ++ internal_error ("bad builtin fcode"); ++ icode = code_for_builtin[fcode]; ++ if (icode == 0) ++ internal_error ("bad builtin fcode"); ++ ++ nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node; ++ ++ arity = 0; ++ FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) ++ { ++ const struct insn_operand_data *insn_op; ++ ++ if (arg == error_mark_node) ++ return NULL_RTX; ++ if (arity > MAX_ARGS) ++ return NULL_RTX; ++ ++ insn_op = &insn_data[icode].operand[arity + nonvoid]; ++ ++ op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL); ++ ++ if (!(*insn_op->predicate) (op[arity], insn_op->mode)) ++ op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]); ++ arity++; ++ } ++ ++ if (nonvoid) ++ { ++ machine_mode tmode = insn_data[icode].operand[0].mode; ++ if (!target || GET_MODE (target) != tmode ++ || !(*insn_data[icode].operand[0].predicate) (target, tmode)) ++ target = gen_reg_rtx (tmode); ++ } ++ ++ switch (arity) ++ { ++ case 0: ++ pat = GEN_FCN (icode) (target); ++ break; ++ case 1: ++ if (nonvoid) ++ pat = GEN_FCN (icode) (target, op[0]); ++ else ++ pat = GEN_FCN (icode) (op[0]); ++ break; ++ case 2: ++ pat = GEN_FCN (icode) (target, op[0], op[1]); ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ if (!pat) ++ return NULL_RTX; ++ emit_insn (pat); ++ ++ if (nonvoid) ++ return target; ++ else ++ return const0_rtx; ++} ++ ++/* Fold the builtin for the CMPBGE instruction. This is a vector comparison ++ with an 8-bit output vector. OPINT contains the integer operands; bit N ++ of OP_CONST is set if OPINT[N] is valid. */ ++ ++static tree ++sw_64_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ if (op_const == 3) ++ { ++ int i, val; ++ for (i = 0, val = 0; i < 8; ++i) ++ { ++ unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff; ++ unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff; ++ if (c0 >= c1) ++ val |= 1 << i; ++ } ++ return build_int_cst (sw_64_dimode_u, val); ++ } ++ else if (op_const == 2 && opint[1] == 0) ++ return build_int_cst (sw_64_dimode_u, 0xff); ++ return NULL; ++} ++ ++/* Fold the builtin for the ZAPNOT instruction. This is essentially a ++ specialized form of an AND operation. Other byte manipulation instructions ++ are defined in terms of this instruction, so this is also used as a ++ subroutine for other builtins. ++ ++ OP contains the tree operands; OPINT contains the extracted integer values. ++ Bit N of OP_CONST it set if OPINT[N] is valid. OP may be null if only ++ OPINT may be considered. */ ++ ++static tree ++sw_64_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[], ++ long op_const) ++{ ++ if (op_const & 2) ++ { ++ unsigned HOST_WIDE_INT mask = 0; ++ int i; ++ ++ for (i = 0; i < 8; ++i) ++ if ((opint[1] >> i) & 1) ++ mask |= (unsigned HOST_WIDE_INT) 0xff << (i * 8); ++ ++ if (op_const & 1) ++ return build_int_cst (sw_64_dimode_u, opint[0] & mask); ++ ++ if (op) ++ return fold_build2 (BIT_AND_EXPR, sw_64_dimode_u, op[0], ++ build_int_cst (sw_64_dimode_u, mask)); ++ } ++ else if ((op_const & 1) && opint[0] == 0) ++ return build_int_cst (sw_64_dimode_u, 0); ++ return NULL; ++} ++ ++/* Fold the builtins for the EXT family of instructions. */ ++ ++static tree ++sw_64_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[], ++ long op_const, unsigned HOST_WIDE_INT bytemask, ++ bool is_high) ++{ ++ long zap_const = 2; ++ tree *zap_op = NULL; ++ ++ if (op_const & 2) ++ { ++ unsigned HOST_WIDE_INT loc; ++ ++ loc = opint[1] & 7; ++ loc *= BITS_PER_UNIT; ++ ++ if (loc != 0) ++ { ++ if (op_const & 1) ++ { ++ unsigned HOST_WIDE_INT temp = opint[0]; ++ if (is_high) ++ temp <<= loc; ++ else ++ temp >>= loc; ++ opint[0] = temp; ++ zap_const = 3; ++ } ++ } ++ else ++ zap_op = op; ++ } ++ ++ opint[1] = bytemask; ++ return sw_64_fold_builtin_zapnot (zap_op, opint, zap_const); ++} ++ ++/* Fold the builtins for the INS family of instructions. */ ++ ++static tree ++sw_64_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[], ++ long op_const, unsigned HOST_WIDE_INT bytemask, ++ bool is_high) ++{ ++ if ((op_const & 1) && opint[0] == 0) ++ return build_int_cst (sw_64_dimode_u, 0); ++ ++ if (op_const & 2) ++ { ++ unsigned HOST_WIDE_INT temp, loc, byteloc; ++ tree *zap_op = NULL; ++ ++ loc = opint[1] & 7; ++ bytemask <<= loc; ++ ++ temp = opint[0]; ++ if (is_high) ++ { ++ byteloc = (64 - (loc * 8)) & 0x3f; ++ if (byteloc == 0) ++ zap_op = op; ++ else ++ temp >>= byteloc; ++ bytemask >>= 8; ++ } ++ else ++ { ++ byteloc = loc * 8; ++ if (byteloc == 0) ++ zap_op = op; ++ else ++ temp <<= byteloc; ++ } ++ ++ opint[0] = temp; ++ opint[1] = bytemask; ++ return sw_64_fold_builtin_zapnot (zap_op, opint, op_const); ++ } ++ ++ return NULL; ++} ++ ++static tree ++sw_64_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[], ++ long op_const, unsigned HOST_WIDE_INT bytemask, ++ bool is_high) ++{ ++ if (op_const & 2) ++ { ++ unsigned HOST_WIDE_INT loc; ++ ++ loc = opint[1] & 7; ++ bytemask <<= loc; ++ ++ if (is_high) ++ bytemask >>= 8; ++ ++ opint[1] = bytemask ^ 0xff; ++ } ++ ++ return sw_64_fold_builtin_zapnot (op, opint, op_const); ++} ++ ++static tree ++sw_64_fold_vector_minmax (enum tree_code code, tree op[], tree vtype) ++{ ++ tree op0 = fold_convert (vtype, op[0]); ++ tree op1 = fold_convert (vtype, op[1]); ++ tree val = fold_build2 (code, vtype, op0, op1); ++ return fold_build1 (VIEW_CONVERT_EXPR, sw_64_dimode_u, val); ++} ++ ++static tree ++sw_64_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp = 0; ++ int i; ++ ++ if (op_const != 3) ++ return NULL; ++ ++ for (i = 0; i < 8; ++i) ++ { ++ unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff; ++ unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff; ++ if (a >= b) ++ temp += a - b; ++ else ++ temp += b - a; ++ } ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ temp = opint[0] & 0xff; ++ temp |= (opint[0] >> 24) & 0xff00; ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ temp = opint[0] & 0xff; ++ temp |= (opint[0] >> 8) & 0xff00; ++ temp |= (opint[0] >> 16) & 0xff0000; ++ temp |= (opint[0] >> 24) & 0xff000000; ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ temp = opint[0] & 0xff; ++ temp |= (opint[0] & 0xff00) << 24; ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ temp = opint[0] & 0xff; ++ temp |= (opint[0] & 0x0000ff00) << 8; ++ temp |= (opint[0] & 0x00ff0000) << 16; ++ temp |= (opint[0] & 0xff000000) << 24; ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ if (opint[0] == 0) ++ temp = 64; ++ else ++ temp = exact_log2 (opint[0] & -opint[0]); ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ if (opint[0] == 0) ++ temp = 64; ++ else ++ temp = 64 - floor_log2 (opint[0]) - 1; ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++static tree ++sw_64_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const) ++{ ++ unsigned HOST_WIDE_INT temp, op; ++ ++ if (op_const == 0) ++ return NULL; ++ ++ op = opint[0]; ++ temp = 0; ++ while (op) ++ temp++, op &= op - 1; ++ ++ return build_int_cst (sw_64_dimode_u, temp); ++} ++ ++/* Fold one of our builtin functions. */ ++ ++static tree ++sw_64_fold_builtin (tree fndecl, int n_args, tree *op, ++ bool ignore ATTRIBUTE_UNUSED) ++{ ++ unsigned HOST_WIDE_INT opint[MAX_ARGS]; ++ long op_const = 0; ++ int i; ++ ++ if (n_args > MAX_ARGS) ++ return NULL; ++ ++ for (i = 0; i < n_args; i++) ++ { ++ tree arg = op[i]; ++ if (arg == error_mark_node) ++ return NULL; ++ ++ opint[i] = 0; ++ if (TREE_CODE (arg) == INTEGER_CST) ++ { ++ op_const |= 1L << i; ++ opint[i] = int_cst_value (arg); ++ } ++ } ++ ++ switch (DECL_MD_FUNCTION_CODE (fndecl)) ++ { ++ case SW_64_BUILTIN_CMPBGE: ++ return sw_64_fold_builtin_cmpbge (opint, op_const); ++ ++ case SW_64_BUILTIN_EXTBL: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0x01, false); ++ case SW_64_BUILTIN_EXTWL: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0x03, false); ++ case SW_64_BUILTIN_EXTLL: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0x0f, false); ++ case SW_64_BUILTIN_EXTQL: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0xff, false); ++ case SW_64_BUILTIN_EXTWH: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0x03, true); ++ case SW_64_BUILTIN_EXTLH: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0x0f, true); ++ case SW_64_BUILTIN_EXTQH: ++ return sw_64_fold_builtin_extxx (op, opint, op_const, 0xff, true); ++ ++ case SW_64_BUILTIN_INSBL: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0x01, false); ++ case SW_64_BUILTIN_INSWL: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0x03, false); ++ case SW_64_BUILTIN_INSLL: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0x0f, false); ++ case SW_64_BUILTIN_INSQL: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0xff, false); ++ case SW_64_BUILTIN_INSWH: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0x03, true); ++ case SW_64_BUILTIN_INSLH: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0x0f, true); ++ case SW_64_BUILTIN_INSQH: ++ return sw_64_fold_builtin_insxx (op, opint, op_const, 0xff, true); ++ ++ case SW_64_BUILTIN_MSKBL: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0x01, false); ++ case SW_64_BUILTIN_MSKWL: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0x03, false); ++ case SW_64_BUILTIN_MSKLL: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0x0f, false); ++ case SW_64_BUILTIN_MSKQL: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0xff, false); ++ case SW_64_BUILTIN_MSKWH: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0x03, true); ++ case SW_64_BUILTIN_MSKLH: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0x0f, true); ++ case SW_64_BUILTIN_MSKQH: ++ return sw_64_fold_builtin_mskxx (op, opint, op_const, 0xff, true); ++ ++ case SW_64_BUILTIN_ZAP: ++ opint[1] ^= 0xff; ++ /* FALLTHRU */ ++ case SW_64_BUILTIN_ZAPNOT: ++ return sw_64_fold_builtin_zapnot (op, opint, op_const); ++ ++ case SW_64_BUILTIN_MINUB8: ++ return sw_64_fold_vector_minmax (MIN_EXPR, op, sw_64_v8qi_u); ++ case SW_64_BUILTIN_MINSB8: ++ return sw_64_fold_vector_minmax (MIN_EXPR, op, sw_64_v8qi_s); ++ case SW_64_BUILTIN_MINUW4: ++ return sw_64_fold_vector_minmax (MIN_EXPR, op, sw_64_v4hi_u); ++ case SW_64_BUILTIN_MINSW4: ++ return sw_64_fold_vector_minmax (MIN_EXPR, op, sw_64_v4hi_s); ++ case SW_64_BUILTIN_MAXUB8: ++ return sw_64_fold_vector_minmax (MAX_EXPR, op, sw_64_v8qi_u); ++ case SW_64_BUILTIN_MAXSB8: ++ return sw_64_fold_vector_minmax (MAX_EXPR, op, sw_64_v8qi_s); ++ case SW_64_BUILTIN_MAXUW4: ++ return sw_64_fold_vector_minmax (MAX_EXPR, op, sw_64_v4hi_u); ++ case SW_64_BUILTIN_MAXSW4: ++ return sw_64_fold_vector_minmax (MAX_EXPR, op, sw_64_v4hi_s); ++ ++ case SW_64_BUILTIN_PERR: ++ return sw_64_fold_builtin_perr (opint, op_const); ++ case SW_64_BUILTIN_PKLB: ++ return sw_64_fold_builtin_pklb (opint, op_const); ++ case SW_64_BUILTIN_PKWB: ++ return sw_64_fold_builtin_pkwb (opint, op_const); ++ case SW_64_BUILTIN_UNPKBL: ++ return sw_64_fold_builtin_unpkbl (opint, op_const); ++ case SW_64_BUILTIN_UNPKBW: ++ return sw_64_fold_builtin_unpkbw (opint, op_const); ++ ++ case SW_64_BUILTIN_CTTZ: ++ return sw_64_fold_builtin_cttz (opint, op_const); ++ case SW_64_BUILTIN_CTLZ: ++ return sw_64_fold_builtin_ctlz (opint, op_const); ++ case SW_64_BUILTIN_CTPOP: ++ return sw_64_fold_builtin_ctpop (opint, op_const); ++ ++ case SW_64_BUILTIN_AMASK: ++ case SW_64_BUILTIN_IMPLVER: ++ case SW_64_BUILTIN_RPCC: ++ /* None of these are foldable at compile-time. */ ++ default: ++ return NULL; ++ } ++} ++ ++bool ++sw_64_gimple_fold_builtin (gimple_stmt_iterator *gsi) ++{ ++ bool changed = false; ++ gimple *stmt = gsi_stmt (*gsi); ++ tree call = gimple_call_fn (stmt); ++ gimple *new_stmt = NULL; ++ ++ if (call) ++ { ++ tree fndecl = gimple_call_fndecl (stmt); ++ ++ if (fndecl) ++ { ++ tree arg0, arg1; ++ ++ switch (DECL_MD_FUNCTION_CODE (fndecl)) ++ { ++ case SW_64_BUILTIN_UMULH: ++ arg0 = gimple_call_arg (stmt, 0); ++ arg1 = gimple_call_arg (stmt, 1); ++ ++ new_stmt = gimple_build_assign (gimple_call_lhs (stmt), ++ MULT_HIGHPART_EXPR, arg0, arg1); ++ break; ++ default: ++ break; ++ } ++ } ++ } ++ ++ if (new_stmt) ++ { ++ gsi_replace (gsi, new_stmt, true); ++ changed = true; ++ } ++ ++ return changed; ++} ++ ++/* This page contains routines that are used to determine what the function ++ prologue and epilogue code will do and write them out. */ ++ ++/* Compute the size of the save area in the stack. */ ++ ++/* These variables are used for communication between the following functions. ++ They indicate various things about the current function being compiled ++ that are used to tell what kind of prologue, epilogue and procedure ++ descriptor to generate. */ ++ ++/* Nonzero if we need a stack procedure. */ ++enum sw_64_procedure_types ++{ ++ PT_NULL = 0, ++ PT_REGISTER = 1, ++ PT_STACK = 2 ++}; ++static enum sw_64_procedure_types sw_64_procedure_type; ++ ++/* Compute register masks for saved registers, register save area size, ++ and total frame size. */ ++static void ++sw_64_compute_frame_layout (void) ++{ ++ unsigned HOST_WIDE_INT sa_mask = 0; ++ HOST_WIDE_INT frame_size; ++ int sa_size; ++ ++ /* When outputting a thunk, we don't have valid register life info, ++ but assemble_start_function wants to output .frame and .mask ++ directives. */ ++ if (!cfun->is_thunk) ++ { ++ /* One for every register we have to save. */ ++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++) ++ if (!call_used_or_fixed_reg_p (i) && df_regs_ever_live_p (i) ++ && i != REG_RA) ++ sa_mask |= HOST_WIDE_INT_1U << i; ++ ++ /* We need to restore these for the handler. */ ++ if (crtl->calls_eh_return) ++ { ++ for (unsigned i = 0;; ++i) ++ { ++ unsigned regno = EH_RETURN_DATA_REGNO (i); ++ if (regno == INVALID_REGNUM) ++ break; ++ sa_mask |= HOST_WIDE_INT_1U << regno; ++ } ++ } ++ /* If any register spilled, then spill the return address also. */ ++ /* ??? This is required by the Digital stack unwind specification ++ and isn't needed if we're doing Dwarf2 unwinding. */ ++ if (sa_mask || sw_64_ra_ever_killed ()) ++ sa_mask |= HOST_WIDE_INT_1U << REG_RA; ++ } ++ sa_size = popcount_hwi (sa_mask); ++ frame_size = get_frame_size (); ++ ++ /* Our size must be even (multiple of 16 bytes). */ ++ if (sa_size & 1) ++ sa_size++; ++ sa_size *= 8; ++ ++ frame_size = (SW_64_ROUND (crtl->outgoing_args_size) + sa_size ++ + SW_64_ROUND (frame_size + crtl->args.pretend_args_size)); ++ ++ cfun->machine->sa_mask = sa_mask; ++ cfun->machine->sa_size = sa_size; ++ cfun->machine->frame_size = frame_size; ++} ++ ++#undef TARGET_COMPUTE_FRAME_LAYOUT ++#define TARGET_COMPUTE_FRAME_LAYOUT sw_64_layout_frame ++ ++/* Return 1 if this function can directly return via $26. */ ++ ++bool ++direct_return (void) ++{ ++ return (reload_completed && cfun->machine->frame_size == 0); ++} ++ ++bool ++sw_64_find_lo_sum_using_gp (rtx insn) ++{ ++ subrtx_iterator::array_type array; ++ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST) ++ { ++ const_rtx x = *iter; ++ if (GET_CODE (x) == LO_SUM && XEXP (x, 0) == pic_offset_table_rtx) ++ return true; ++ } ++ return false; ++} ++ ++static int ++sw_64_does_function_need_gp (void) ++{ ++ rtx_insn *insn; ++ ++ /* We need the gp to load the address of __mcount. */ ++ if (TARGET_PROFILING_NEEDS_GP && crtl->profile) ++ return 1; ++ ++ /* The code emitted by sw_64_output_mi_thunk_sysv uses the gp. */ ++ if (cfun->is_thunk) ++ return 1; ++ ++ /* The nonlocal receiver pattern assumes that the gp is valid for ++ the nested function. Reasonable because it's almost always set ++ correctly already. For the cases where that's wrong, make sure ++ the nested function loads its gp on entry. */ ++ if (crtl->has_nonlocal_goto) ++ return 1; ++ ++ /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. ++ Even if we are a static function, we still need to do this in case ++ our address is taken and passed to something like qsort. */ ++ ++ push_topmost_sequence (); ++ insn = get_insns (); ++ pop_topmost_sequence (); ++ ++ for (; insn; insn = NEXT_INSN (insn)) ++ if (NONDEBUG_INSN_P (insn) && GET_CODE (PATTERN (insn)) != USE ++ && GET_CODE (PATTERN (insn)) != CLOBBER && get_attr_usegp (insn)) ++ return 1; ++ ++ return 0; ++} ++ ++/* Helper function to set RTX_FRAME_RELATED_P on instructions, including ++ sequences. */ ++ ++static rtx_insn * ++set_frame_related_p (void) ++{ ++ rtx_insn *seq = get_insns (); ++ rtx_insn *insn; ++ ++ end_sequence (); ++ ++ if (!seq) ++ return NULL; ++ ++ if (INSN_P (seq)) ++ { ++ insn = seq; ++ while (insn != NULL_RTX) ++ { ++ RTX_FRAME_RELATED_P (insn) = 1; ++ insn = NEXT_INSN (insn); ++ } ++ seq = emit_insn (seq); ++ } ++ else ++ { ++ seq = emit_insn (seq); ++ RTX_FRAME_RELATED_P (seq) = 1; ++ } ++ return seq; ++} ++ ++#define FRP(exp) (start_sequence (), exp, set_frame_related_p ()) ++ ++/* Generates a store with the proper unwind info attached. VALUE is ++ stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG ++ contains SP+FRAME_BIAS, and that is the unwind info that should be ++ generated. If FRAME_REG != VALUE, then VALUE is being stored on ++ behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */ ++ ++static void ++emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias, ++ HOST_WIDE_INT base_ofs, rtx frame_reg) ++{ ++ rtx addr, mem; ++ rtx_insn *insn; ++ ++ addr = plus_constant (Pmode, base_reg, base_ofs); ++ mem = gen_frame_mem (DImode, addr); ++ ++ insn = emit_move_insn (mem, value); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ ++ if (frame_bias || value != frame_reg) ++ { ++ if (frame_bias) ++ { ++ addr ++ = plus_constant (Pmode, stack_pointer_rtx, frame_bias + base_ofs); ++ mem = gen_rtx_MEM (DImode, addr); ++ } ++ ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, gen_rtx_SET (mem, frame_reg)); ++ } ++} ++ ++static void ++emit_frame_store (unsigned int regno, rtx base_reg, HOST_WIDE_INT frame_bias, ++ HOST_WIDE_INT base_ofs) ++{ ++ rtx reg = gen_rtx_REG (DImode, regno); ++ emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg); ++} ++ ++static void ++sw64_add_cfa_expression (rtx_insn *insn, unsigned int reg, rtx base, ++ poly_int64 offset) ++{ ++ rtx mem = gen_frame_mem (DImode, plus_constant (Pmode, base, offset)); ++ add_reg_note (insn, REG_CFA_EXPRESSION, ++ gen_rtx_SET (mem, regno_reg_rtx[reg])); ++} ++ ++/* Write function prologue. */ ++ ++void ++sw_64_expand_prologue (void) ++{ ++ /* Registers to save. */ ++ unsigned HOST_WIDE_INT sa_mask = cfun->machine->frame.sa_mask; ++ /* Stack space needed for pushing registers clobbered by us. */ ++ HOST_WIDE_INT sa_size = cfun->machine->frame.saved_regs_size; ++ /* Complete stack size needed. */ ++ HOST_WIDE_INT frame_size = cfun->machine->frame.frame_size; ++ /* Probed stack size; it additionally includes the size of ++ the "reserve region" if any. */ ++ HOST_WIDE_INT probed_size, sa_bias; ++ /* Offset from base reg to register save area. */ ++ HOST_WIDE_INT reg_offset; ++ rtx sa_reg; ++ bool fp_flag = false; ++ ++ if (flag_stack_usage_info) ++ current_function_static_stack_size = frame_size; ++ ++#ifdef SW_64_ENABLE_FULL_ASAN ++ reg_offset = aligned_upper_bound (crtl->outgoing_args_size, ++ STACK_BOUNDARY / BITS_PER_UNIT); ++#else ++ reg_offset = SW_64_ROUND (crtl->outgoing_args_size); ++#endif ++ ++ /* Emit an insn to reload GP, if needed. */ ++ sw_64_function_needs_gp = sw_64_does_function_need_gp (); ++ if (sw_64_function_needs_gp) ++ emit_insn (gen_prologue_ldgp ()); ++ if (strcmp ("main", lang_hooks.decl_printable_name (cfun->decl, 1)) == 0 ++ && (TARGET_SW_32ALIGN || TARGET_SW_SIMD)) ++ { ++ rtx const16 = gen_rtx_REG (DImode, 7); ++ sw_64_emit_set_const (const16, DImode, 16, 3, false); ++ emit_insn (gen_anddi3 (const16, const16, stack_pointer_rtx)); ++ emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, const16)); ++ ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-32))); ++ rtx mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (0)); ++ rtx tmp7 = gen_rtx_MEM (Pmode, mem_address); ++ emit_move_insn (tmp7, gen_rtx_REG (DImode, 7)); ++ } ++ /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert ++ the call to mcount ourselves, rather than having the linker do it ++ magically in response to -pg. Since _mcount has special linkage, ++ don't represent the call as a call. */ ++ if (TARGET_PROFILING_NEEDS_GP && crtl->profile) ++ emit_insn (gen_prologue_mcount ()); ++ ++ if (strcmp ("main", lang_hooks.decl_printable_name (cfun->decl, 1)) == 0 ++ && flag_sw_hardware_prefetch) ++ { ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-256))); ++ rtx mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (8)); ++ rtx tmp16 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (16)); ++ rtx tmp17 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (24)); ++ rtx tmp18 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (32)); ++ rtx tmp19 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (40)); ++ rtx tmp26 = gen_rtx_MEM (Pmode, mem_address); ++ ++ emit_move_insn (tmp16, gen_rtx_REG (DImode, 16)); ++ emit_move_insn (tmp17, gen_rtx_REG (DImode, 17)); ++ emit_move_insn (tmp18, gen_rtx_REG (DImode, 18)); ++ emit_move_insn (tmp19, gen_rtx_REG (DImode, 19)); ++ emit_move_insn (tmp26, gen_rtx_REG (DImode, 26)); ++ ++ rtx tmp_clt = gen_rtx_REG (DImode, 7); ++ rtx tmp_cnt = gen_rtx_REG (DImode, 8); ++ rtx op = gen_rtx_REG (DImode, 17); ++ ++ unsigned long clt1, clt2, clt3; ++ unsigned long cnt1, cnt2, cnt3; ++ clt1 = flag_hardware_prefetch_clt % 2; ++ clt2 = (flag_hardware_prefetch_clt >> 1) % 2; ++ clt3 = (flag_hardware_prefetch_clt >> 2) % 2; ++ cnt1 = flag_hardware_prefetch_cnt_l1; ++ cnt2 = flag_hardware_prefetch_cnt_l2; ++ cnt3 = flag_hardware_prefetch_cnt_l3; ++ sw_64_emit_set_const (op, DImode, 0x10, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt1, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x11, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt2, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x12, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt3, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x1, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt1, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x4, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt2, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x8, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt3, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ emit_move_insn (gen_rtx_REG (DImode, 16), tmp16); ++ emit_move_insn (gen_rtx_REG (DImode, 17), tmp17); ++ emit_move_insn (gen_rtx_REG (DImode, 18), tmp18); ++ emit_move_insn (gen_rtx_REG (DImode, 19), tmp19); ++ emit_move_insn (gen_rtx_REG (DImode, 26), tmp26); ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (256))); ++ } ++ if (strcmp ("exit", lang_hooks.decl_printable_name (cfun->decl, 1)) == 0 ++ && flag_sw_hardware_prefetch_exit) ++ { ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-256))); ++ rtx mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (8)); ++ rtx tmp16 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (16)); ++ rtx tmp17 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (24)); ++ rtx tmp18 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (32)); ++ rtx tmp19 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (40)); ++ rtx tmp26 = gen_rtx_MEM (Pmode, mem_address); ++ ++ emit_move_insn (tmp16, gen_rtx_REG (DImode, 16)); ++ emit_move_insn (tmp17, gen_rtx_REG (DImode, 17)); ++ emit_move_insn (tmp18, gen_rtx_REG (DImode, 18)); ++ emit_move_insn (tmp19, gen_rtx_REG (DImode, 19)); ++ emit_move_insn (tmp26, gen_rtx_REG (DImode, 26)); ++ ++ rtx tmp_clt = gen_rtx_REG (DImode, 7); ++ rtx tmp_cnt = gen_rtx_REG (DImode, 8); ++ rtx op = gen_rtx_REG (DImode, 17); ++ ++ unsigned long clt1, clt2, clt3; ++ unsigned long cnt1, cnt2, cnt3; ++ clt1 = 1; ++ clt2 = 0; ++ clt3 = 1; ++ cnt1 = 0; ++ cnt2 = 0; ++ cnt3 = 5; ++ sw_64_emit_set_const (op, DImode, 0x10, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt1, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x11, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt2, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x12, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt3, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x1, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt1, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x4, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt2, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x8, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt3, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ emit_move_insn (gen_rtx_REG (DImode, 16), tmp16); ++ emit_move_insn (gen_rtx_REG (DImode, 17), tmp17); ++ emit_move_insn (gen_rtx_REG (DImode, 18), tmp18); ++ emit_move_insn (gen_rtx_REG (DImode, 19), tmp19); ++ emit_move_insn (gen_rtx_REG (DImode, 26), tmp26); ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (256))); ++ } ++ ++ /* Adjust the stack by the frame size. If the frame size is > 4096 ++ bytes, we need to be sure we probe somewhere in the first and last ++ 4096 bytes (we can probably get away without the latter test) and ++ every 8192 bytes in between. If the frame size is > 32768, we ++ do this in a loop. Otherwise, we generate the explicit probe ++ instructions. ++ ++ Note that we are only allowed to adjust sp once in the prologue. */ ++ ++ probed_size = frame_size; ++ if (flag_stack_check || flag_stack_clash_protection) ++ probed_size += get_stack_check_protect (); ++ ++ if (probed_size <= 32768) ++ { ++ if (probed_size > 4096) ++ { ++ int probed; ++ ++ for (probed = 4096; probed < probed_size; probed += 8192) ++ emit_insn (gen_stack_probe_internal (GEN_INT (-probed))); ++ ++ /* We only have to do this probe if we aren't saving registers or ++ if we are probing beyond the frame because of -fstack-check. */ ++ if ((sa_size == 0 && probed_size > probed - 4096) || flag_stack_check ++ || flag_stack_clash_protection) ++ emit_insn (gen_stack_probe_internal (GEN_INT (-probed_size))); ++ } ++ ++ if (frame_size != 0) ++ FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, ++ GEN_INT (-frame_size)))); ++ } ++ else ++ { ++ /* Here we generate code to set R22 to SP + 4096 and set R23 to the ++ number of 8192 byte blocks to probe. We then probe each block ++ in the loop and then set SP to the proper location. If the ++ amount remaining is > 4096, we have to do one more probe if we ++ are not saving any registers or if we are probing beyond the ++ frame because of -fstack-check. */ ++ ++ HOST_WIDE_INT blocks = (probed_size + 4096) / 8192; ++ HOST_WIDE_INT leftover = probed_size + 4096 - blocks * 8192; ++ rtx ptr = gen_rtx_REG (DImode, 22); ++ rtx count = gen_rtx_REG (DImode, 23); ++ rtx seq; ++ ++ emit_move_insn (count, GEN_INT (blocks)); ++ emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096))); ++ ++ /* Because of the difficulty in emitting a new basic block this ++ late in the compilation, generate the loop as a single insn. */ ++ emit_insn (gen_prologue_stack_probe_loop (count, ptr)); ++ ++ if ((leftover > 4096 && sa_size == 0) || flag_stack_check ++ || flag_stack_clash_protection) ++ { ++ rtx last ++ = gen_rtx_MEM (DImode, plus_constant (Pmode, ptr, -leftover)); ++ MEM_VOLATILE_P (last) = 1; ++ emit_move_insn (last, const0_rtx); ++ } ++ ++ if (flag_stack_check || flag_stack_clash_protection) ++ { ++ /* If -fstack-check is specified we have to load the entire ++ constant into a register and subtract from the sp in one go, ++ because the probed stack size is not equal to the frame size. */ ++ HOST_WIDE_INT lo, hi; ++ lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; ++ hi = frame_size - lo; ++ ++ emit_move_insn (ptr, GEN_INT (hi)); ++ emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo))); ++ seq = emit_insn ( ++ gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, ptr)); ++ } ++ else ++ { ++ seq = emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, ptr, GEN_INT (-leftover))); ++ } ++ ++ /* This alternative is special, because the DWARF code cannot ++ possibly intuit through the loop above. So we invent this ++ note it looks at instead. */ ++ RTX_FRAME_RELATED_P (seq) = 1; ++ add_reg_note (seq, REG_FRAME_RELATED_EXPR, ++ gen_rtx_SET (stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ -frame_size))); ++ } ++ ++ /* Cope with very large offsets to the register save area. */ ++ sa_bias = 0; ++ sa_reg = stack_pointer_rtx; ++ if (reg_offset + sa_size > 0x8000) ++ { ++ int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; ++ rtx sa_bias_rtx; ++ ++ if (low + sa_size <= 0x8000) ++ sa_bias = reg_offset - low, reg_offset = low; ++ else ++ sa_bias = reg_offset, reg_offset = 0; ++ ++ sa_reg = gen_rtx_REG (DImode, 24); ++ sa_bias_rtx = GEN_INT (sa_bias); ++ ++ if (add_operand (sa_bias_rtx, DImode)) ++ emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx)); ++ else ++ { ++ emit_move_insn (sa_reg, sa_bias_rtx); ++ emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg)); ++ } ++ } ++ ++ /* Save register RA next, followed by any other registers ++ that need to be saved. */ ++ for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi (sa_mask)) ++ { ++ /* if we need a frame pointer, set it from the stack pointer. */ ++ if (frame_pointer_needed && i != REG_RA && fp_flag == false) ++ { ++ emit_frame_store (HARD_FRAME_POINTER_REGNUM, sa_reg, sa_bias, ++ reg_offset); ++ sa_mask &= ~(HOST_WIDE_INT_1U << HARD_FRAME_POINTER_REGNUM); ++ reg_offset += 8; ++ fp_flag = true; ++ } ++ else ++ { ++ emit_frame_store (i, sa_reg, sa_bias, reg_offset); ++ reg_offset += 8; ++ sa_mask &= ~(HOST_WIDE_INT_1U << i); ++ } ++ } ++ ++ /* If we need a frame pointer, set it from the stack pointer. */ ++ if (frame_pointer_needed) ++ { ++ if (TARGET_CAN_FAULT_IN_PROLOGUE) ++ { ++ unsigned reg2 = 15; // FP ++ unsigned reg1 = 26; // R26 ++ long adj_size = SW_64_ROUND (crtl->outgoing_args_size); ++ if (adj_size > 0xFFFFFFFF) ++ { ++ int low = ((adj_size & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT bias; ++ ++ if (low <= 0x8000) ++ bias = adj_size - low, adj_size = low; ++ else ++ bias = adj_size, adj_size = 0; ++ ++ rtx fp_move; ++ rtx tmp_reg = gen_rtx_REG (DImode, 28); ++ rtx tmp = gen_int_mode (bias, DImode); ++ emit_move_insn (tmp_reg, tmp); ++ rtx adden = gen_movdi (tmp_reg, tmp); ++ ++ if (adj_size != 0) ++ fp_move = gen_adddi3 (hard_frame_pointer_rtx, ++ hard_frame_pointer_rtx, tmp_reg); ++ emit_insn (fp_move); ++ } ++ else if (adj_size > 0x8000) ++ { ++ int low = ((adj_size & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT bias; ++ ++ if (low <= 0x8000) ++ bias = adj_size - low, adj_size = low; ++ else ++ bias = adj_size, adj_size = 0; ++ ++ rtx fp_move; ++ rtx sa_reg_exp ++ = plus_constant (Pmode, stack_pointer_rtx, bias); ++ emit_move_insn (hard_frame_pointer_rtx, sa_reg_exp); ++ if (adj_size != 0) ++ fp_move ++ = gen_adddi3 (hard_frame_pointer_rtx, ++ hard_frame_pointer_rtx, GEN_INT (adj_size)); ++ ++ if ((void *) fp_move == NULL) ++ printf ("unable gen add3"); ++ emit_insn (fp_move); ++ } ++ else ++ { ++ rtx fp_move ++ = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx, ++ GEN_INT ( ++ SW_64_ROUND (crtl->outgoing_args_size))); ++ FRP (emit_insn (fp_move)); ++ } ++ rtx_insn *insn = get_last_insn (); ++ if (!find_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX)) ++ { ++ rtx src ++ = plus_constant (Pmode, stack_pointer_rtx, ++ SW_64_ROUND (crtl->outgoing_args_size)); ++ add_reg_note (insn, REG_CFA_ADJUST_CFA, ++ gen_rtx_SET (hard_frame_pointer_rtx, src)); ++ } ++ ++ emit_insn ( ++ gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); ++ } ++ else ++ /* This must always be the last instruction in the ++ prologue, thus we emit a special move + clobber. */ ++ FRP (emit_insn ( ++ gen_init_fp (hard_frame_pointer_rtx, stack_pointer_rtx, sa_reg))); ++ } ++ ++ /* The ABIs for VMS and SYSV say that while we can schedule insns into ++ the prologue, for exception handling reasons, we cannot do this for ++ any insn that might fault. We could prevent this for mems with a ++ (clobber:BLK (scratch)), but this doesn't work for fp insns. So we ++ have to prevent all such scheduling with a blockage. ++ ++ Linux, on the other hand, never bothered to implement SYSV's ++ exception handling, and so doesn't care about such things. Anyone ++ planning to use dwarf2 frame-unwind info can also omit the blockage. */ ++ ++ if (!TARGET_CAN_FAULT_IN_PROLOGUE) ++ emit_insn (gen_blockage ()); ++} ++ ++/* Count the number of .file directives, so that .loc is up to date. */ ++int num_source_filenames = 0; ++ ++/* Output the textual info surrounding the prologue. */ ++ ++void ++sw_64_start_function (FILE *file, const char *fnname, ++ tree decl ATTRIBUTE_UNUSED) ++{ ++ unsigned long imask, fmask; ++ /* Complete stack size needed. */ ++ HOST_WIDE_INT frame_size = cfun->machine->frame.frame_size; ++ /* The maximum debuggable frame size. */ ++ const HOST_WIDE_INT max_frame_size = HOST_WIDE_INT_1 << 31; ++ /* Offset from base reg to register save area. */ ++ HOST_WIDE_INT reg_offset; ++ char *entry_label = (char *) alloca (strlen (fnname) + 6); ++ char *tramp_label = (char *) alloca (strlen (fnname) + 6); ++ int i; ++ ++ sw_64_fnname = fnname; ++ const char *main = "main"; ++ if (flag_fpcr_set == 4 && strcmp (fnname, main) == 0) ++ stfp3_flag = 1; ++ else ++ stfp3_flag = 0; ++ ++ reg_offset = SW_64_ROUND (crtl->outgoing_args_size); ++ ++ imask = cfun->machine->frame.sa_mask & 0xffffffffu; ++ fmask = cfun->machine->frame.sa_mask >> 32; ++ /* Issue function start and label. */ ++ if (!flag_inhibit_size_directive) ++ { ++ fputs ("\t.ent ", file); ++ assemble_name (file, fnname); ++ putc ('\n', file); ++ ++ /* If the function needs GP, we'll write the "..ng" label there. ++ Otherwise, do it here. */ ++ if (!sw_64_function_needs_gp && !cfun->is_thunk) ++ { ++ putc ('$', file); ++ assemble_name (file, fnname); ++ fputs ("..ng:\n", file); ++ } ++ } ++ /* Nested functions on VMS that are potentially called via trampoline ++ get a special transfer entry point that loads the called functions ++ procedure descriptor and static chain. */ ++ strcpy (entry_label, fnname); ++ ++ ASM_OUTPUT_LABEL (file, entry_label); ++ inside_function = TRUE; ++ ++ if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive) ++ { ++ /* Set flags in procedure descriptor to request IEEE-conformant ++ math-library routines. The value we set it to is PDSC_EXC_IEEE ++ (/usr/include/pdsc.h). */ ++ fputs ("\t.eflag 48\n", file); ++ } ++ ++ /* Set up offsets to sw_64 virtual arg/local debugging pointer. */ ++ sw_64_auto_offset = -frame_size + cfun->machine->frame.saved_varargs_size ++ + crtl->args.pretend_args_size; ++ sw_64_arg_offset = -frame_size + 48; ++ ++ /* Describe our frame. If the frame size is larger than an integer, ++ print it as zero to avoid an assembler error. We won't be ++ properly describing such a frame, but that's the best we can do. */ ++ if (!flag_inhibit_size_directive) ++ fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n", ++ (frame_pointer_needed ? HARD_FRAME_POINTER_REGNUM ++ : STACK_POINTER_REGNUM), ++ frame_size >= max_frame_size ? 0 : frame_size, ++ crtl->args.pretend_args_size); ++ ++ /* Describe which registers were spilled. */ ++ if (!flag_inhibit_size_directive) ++ { ++ if (imask) ++ { ++ fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask, ++ frame_size >= max_frame_size ? 0 : reg_offset - frame_size); ++ ++ for (i = 0; i < 32; ++i) ++ if (imask & (1UL << i)) ++ reg_offset += 8; ++ } ++ ++ if (fmask) ++ fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask, ++ frame_size >= max_frame_size ? 0 : reg_offset - frame_size); ++ } ++} ++ ++/* Emit the .prologue note at the scheduled end of the prologue. */ ++ ++static void ++sw_64_output_function_end_prologue (FILE *file) ++{ ++ if (!flag_inhibit_size_directive) ++ fprintf (file, "\t.prologue %d\n", ++ sw_64_function_needs_gp || cfun->is_thunk); ++} ++ ++/* Write function epilogue. */ ++ ++void ++sw_64_expand_epilogue (void) ++{ ++ /* Registers to save. */ ++ unsigned HOST_WIDE_INT sa_mask = cfun->machine->frame.sa_mask; ++ /* Stack space needed for pushing registers clobbered by us. */ ++ HOST_WIDE_INT sa_size = cfun->machine->frame.saved_regs_size; ++ /* Complete stack size needed. */ ++ HOST_WIDE_INT frame_size = cfun->machine->frame.frame_size; ++ /* Offset from base reg to register save area. */ ++ HOST_WIDE_INT reg_offset; ++ int fp_is_frame_pointer, fp_offset; ++ rtx sa_reg, sa_reg_exp = NULL; ++ rtx sp_adj1, sp_adj2, mem, reg, insn; ++ rtx eh_ofs; ++ rtx cfa_restores = NULL_RTX; ++ bool fp_flag = false; ++ ++#ifdef SW_64_ENABLE_FULL_ASAN ++ reg_offset = aligned_upper_bound (crtl->outgoing_args_size, ++ STACK_BOUNDARY / BITS_PER_UNIT); ++#else ++ reg_offset = SW_64_ROUND (crtl->outgoing_args_size); ++#endif ++ ++ if (strcmp ("main", lang_hooks.decl_printable_name (cfun->decl, 1)) == 0 ++ && flag_sw_hardware_prefetch) ++ { ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-256))); ++ rtx mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (8)); ++ rtx tmp16 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (16)); ++ rtx tmp17 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (24)); ++ rtx tmp18 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (32)); ++ rtx tmp19 = gen_rtx_MEM (Pmode, mem_address); ++ mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (40)); ++ rtx tmp26 = gen_rtx_MEM (Pmode, mem_address); ++ ++ emit_move_insn (tmp16, gen_rtx_REG (DImode, 16)); ++ emit_move_insn (tmp17, gen_rtx_REG (DImode, 17)); ++ emit_move_insn (tmp18, gen_rtx_REG (DImode, 18)); ++ emit_move_insn (tmp19, gen_rtx_REG (DImode, 19)); ++ emit_move_insn (tmp26, gen_rtx_REG (DImode, 26)); ++ ++ rtx tmp_clt = gen_rtx_REG (DImode, 7); ++ rtx tmp_cnt = gen_rtx_REG (DImode, 8); ++ rtx op = gen_rtx_REG (DImode, 17); ++ ++ unsigned long clt1, clt2, clt3; ++ unsigned long cnt1, cnt2, cnt3; ++ clt1 = 1; ++ clt2 = 0; ++ clt3 = 1; ++ cnt1 = 0; ++ cnt2 = 0; ++ cnt3 = 5; ++ sw_64_emit_set_const (op, DImode, 0x10, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt1, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x11, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt2, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x12, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, clt3, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x1, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt1, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x4, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt2, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ sw_64_emit_set_const (op, DImode, 0x8, 3, false); ++ sw_64_emit_set_const (tmp_clt, DImode, cnt3, 3, false); ++ emit_insn (gen_hardware_prefetch_use_syscall (tmp_clt, op)); ++ ++ emit_move_insn (gen_rtx_REG (DImode, 16), tmp16); ++ emit_move_insn (gen_rtx_REG (DImode, 17), tmp17); ++ emit_move_insn (gen_rtx_REG (DImode, 18), tmp18); ++ emit_move_insn (gen_rtx_REG (DImode, 19), tmp19); ++ emit_move_insn (gen_rtx_REG (DImode, 26), tmp26); ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (256))); ++ } ++ ++ fp_is_frame_pointer = frame_pointer_needed; ++ fp_offset = 0; ++ sa_reg = stack_pointer_rtx; ++ ++ if (crtl->calls_eh_return) ++ eh_ofs = EH_RETURN_STACKADJ_RTX; ++ else ++ eh_ofs = NULL_RTX; ++ ++ if (sa_size) ++ { ++ /* If we have a frame pointer, restore SP from it. */ ++ if (frame_pointer_needed) ++ { ++ long adj_size = SW_64_ROUND (crtl->outgoing_args_size); ++ if (adj_size > 0xFFFFFFFF) ++ { ++ int low = ((adj_size & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT bias; ++ ++ if (low <= 0x8000) ++ bias = adj_size - low, adj_size = low; ++ else ++ bias = adj_size, adj_size = 0; ++ ++ rtx sa_reg = stack_pointer_rtx; ++ rtx tmp_reg = gen_rtx_REG (DImode, 28); ++ rtx tmp = gen_int_mode (bias, DImode); ++ emit_move_insn (tmp_reg, tmp); ++ rtx adden = gen_movdi (tmp_reg, tmp); ++ sa_reg_exp = gen_adddi3 (sa_reg, hard_frame_pointer_rtx, tmp_reg); ++ emit_insn (sa_reg_exp); ++ if (adj_size != 0) ++ emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, ++ GEN_INT (-adj_size))); ++ } ++ else if (adj_size > 0x8000) ++ { ++ int low = ((adj_size & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT bias; ++ ++ if (low <= 0x8000) ++ bias = adj_size - low, adj_size = low; ++ else ++ bias = adj_size, adj_size = 0; ++ ++ rtx sa_reg = stack_pointer_rtx; ++ rtx sa_reg_exp ++ = plus_constant (Pmode, hard_frame_pointer_rtx, -bias); ++ emit_move_insn (sa_reg, sa_reg_exp); ++ if (adj_size != 0) ++ emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, ++ GEN_INT (-adj_size))); ++ } ++ else ++ { ++ emit_insn ( ++ gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); ++ rtx insn ++ = gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, ++ GEN_INT ( ++ -SW_64_ROUND (crtl->outgoing_args_size))); ++ emit_insn (insn); ++ } ++ } ++ // emit_move_insn (stack_pointer_rtx, ++ //hard_frame_pointer_rtx); ++ ++ /* Cope with very large offsets to the register save area. */ ++ if (reg_offset + sa_size > 0x7FFFFFFFFFFFUL) ++ { ++ int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT bias; ++ ++ if (low + sa_size <= 0x8000) ++ bias = reg_offset - low, reg_offset = low; ++ else ++ bias = reg_offset, reg_offset = 0; ++ ++ sa_reg = gen_rtx_REG (DImode, 22); ++ rtx tmp_reg = gen_rtx_REG (DImode, 28); ++ rtx tmp = gen_int_mode (bias, DImode); ++ emit_move_insn (tmp_reg, tmp); ++ rtx adden = gen_movdi (tmp_reg, tmp); ++ sa_reg_exp = gen_adddi3 (sa_reg, stack_pointer_rtx, tmp_reg); ++ ++ emit_insn (sa_reg_exp); ++ } ++ else if (reg_offset + sa_size > 0x8000) ++ { ++ int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000; ++ HOST_WIDE_INT bias; ++ ++ if (low + sa_size <= 0x8000) ++ bias = reg_offset - low, reg_offset = low; ++ else ++ bias = reg_offset, reg_offset = 0; ++ ++ sa_reg = gen_rtx_REG (DImode, 22); ++ sa_reg_exp = plus_constant (Pmode, stack_pointer_rtx, bias); ++ ++ emit_move_insn (sa_reg, sa_reg_exp); ++ } ++ ++ /* Restore registers in order, excepting a true frame pointer. */ ++ for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi (sa_mask)) ++ { ++ if (fp_is_frame_pointer && i != REG_RA && fp_flag == false) ++ { ++ emit_insn (gen_blockage ()); ++ mem = gen_frame_mem (DImode, ++ plus_constant (Pmode, sa_reg, reg_offset)); ++ emit_move_insn (hard_frame_pointer_rtx, mem); ++ cfa_restores ++ = alloc_reg_note (REG_CFA_RESTORE, hard_frame_pointer_rtx, ++ cfa_restores); ++ sa_mask &= ~(1UL << HARD_FRAME_POINTER_REGNUM); ++ reg_offset += 8; ++ fp_offset = reg_offset; ++ fp_flag = true; ++ } ++ else ++ { ++ mem = gen_frame_mem (DImode, ++ plus_constant (Pmode, sa_reg, reg_offset)); ++ reg = gen_rtx_REG (DImode, i); ++ emit_move_insn (reg, mem); ++ cfa_restores ++ = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); ++ reg_offset += 8; ++ sa_mask &= ~(HOST_WIDE_INT_1U << i); ++ } ++ } ++ } ++ ++ if (frame_size || eh_ofs) ++ { ++ sp_adj1 = stack_pointer_rtx; ++ ++ if (eh_ofs) ++ { ++ sp_adj1 = gen_rtx_REG (DImode, 23); ++ emit_move_insn (sp_adj1, ++ gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs)); ++ } ++ ++ /* If the stack size is large, begin computation into a temporary ++ register so as not to interfere with a potential fp restore, ++ which must be consecutive with an SP restore. */ ++ if (frame_size < 32768 && !cfun->calls_alloca) ++ sp_adj2 = GEN_INT (frame_size); ++ else if (frame_size < 0x40007fffL) ++ { ++ int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; ++ ++ sp_adj2 = plus_constant (Pmode, sp_adj1, frame_size - low); ++ if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2)) ++ sp_adj1 = sa_reg; ++ else ++ { ++ sp_adj1 = gen_rtx_REG (DImode, 23); ++ emit_move_insn (sp_adj1, sp_adj2); ++ } ++ sp_adj2 = GEN_INT (low); ++ } ++ else ++ { ++ rtx tmp = gen_rtx_REG (DImode, 23); ++ sp_adj2 = sw_64_emit_set_const (tmp, DImode, frame_size, 3, false); ++ if (!sp_adj2) ++ { ++ /* We can't drop new things to memory this late, afaik, ++ so build it up by pieces. */ ++ sp_adj2 = sw_64_emit_set_long_const (tmp, frame_size); ++ gcc_assert (sp_adj2); ++ } ++ } ++ ++ /* Restore the stack pointer. */ ++ emit_insn (gen_blockage ()); ++ if (sp_adj2 == const0_rtx) ++ insn = emit_move_insn (stack_pointer_rtx, sp_adj1); ++ else ++ insn = emit_move_insn (stack_pointer_rtx, ++ gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)); ++ REG_NOTES (insn) = cfa_restores; ++ add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ } ++ else ++ { ++ gcc_assert (cfa_restores == NULL); ++ } ++ if (strcmp ("main", lang_hooks.decl_printable_name (cfun->decl, 1)) == 0 ++ && (TARGET_SW_32ALIGN || TARGET_SW_SIMD)) ++ { ++ rtx mem_address = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (0)); ++ rtx tmp7 = gen_rtx_MEM (Pmode, mem_address); ++ emit_move_insn (gen_rtx_REG (DImode, 7), tmp7); ++ rtx const16 = gen_rtx_REG (DImode, 7); ++ emit_insn ( ++ gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (32))); ++ emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, const16)); ++ } ++} ++ ++/* Output the rest of the textual info surrounding the epilogue. */ ++ ++void ++sw_64_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED) ++{ ++ rtx_insn *insn; ++ ++ /* We output a nop after noreturn calls at the very end of the function to ++ ensure that the return address always remains in the caller's code range, ++ as not doing so might confuse unwinding engines. */ ++ insn = get_last_insn (); ++ if (!INSN_P (insn)) ++ insn = prev_active_insn (insn); ++ if (insn && CALL_P (insn)) ++ output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL); ++ ++ /* End the function. */ ++ if (!flag_inhibit_size_directive) ++ { ++ fputs ("\t.end ", file); ++ assemble_name (file, fnname); ++ putc ('\n', file); ++ } ++ inside_function = FALSE; ++} ++ ++/* Emit a tail call to FUNCTION after adjusting THIS by DELTA. ++ ++ In order to avoid the hordes of differences between generated code ++ with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating ++ lots of code loading up large constants, generate rtl and emit it ++ instead of going straight to text. ++ ++ Not sure why this idea hasn't been explored before... */ ++ ++static void ++sw_64_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, ++ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, ++ tree function) ++{ ++ const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); ++ HOST_WIDE_INT hi, lo; ++ rtx this_rtx, funexp; ++ rtx_insn *insn; ++ ++ /* We always require a valid GP. */ ++ emit_insn (gen_prologue_ldgp ()); ++ emit_note (NOTE_INSN_PROLOGUE_END); ++ ++ /* Find the "this" pointer. If the function returns a structure, ++ the structure return pointer is in $16. */ ++ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) ++ this_rtx = gen_rtx_REG (Pmode, 17); ++ else ++ this_rtx = gen_rtx_REG (Pmode, 16); ++ ++ /* Add DELTA. When possible we use ldih+ldi. Otherwise load the ++ entire constant for the add. */ ++ lo = ((delta & 0xffff) ^ 0x8000) - 0x8000; ++ hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ if (hi + lo == delta) ++ { ++ if (hi) ++ emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi))); ++ if (lo) ++ emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo))); ++ } ++ else ++ { ++ rtx tmp = sw_64_emit_set_long_const (gen_rtx_REG (Pmode, 0), delta); ++ emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp)); ++ } ++ ++ /* Add a delta stored in the vtable at VCALL_OFFSET. */ ++ if (vcall_offset) ++ { ++ rtx tmp, tmp2; ++ ++ tmp = gen_rtx_REG (Pmode, 0); ++ emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx)); ++ ++ lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000; ++ hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000; ++ if (hi + lo == vcall_offset) ++ { ++ if (hi) ++ emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi))); ++ } ++ else ++ { ++ tmp2 ++ = sw_64_emit_set_long_const (gen_rtx_REG (Pmode, 1), vcall_offset); ++ emit_insn (gen_adddi3 (tmp, tmp, tmp2)); ++ lo = 0; ++ } ++ if (lo) ++ tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo)); ++ else ++ tmp2 = tmp; ++ emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2)); ++ ++ emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp)); ++ } ++ ++ /* Generate a tail call to the target function. */ ++ if (!TREE_USED (function)) ++ { ++ assemble_external (function); ++ TREE_USED (function) = 1; ++ } ++ funexp = XEXP (DECL_RTL (function), 0); ++ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp); ++ insn = emit_call_insn (gen_sibcall (funexp, const0_rtx)); ++ SIBLING_CALL_P (insn) = 1; ++ ++ /* Run just enough of rest_of_compilation to get the insns emitted. ++ There's not really enough bulk here to make other passes such as ++ instruction scheduling worth while. */ ++ insn = get_insns (); ++ shorten_branches (insn); ++ assemble_start_function (thunk_fndecl, fnname); ++ final_start_function (insn, file, 1); ++ final (insn, file, 1); ++ final_end_function (); ++ assemble_end_function (thunk_fndecl, fnname); ++} ++ ++/* Name of the file containing the current function. */ ++ ++static const char *current_function_file = ""; ++ ++/* Offsets to sw_64 virtual arg/local debugging pointers. */ ++ ++long sw_64_arg_offset; ++long sw_64_auto_offset; ++ ++/* Emit a new filename to a stream. */ ++ ++void ++sw_64_output_filename (FILE *stream, const char *name) ++{ ++ static int first_time = TRUE; ++ ++ if (first_time) ++ { ++ first_time = FALSE; ++ ++num_source_filenames; ++ current_function_file = name; ++ fprintf (stream, "\t.file\t "); ++ output_quoted_string (stream, name); ++ fprintf (stream, "\n"); ++ } ++ ++ else if (name != current_function_file ++ && strcmp (name, current_function_file) != 0) ++ { ++ ++num_source_filenames; ++ current_function_file = name; ++ fprintf (stream, "\t.file\t "); ++ ++ output_quoted_string (stream, name); ++ fprintf (stream, "\n"); ++ } ++} ++ ++/* Structure to show the current status of registers and memory. */ ++ ++struct shadow_summary ++{ ++ struct ++ { ++ unsigned int i : 31; /* Mask of int regs */ ++ unsigned int fp : 31; /* Mask of fp regs */ ++ unsigned int mem : 1; /* mem == imem | fpmem */ ++ } used, defd; ++}; ++ ++/* Summary the effects of expression X on the machine. Update SUM, a pointer ++ to the summary structure. SET is nonzero if the insn is setting the ++ object, otherwise zero. */ ++ ++static void ++summarize_insn (rtx x, struct shadow_summary *sum, int set) ++{ ++ const char *format_ptr; ++ int i, j; ++ ++ if (x == 0) ++ return; ++ ++ switch (GET_CODE (x)) ++ { ++ /* ??? Note that this case would be incorrect if the Sw_64 had a ++ ZERO_EXTRACT in SET_DEST. */ ++ case SET: ++ summarize_insn (SET_SRC (x), sum, 0); ++ summarize_insn (SET_DEST (x), sum, 1); ++ break; ++ ++ case CLOBBER: ++ summarize_insn (XEXP (x, 0), sum, 1); ++ break; ++ ++ case USE: ++ summarize_insn (XEXP (x, 0), sum, 0); ++ break; ++ ++ case ASM_OPERANDS: ++ for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) ++ summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0); ++ break; ++ ++ case PARALLEL: ++ for (i = XVECLEN (x, 0) - 1; i >= 0; i--) ++ summarize_insn (XVECEXP (x, 0, i), sum, 0); ++ break; ++ ++ case SUBREG: ++ summarize_insn (SUBREG_REG (x), sum, 0); ++ break; ++ ++ case REG: { ++ int regno = REGNO (x); ++ unsigned long mask = ((unsigned long) 1) << (regno % 32); ++ ++ if (regno == 31 || regno == 63) ++ break; ++ ++ if (set) ++ { ++ if (regno < 32) ++ sum->defd.i |= mask; ++ else ++ sum->defd.fp |= mask; ++ } ++ else ++ { ++ if (regno < 32) ++ sum->used.i |= mask; ++ else ++ sum->used.fp |= mask; ++ } ++ } ++ break; ++ ++ case MEM: ++ if (set) ++ sum->defd.mem = 1; ++ else ++ sum->used.mem = 1; ++ ++ /* Find the regs used in memory address computation: */ ++ summarize_insn (XEXP (x, 0), sum, 0); ++ break; ++ ++ case CONST_INT: ++ case CONST_WIDE_INT: ++ case CONST_DOUBLE: ++ case SYMBOL_REF: ++ case LABEL_REF: ++ case CONST: ++ case SCRATCH: ++ case ASM_INPUT: ++ break; ++ ++ /* Handle common unary and binary ops for efficiency. */ ++ case COMPARE: ++ case PLUS: ++ case MINUS: ++ case MULT: ++ case DIV: ++ case MOD: ++ case UDIV: ++ case UMOD: ++ case AND: ++ case IOR: ++ case XOR: ++ case ASHIFT: ++ case ROTATE: ++ case ASHIFTRT: ++ case LSHIFTRT: ++ case ROTATERT: ++ case SMIN: ++ case SMAX: ++ case UMIN: ++ case UMAX: ++ case NE: ++ case EQ: ++ case GE: ++ case GT: ++ case LE: ++ case LT: ++ case GEU: ++ case GTU: ++ case LEU: ++ case LTU: ++ summarize_insn (XEXP (x, 0), sum, 0); ++ summarize_insn (XEXP (x, 1), sum, 0); ++ break; ++ ++ case NEG: ++ case NOT: ++ case SIGN_EXTEND: ++ case ZERO_EXTEND: ++ case TRUNCATE: ++ case FLOAT_EXTEND: ++ case FLOAT_TRUNCATE: ++ case FLOAT: ++ case FIX: ++ case UNSIGNED_FLOAT: ++ case UNSIGNED_FIX: ++ case ABS: ++ case SQRT: ++ case FFS: ++ summarize_insn (XEXP (x, 0), sum, 0); ++ break; ++ ++ default: ++ format_ptr = GET_RTX_FORMAT (GET_CODE (x)); ++ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) ++ switch (format_ptr[i]) ++ { ++ case 'e': ++ summarize_insn (XEXP (x, i), sum, 0); ++ break; ++ ++ case 'E': ++ for (j = XVECLEN (x, i) - 1; j >= 0; j--) ++ summarize_insn (XVECEXP (x, i, j), sum, 0); ++ break; ++ ++ case 'i': ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ } ++} ++ ++/* Ensure a sufficient number of `memb' insns are in the code when ++ the user requests code with a trap precision of functions or ++ instructions. ++ ++ In naive mode, when the user requests a trap-precision of ++ "instruction", a memb is needed after every instruction that may ++ generate a trap. This ensures that the code is resumption safe but ++ it is also slow. ++ ++ When optimizations are turned on, we delay issuing a memb as long ++ as possible. In this context, a trap shadow is the sequence of ++ instructions that starts with a (potentially) trap generating ++ instruction and extends to the next memb. We can delay (and ++ therefore sometimes omit) a memb subject to the following ++conditions: ++ ++(a) On entry to the trap shadow, if any Sw_64 register or memory ++location contains a value that is used as an operand value by some ++instruction in the trap shadow (live on entry), then no instruction ++in the trap shadow may modify the register or memory location. ++ ++(b) Within the trap shadow, the computation of the base register ++for a memory load or store instruction may not involve using the ++result of an instruction that might generate an UNPREDICTABLE ++result. ++ ++(c) Within the trap shadow, no register may be used more than once ++as a destination register. (This is to make life easier for the ++trap-handler.) ++ ++(d) The trap shadow may not include any branch instructions. */ ++ ++static void ++sw_64_handle_trap_shadows (void) ++{ ++ struct shadow_summary shadow; ++ int trap_pending, exception_nesting; ++ rtx_insn *i, *n; ++ ++ trap_pending = 0; ++ exception_nesting = 0; ++ shadow.used.i = 0; ++ shadow.used.fp = 0; ++ shadow.used.mem = 0; ++ shadow.defd = shadow.used; ++ ++ for (i = get_insns (); i; i = NEXT_INSN (i)) ++ { ++ if (NOTE_P (i)) ++ { ++ switch (NOTE_KIND (i)) ++ { ++ case NOTE_INSN_EH_REGION_BEG: ++ exception_nesting++; ++ if (trap_pending) ++ goto close_shadow; ++ break; ++ ++ case NOTE_INSN_EH_REGION_END: ++ exception_nesting--; ++ if (trap_pending) ++ goto close_shadow; ++ break; ++ ++ case NOTE_INSN_EPILOGUE_BEG: ++ if (trap_pending && sw_64_tp >= SW_64_TP_FUNC) ++ goto close_shadow; ++ break; ++ } ++ } ++ else if (trap_pending) ++ { ++ if (sw_64_tp == SW_64_TP_FUNC) ++ { ++ if (JUMP_P (i) && GET_CODE (PATTERN (i)) == RETURN) ++ goto close_shadow; ++ } ++ else if (sw_64_tp == SW_64_TP_INSN) ++ { ++ if (optimize > 0) ++ { ++ struct shadow_summary sum; ++ ++ sum.used.i = 0; ++ sum.used.fp = 0; ++ sum.used.mem = 0; ++ sum.defd = sum.used; ++ ++ switch (GET_CODE (i)) ++ { ++ case INSN: ++ /* Annoyingly, get_attr_trap will die on these. */ ++ if (GET_CODE (PATTERN (i)) == USE ++ || GET_CODE (PATTERN (i)) == CLOBBER) ++ break; ++ ++ summarize_insn (PATTERN (i), &sum, 0); ++ ++ if ((sum.defd.i & shadow.defd.i) ++ || (sum.defd.fp & shadow.defd.fp)) ++ { ++ /* (c) would be violated */ ++ goto close_shadow; ++ } ++ ++ /* Combine shadow with summary of current insn: */ ++ shadow.used.i |= sum.used.i; ++ shadow.used.fp |= sum.used.fp; ++ shadow.used.mem |= sum.used.mem; ++ shadow.defd.i |= sum.defd.i; ++ shadow.defd.fp |= sum.defd.fp; ++ shadow.defd.mem |= sum.defd.mem; ++ ++ if ((sum.defd.i & shadow.used.i) ++ || (sum.defd.fp & shadow.used.fp) ++ || (sum.defd.mem & shadow.used.mem)) ++ { ++ /* (a) would be violated (also takes care of (b)) */ ++ gcc_assert (get_attr_trap (i) != TRAP_YES ++ || (!(sum.defd.i & sum.used.i) ++ && !(sum.defd.fp & sum.used.fp))); ++ ++ goto close_shadow; ++ } ++ break; ++ ++ case BARRIER: ++ /* __builtin_unreachable can expand to no code at all, ++ leaving (barrier) RTXes in the instruction stream. */ ++ goto close_shadow_notrapb; ++ ++ case JUMP_INSN: ++ case CALL_INSN: ++ case CODE_LABEL: ++ goto close_shadow; ++ ++ case DEBUG_INSN: ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ } ++ else ++ { ++ close_shadow: ++ n = emit_insn_before (gen_trapb (), i); ++ PUT_MODE (n, TImode); ++ PUT_MODE (i, TImode); ++ close_shadow_notrapb: ++ trap_pending = 0; ++ shadow.used.i = 0; ++ shadow.used.fp = 0; ++ shadow.used.mem = 0; ++ shadow.defd = shadow.used; ++ } ++ } ++ } ++ ++ if ((exception_nesting > 0 || sw_64_tp >= SW_64_TP_FUNC) ++ && NONJUMP_INSN_P (i) && GET_CODE (PATTERN (i)) != USE ++ && GET_CODE (PATTERN (i)) != CLOBBER && get_attr_trap (i) == TRAP_YES) ++ { ++ if (optimize && !trap_pending) ++ summarize_insn (PATTERN (i), &shadow, 0); ++ trap_pending = 1; ++ } ++ } ++} ++ ++/* Sw_64 can only issue instruction groups simultaneously if they are ++ suitably aligned. This is very processor-specific. */ ++ ++/* The instruction group alignment main loop. */ ++ ++static void ++sw_64_align_insns_1 (unsigned int max_align, ++ rtx_insn *(*next_group) (rtx_insn *, int *, int *), ++ rtx (*next_nop) (int *)) ++{ ++ /* ALIGN is the known alignment for the insn group. */ ++ unsigned int align; ++ /* OFS is the offset of the current insn in the insn group. */ ++ int ofs; ++ int prev_in_use, in_use, len, ldgp; ++ rtx_insn *i, *next; ++ ++ /* Let shorten branches care for assigning alignments to code labels. */ ++ shorten_branches (get_insns ()); ++ ++ unsigned int option_alignment = align_functions.levels[0].get_value (); ++ if (option_alignment < 4) ++ align = 4; ++ else if ((unsigned int) option_alignment < max_align) ++ align = option_alignment; ++ else ++ align = max_align; ++ ++ ofs = prev_in_use = 0; ++ i = get_insns (); ++ if (NOTE_P (i)) ++ i = next_nonnote_insn (i); ++ ++ ldgp = sw_64_function_needs_gp ? 8 : 0; ++ ++ while (i) ++ { ++ next = (*next_group) (i, &in_use, &len); ++ ++ /* When we see a label, resync alignment etc. */ ++ if (LABEL_P (i)) ++ { ++ unsigned int new_align ++ = label_to_alignment (i).levels[0].get_value (); ++ if (new_align >= align) ++ { ++ align = new_align < max_align ? new_align : max_align; ++ ofs = 0; ++ } ++ ++ else if (ofs & (new_align - 1)) ++ ofs = (ofs | (new_align - 1)) + 1; ++ gcc_assert (!len); ++ } ++ ++ /* Handle complex instructions special. */ ++ else if (in_use == 0) ++ { ++ /* Asms will have length < 0. This is a signal that we have ++ lost alignment knowledge. Assume, however, that the asm ++ will not mis-align instructions. */ ++ if (len < 0) ++ { ++ ofs = 0; ++ align = 4; ++ len = 0; ++ } ++ } ++ ++ /* If the known alignment is smaller than the recognized insn group, ++ realign the output. */ ++ else if ((int) align < len) ++ { ++ unsigned int new_log_align = len > 8 ? 4 : 3; ++ rtx_insn *prev, *where; ++ ++ where = prev = prev_nonnote_insn (i); ++ if (!where || !LABEL_P (where)) ++ where = i; ++ ++ /* Can't realign between a call and its gp reload. */ ++ if (!(TARGET_EXPLICIT_RELOCS && prev && CALL_P (prev))) ++ { ++ emit_insn_before (gen_realign (GEN_INT (new_log_align)), where); ++ align = 1 << new_log_align; ++ ofs = 0; ++ } ++ } ++ ++ /* We may not insert padding inside the initial ldgp sequence. */ ++ else if (ldgp > 0) ++ ldgp -= len; ++ ++ /* If the group won't fit in the same INT16 as the previous, ++ we need to add padding to keep the group together. Rather ++ than simply leaving the insn filling to the assembler, we ++ can make use of the knowledge of what sorts of instructions ++ were issued in the previous group to make sure that all of ++ the added nops are really free. */ ++ else if (ofs + len > (int) align) ++ { ++ int nop_count = (align - ofs) / 4; ++ rtx_insn *where; ++ ++ /* Insert nops before labels, branches, and calls to truly merge ++ the execution of the nops with the previous instruction group. */ ++ where = prev_nonnote_insn (i); ++ if (where) ++ { ++ if (LABEL_P (where)) ++ { ++ rtx_insn *where2 = prev_nonnote_insn (where); ++ if (where2 && JUMP_P (where2)) ++ where = where2; ++ } ++ else if (NONJUMP_INSN_P (where)) ++ where = i; ++ } ++ else ++ where = i; ++ ++ do ++ emit_insn_before ((*next_nop) (&prev_in_use), where); ++ while (--nop_count); ++ ofs = 0; ++ } ++ ++ ofs = (ofs + len) & (align - 1); ++ prev_in_use = in_use; ++ i = next; ++ } ++} ++ ++static void ++sw_64_align_insns (void) ++{ ++ gcc_unreachable (); ++} ++ ++/* Insert an unop between sibcall or noreturn function call and GP load. */ ++ ++static void ++sw_64_pad_function_end (void) ++{ ++ rtx_insn *insn, *next; ++ ++ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) ++ { ++ if (!CALL_P (insn) ++ || !(SIBLING_CALL_P (insn) ++ || find_reg_note (insn, REG_NORETURN, NULL_RTX))) ++ continue; ++ ++ next = next_active_insn (insn); ++ if (next) ++ { ++ rtx pat = PATTERN (next); ++ ++ if (GET_CODE (pat) == SET ++ && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE ++ && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1) ++ emit_insn_after (gen_unop (), insn); ++ } ++ } ++} ++ ++/* Machine dependent reorg pass. */ ++ ++static void ++sw_64_reorg (void) ++{ ++ /* Workaround for a linker error that triggers when an exception ++ handler immediatelly follows a sibcall or a noreturn function. ++ ++ In the sibcall case: ++ ++ The instruction stream from an object file: ++ ++1d8: 00 00 fb 6b jmp (t12) ++1dc: 00 00 ba 27 ldih gp,0(ra) ++1e0: 00 00 bd 23 ldi gp,0(gp) ++1e4: 00 00 7d a7 ldl t12,0(gp) ++1e8: 00 40 5b 6b call ra,(t12),1ec <__funcZ+0x1ec> ++ ++was converted in the final link pass to: ++ ++12003aa88: 67 fa ff c3 br 120039428 <...> ++12003aa8c: 00 00 fe 2f unop ++12003aa90: 00 00 fe 2f unop ++12003aa94: 48 83 7d a7 ldl t12,-31928(gp) ++12003aa98: 00 40 5b 6b call ra,(t12),12003aa9c <__func+0x1ec> ++ ++And in the noreturn case: ++ ++The instruction stream from an object file: ++ ++54: 00 40 5b 6b call ra,(t12),58 <__func+0x58> ++58: 00 00 ba 27 ldih gp,0(ra) ++5c: 00 00 bd 23 ldi gp,0(gp) ++60: 00 00 7d a7 ldl t12,0(gp) ++64: 00 40 5b 6b call ra,(t12),68 <__func+0x68> ++ ++was converted in the final link pass to: ++ ++fdb24: a0 03 40 d3 bsr ra,fe9a8 <_called_func+0x8> ++fdb28: 00 00 fe 2f unop ++fdb2c: 00 00 fe 2f unop ++fdb30: 30 82 7d a7 ldl t12,-32208(gp) ++fdb34: 00 40 5b 6b call ra,(t12),fdb38 <__func+0x68> ++ ++GP load instructions were wrongly cleared by the linker relaxation ++pass. This workaround prevents removal of GP loads by inserting ++an unop instruction between a sibcall or noreturn function call and ++exception handler prologue. */ ++ ++ if (current_function_has_exception_handlers ()) ++ sw_64_pad_function_end (); ++} ++ ++static void ++sw_64_file_start (void) ++{ ++ default_file_start (); ++ ++ fputs ("\t.set noreorder\n", asm_out_file); ++ fputs ("\t.set volatile\n", asm_out_file); ++ fputs ("\t.set noat\n", asm_out_file); ++ if (TARGET_EXPLICIT_RELOCS) ++ fputs ("\t.set nomacro\n", asm_out_file); ++ if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX ++ | TARGET_SW6A | TARGET_SW6B | TARGET_SW4D | TARGET_SW8A) ++ { ++ const char *arch; ++ ++ if (sw_64_cpu == PROCESSOR_SW6 || TARGET_FIX || TARGET_CIX || TARGET_SW8A) ++ { ++ if (TARGET_SW6A) ++ arch = "sw6a"; ++ else if (TARGET_SW6B) ++ arch = "sw6b"; ++ else if (TARGET_SW4D) ++ arch = "sw4d"; ++ else if (TARGET_SW8A) ++ arch = "sw8a"; ++ } ++ else if (TARGET_MAX) ++ arch = "pca56"; ++ else ++ arch = "sw6b"; ++ ++ fprintf (asm_out_file, "\t.arch %s\n", arch); ++ } ++} ++ ++/* Since we don't have a .dynbss section, we should not allow global ++ relocations in the .rodata section. */ ++ ++static int ++sw_64_elf_reloc_rw_mask (void) ++{ ++ return flag_pic ? 3 : 2; ++} ++ ++/* Return a section for X. The only special thing we do here is to ++ honor small data. */ ++ ++static section * ++sw_64_elf_select_rtx_section (machine_mode mode, rtx x, ++ unsigned HOST_WIDE_INT align) ++{ ++ if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value) ++ /* ??? Consider using mergeable sdata sections. */ ++ return sdata_section; ++ else ++ return default_elf_select_rtx_section (mode, x, align); ++} ++ ++static unsigned int ++sw_64_elf_section_type_flags (tree decl, const char *name, int reloc) ++{ ++ unsigned int flags = 0; ++ ++ if (strcmp (name, ".sdata") == 0 || startswith (name, ".sdata.") ++ || startswith (name, ".gnu.linkonce.s.") || strcmp (name, ".sbss") == 0 ++ || startswith (name, ".sbss.") || startswith (name, ".gnu.linkonce.sb.")) ++ flags = SECTION_SMALL; ++ ++ flags |= default_section_type_flags (decl, name, reloc); ++ return flags; ++} ++ ++/* Structure to collect function names for final output in link section. */ ++/* Note that items marked with GTY can't be ifdef'ed out. */ ++ ++enum reloc_kind ++{ ++ KIND_LINKAGE, ++ KIND_CODEADDR ++}; ++ ++struct GTY (()) sw_64_links ++{ ++ rtx func; ++ rtx linkage; ++ enum reloc_kind rkind; ++}; ++ ++rtx ++sw_64_use_linkage (rtx func ATTRIBUTE_UNUSED, bool lflag ATTRIBUTE_UNUSED, ++ bool rflag ATTRIBUTE_UNUSED) ++{ ++ return NULL_RTX; ++} ++ ++/* On the Sw_64, we use this to disable the floating-point registers ++ when they don't exist. */ ++ ++static void ++sw_64_conditional_register_usage (void) ++{ ++ int i; ++ if (!TARGET_FPREGS) ++ for (i = 32; i < 63; i++) ++ fixed_regs[i] = call_used_regs[i] = 1; ++} ++ ++/* Canonicalize a comparison from one we don't have to one we do have. */ ++ ++static void ++sw_64_canonicalize_comparison (int *code, rtx *op0, rtx *op1, ++ bool op0_preserve_value) ++{ ++ if (!op0_preserve_value ++ && (*code == GE || *code == GT || *code == GEU || *code == GTU) ++ && (REG_P (*op1) || *op1 == const0_rtx)) ++ { ++ std::swap (*op0, *op1); ++ *code = (int) swap_condition ((enum rtx_code) * code); ++ } ++ ++ if ((*code == LT || *code == LTU) && CONST_INT_P (*op1) ++ && INTVAL (*op1) == 256) ++ { ++ *code = *code == LT ? LE : LEU; ++ *op1 = GEN_INT (255); ++ } ++} ++ ++/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */ ++ ++static void ++sw_64_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) ++{ ++ const unsigned HOST_WIDE_INT SWCR_STATUS_MASK = (0x3fUL << 17); ++ ++ tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv; ++ tree new_fenv_var, reload_fenv, restore_fnenv; ++ tree update_call, atomic_feraiseexcept, hold_fnclex; ++ ++ /* Generate the equivalent of : ++ unsigned long fenv_var; ++ fenv_var = __ieee_get_fp_control (); ++ ++ unsigned long masked_fenv; ++ masked_fenv = fenv_var & mask; ++ ++ __ieee_set_fp_control (masked_fenv); */ ++ ++ fenv_var = create_tmp_var_raw (long_unsigned_type_node); ++ get_fpscr ++ = build_fn_decl ("__ieee_get_fp_control", ++ build_function_type_list (long_unsigned_type_node, NULL)); ++ set_fpscr = build_fn_decl ("__ieee_set_fp_control", ++ build_function_type_list (void_type_node, NULL)); ++ mask = build_int_cst (long_unsigned_type_node, ~SWCR_STATUS_MASK); ++ ld_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, fenv_var, ++ build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE); ++ masked_fenv = build2 (BIT_AND_EXPR, long_unsigned_type_node, fenv_var, mask); ++ hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv); ++ *hold = build2 (COMPOUND_EXPR, void_type_node, ++ build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv), ++ hold_fnclex); ++ ++ /* Store the value of masked_fenv to clear the exceptions: ++ __ieee_set_fp_control (masked_fenv); */ ++ ++ *clear = build_call_expr (set_fpscr, 1, masked_fenv); ++ ++ /* Generate the equivalent of : ++ unsigned long new_fenv_var; ++ new_fenv_var = __ieee_get_fp_control (); ++ ++ __ieee_set_fp_control (fenv_var); ++ ++ __atomic_feraiseexcept (new_fenv_var); */ ++ ++ new_fenv_var = create_tmp_var_raw (long_unsigned_type_node); ++ reload_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, new_fenv_var, ++ build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE); ++ restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var); ++ atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT); ++ update_call ++ = build_call_expr (atomic_feraiseexcept, 1, ++ fold_convert (integer_type_node, new_fenv_var)); ++ *update = build2 (COMPOUND_EXPR, void_type_node, ++ build2 (COMPOUND_EXPR, void_type_node, reload_fenv, ++ restore_fnenv), ++ update_call); ++} ++ ++/* Implement TARGET_HARD_REGNO_MODE_OK. On Sw_64, the integer registers ++ can hold any mode. The floating-point registers can hold 64-bit ++ integers as well, but not smaller values. */ ++ ++static bool ++sw_64_hard_regno_mode_ok (unsigned int regno, machine_mode mode) ++{ ++ if (IN_RANGE (regno, 32, 62)) ++ return (mode == SFmode || mode == DFmode || mode == DImode || mode == SCmode ++ || mode == DCmode); ++ return true; ++} ++ ++/* Implement TARGET_MODES_TIEABLE_P. This asymmetric test is true when ++ MODE1 could be put in an FP register but MODE2 could not. */ ++ ++static bool ++sw_64_modes_tieable_p (machine_mode mode1, machine_mode mode2) ++{ ++ return (sw_64_hard_regno_mode_ok (32, mode1) ++ ? sw_64_hard_regno_mode_ok (32, mode2) ++ : true); ++} ++ ++int ++enable_asan_check_stack () ++{ ++ return asan_sanitize_stack_p (); ++} ++ ++/* Implement TARGET_CAN_CHANGE_MODE_CLASS. */ ++ ++static bool ++sw_64_can_change_mode_class (machine_mode from, machine_mode to, ++ reg_class_t rclass) ++{ ++ return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to) ++ || !reg_classes_intersect_p (FLOAT_REGS, rclass)); ++} ++ ++#ifdef ASM_OUTPUT_SIZE_DIRECTIVE ++ ++/* Emit either a label, .comm, or .lcomm directive. When using assembler ++ * macros, mark the symbol as written so that sw_64_asm_output_external ++ * won't emit an .extern for it. STREAM is the output file, NAME is the ++ * name of the symbol, INIT_STRING is the string that should be written ++ * before the symbol and FINAL_STRING is the string that should be ++ * written after it. FINAL_STRING is a printf format that consumes the ++ * remaining arguments. */ ++ ++void ++sw_64_declare_object (FILE *stream, const char *name, const char *init_string, ++ const char *final_string, ...) ++{ ++ va_list ap; ++ ++ fputs (init_string, stream); ++ assemble_name (stream, name); ++ va_start (ap, final_string); ++ vfprintf (stream, final_string, ap); ++ va_end (ap); ++ ++ if (!TARGET_EXPLICIT_RELOCS) ++ { ++ tree name_tree = get_identifier (name); ++ TREE_ASM_WRITTEN (name_tree) = 1; ++ } ++} ++ ++extern int size_directive_output; ++ ++/* Implement ASM_DECLARE_OBJECT_NAME. This is like most of the standard ELF ++ * definitions except that it uses sw_64_declare_object to emit the label. */ ++ ++void ++sw_64_declare_object_name (FILE *stream, const char *name, ++ tree decl ATTRIBUTE_UNUSED) ++{ ++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE ++#ifdef USE_GNU_UNIQUE_OBJECT ++ /* As in elfos.h. */ ++ if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (decl) ++ && (!DECL_ARTIFICIAL (decl) || !TREE_READONLY (decl))) ++ ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "gnu_unique_object"); ++ else ++#endif ++ ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object"); ++#endif ++ ++ size_directive_output = 0; ++ if (!flag_inhibit_size_directive && DECL_SIZE (decl)) ++ { ++ HOST_WIDE_INT size; ++ ++ size_directive_output = 1; ++ size = int_size_in_bytes (TREE_TYPE (decl)); ++ ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size); ++ } ++ ++ sw_64_declare_object (stream, name, "", ":\n"); ++} ++#endif ++ ++bool ++sw_64_slow_unaligned_access (machine_mode mode, unsigned int align) ++{ ++ return STRICT_ALIGNMENT; ++} ++ ++static bool ++sw_64_macro_fusion_p () ++{ ++ return (flag_sw_branch_fusion == 1); ++} ++ ++static bool ++sw_64_macro_fusion_pair_p (rtx_insn *condgen, rtx_insn *condjmp) ++{ ++ rtx src, dest; ++ enum rtx_code ccode; ++ rtx compare_set = NULL_RTX, test_if, cond; ++ rtx alu_set = NULL_RTX, addr = NULL_RTX; ++ if (get_attr_type (condjmp) != TYPE_IBR) ++ return false; ++ if (get_attr_type (condgen) != TYPE_ICMP) ++ return false; ++ compare_set = single_set (condgen); ++ if (compare_set == NULL_RTX) ++ { ++ int i; ++ rtx pat = PATTERN (condgen); ++ for (i = 0; i < XVECLEN (pat, 0); i++) ++ if (GET_CODE (XVECEXP (pat, 0, i)) == SET) ++ { ++ rtx set_src = SET_SRC (XVECEXP (pat, 0, i)); ++ alu_set = XVECEXP (pat, 0, i); ++ } ++ } ++ if (compare_set == NULL_RTX) ++ return false; ++ src = SET_SRC (compare_set); ++ if (GET_CODE (src) == UNSPEC) ++ return false; ++ test_if = SET_SRC (pc_set (condjmp)); ++ cond = XEXP (test_if, 0); ++ ccode = GET_CODE (cond); ++ return true; ++} ++ ++/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ ++static unsigned HOST_WIDE_INT ++sw_64_asan_shadow_offset (void) ++{ ++ return (HOST_WIDE_INT_1 << 49); ++} ++ ++static void ++sw_64_sa_mask (unsigned long *imaskP, unsigned long *fmaskP) ++{ ++ unsigned long imask = 0; ++ unsigned long fmask = 0; ++ unsigned int i; ++ ++ /* When outputting a thunk, we don't have valid register life info, ++ * but assemble_start_function wants to output .frame and .mask ++ * directives. */ ++ if (cfun->is_thunk) ++ { ++ *imaskP = 0; ++ *fmaskP = 0; ++ return; ++ } ++ ++#ifdef SW_64_ENABLE_FULL_ASAN ++ if (frame_pointer_needed) ++ imask |= (1UL << HARD_FRAME_POINTER_REGNUM); ++#endif ++ ++ /* One for every register we have to save. */ ++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ++ if (!fixed_regs[i] && !call_used_regs[i] && df_regs_ever_live_p (i) ++ && i != REG_RA) ++ { ++ if (i < 32) ++ imask |= (1UL << i); ++ else ++ fmask |= (1UL << (i - 32)); ++ } ++ ++ /* We need to restore these for the handler. */ ++ if (crtl->calls_eh_return) ++ { ++ for (i = 0;; ++i) ++ { ++ unsigned regno = EH_RETURN_DATA_REGNO (i); ++ if (regno == INVALID_REGNUM) ++ break; ++ imask |= 1UL << regno; ++ } ++ } ++ ++ /* If any register spilled, then spill the return address also. */ ++ /* ??? This is required by the Digital stack unwind specification ++ and isn't needed if we're doing Dwarf2 unwinding. */ ++ if (imask || fmask || sw_64_ra_ever_killed ()) ++ imask |= (1UL << REG_RA); ++ ++ *imaskP = imask; ++ *fmaskP = fmask; ++} ++ ++int ++sw_64_sa_size (void) ++{ ++ unsigned long mask[2]; ++ int sa_size = 0; ++ int i, j; ++ ++ sw_64_sa_mask (&mask[0], &mask[1]); ++ ++ for (j = 0; j < 2; ++j) ++ for (i = 0; i < 32; ++i) ++ if ((mask[j] >> i) & 1) ++ sa_size++; ++ ++ /* Our size must be even (multiple of 16 bytes). */ ++ if (sa_size & 1) ++ sa_size++; ++ return sa_size * 8; ++} ++ ++/* Sw64 stack frames generated by this compiler look like: ++ ++ +-------------------------------+ ++ | | ++ | incoming stack arguments | ++ | | ++ +-------------------------------+ ++ | | <-- incoming stack pointer (aligned) ++ | callee-allocated save area | ++ | for register varargs | ++ | | ++ +-------------------------------+ ++ | | ++ +-------------------------------+ ++ | local variables | <-- frame_pointer_rtx ++ | | ++ +-------------------------------+ ++ | padding | ++ +-------------------------------+ ++ | callee-saved registers | frame.saved_regs_size ++ +-------------------------------+ ++ | FP' | ++ +-------------------------------+ ++ | RA' | ++ +-------------------------------+ <- hard_frame_pointer_rtx (aligned) ++ | padding | ++ +-------------------------------+ ++ | outgoing stack arguments | <-- arg_pointer ++ | | ++ +-------------------------------+ ++ | | <-- stack_pointer_rtx (aligned) ++ ++ The following registers are reserved during frame layout and should not be ++ used for any other purpose: ++ ++ TODO: add other register purpose ++ - r26(RA), r15(FP): Used by standard frame layout. ++ ++ These registers must be avoided in frame layout related code unless the ++ explicit intention is to interact with one of the features listed above. */ ++ ++static void ++sw_64_layout_frame (void) ++{ ++ poly_int64 offset = 0; ++ ++ cfun->machine->frame.emit_frame_pointer ++ = frame_pointer_needed || crtl->calls_eh_return; ++ ++ unsigned HOST_WIDE_INT sa_mask = 0; ++ int sa_size; ++ ++ /* When outputting a thunk, we don't have valid register life info, ++ but assemble_start_function wants to output .frame and .mask ++ directives. */ ++ if (!cfun->is_thunk) ++ { ++ /* One for every register we have to save. */ ++ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++) ++ if (!call_used_or_fixed_reg_p (i) && df_regs_ever_live_p (i) ++ && i != REG_RA) ++ sa_mask |= HOST_WIDE_INT_1U << i; ++ ++ /* We need to restore these for the handler. */ ++ if (crtl->calls_eh_return) ++ { ++ for (unsigned i = 0;; ++i) ++ { ++ unsigned regno = EH_RETURN_DATA_REGNO (i); ++ if (regno == INVALID_REGNUM) ++ break; ++ sa_mask |= HOST_WIDE_INT_1U << regno; ++ } ++ } ++ /* If any register spilled, then spill the return address also. */ ++ /* ??? This is required by the Digital stack unwind specification ++ and isn't needed if we're doing Dwarf2 unwinding. */ ++ if (sa_mask || sw_64_ra_ever_killed ()) ++ sa_mask |= HOST_WIDE_INT_1U << REG_RA; ++ } ++ sa_size = popcount_hwi (sa_mask); ++ poly_int64 frame_size = get_frame_size (); ++ ++ /* Our size must be even (multiple of 16 bytes). */ ++ if (sa_size & 1) ++ sa_size++; ++ sa_size *= 8; ++ ++ poly_int64 varargs_and_saved_regs_size ++ = sa_size + cfun->machine->frame.saved_varargs_size ++ + crtl->args.pretend_args_size; ++ ++ poly_int64 varargs_size ++ = cfun->machine->frame.saved_varargs_size + crtl->args.pretend_args_size; ++ ++ HOST_WIDE_INT extra_alignment ++ = SW_64_ROUND (frame_size + cfun->machine->frame.saved_varargs_size) ++ - cfun->machine->frame.saved_varargs_size; ++ ++ poly_int64 outgoing_args = SW_64_ROUND (crtl->outgoing_args_size); ++ ++ cfun->machine->frame.local_offset ++ = cfun->machine->frame.saved_varargs_size + crtl->args.pretend_args_size; ++ ++ poly_int64 total_size ++ = aligned_upper_bound (varargs_and_saved_regs_size + frame_size, ++ STACK_BOUNDARY / BITS_PER_UNIT) ++ + outgoing_args; ++ ++ cfun->machine->frame.hard_frame_pointer_offset ++ = aligned_upper_bound (varargs_and_saved_regs_size + frame_size, ++ STACK_BOUNDARY / BITS_PER_UNIT); ++ ++ // TODO: does sw_64 need this feild? ++ cfun->machine->frame.callee_offset ++ = cfun->machine->frame.hard_frame_pointer_offset; ++ cfun->machine->frame.arg_pointer_offset = total_size - varargs_size; ++ cfun->machine->frame.sa_mask = sa_mask; ++ cfun->machine->frame.saved_regs_size = sa_size; ++ cfun->machine->frame.frame_size = total_size; ++} ++ ++/* Define the offset between two registers, one to be eliminated, ++ and the other its replacement, at the start of a routine. */ ++ ++HOST_WIDE_INT ++sw_64_initial_elimination_offset (unsigned int from, ++ unsigned int to ATTRIBUTE_UNUSED) ++{ ++ HOST_WIDE_INT ret; ++#ifdef SW_64_ENABLE_FULL_ASAN ++ if (to == HARD_FRAME_POINTER_REGNUM) ++ { ++ if (from == ARG_POINTER_REGNUM) ++ { ++ // TODO: in sw64 variable arguments processing, all regs ++ // and pretending arguments offset a passive, so we have ++ // to minus varargs size. May be fix it is a better way? ++ return cfun->machine->frame.hard_frame_pointer_offset ++ - cfun->machine->frame.local_offset; ++ } ++ ++ if (from == FRAME_POINTER_REGNUM) ++ { ++ return cfun->machine->frame.hard_frame_pointer_offset ++ - cfun->machine->frame.local_offset; ++ } ++ } ++ ++ if (to == STACK_POINTER_REGNUM) ++ { ++ if (from == ARG_POINTER_REGNUM) ++ { ++ // TODO: same as HARD_FRAME_POINTER_REGNUM; ++ return cfun->machine->frame.arg_pointer_offset; ++ } ++ if (from == FRAME_POINTER_REGNUM) ++ { ++ return cfun->machine->frame.arg_pointer_offset; ++ } ++ } ++ ++ return cfun->machine->frame.frame_size; ++#else ++ ret = sw_64_sa_size (); ++ if (!frame_pointer_needed) ++ ret += SW_64_ROUND (crtl->outgoing_args_size); ++ ++ switch (from) ++ { ++ case FRAME_POINTER_REGNUM: ++ break; ++ ++ case ARG_POINTER_REGNUM: ++ ret += (SW_64_ROUND (get_frame_size () + crtl->args.pretend_args_size) ++ - crtl->args.pretend_args_size); ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ return ret; ++#endif ++} ++ ++/* Compute the frame size. SIZE is the size of the "naked" frame ++ * and SA_SIZE is the size of the register save area. */ ++ ++static HOST_WIDE_INT ++compute_frame_size (HOST_WIDE_INT size, HOST_WIDE_INT sa_size) ++{ ++#ifdef SW_64_ENABLE_FULL_ASAN ++ // sw_64_layout_frame (); ++ return cfun->machine->frame.frame_size; ++#else ++ return SW_64_ROUND (crtl->outgoing_args_size) + sa_size ++ + SW_64_ROUND (size + crtl->args.pretend_args_size); ++#endif ++} ++ ++/* Initialize the GCC target structure. */ ++#undef TARGET_IN_SMALL_DATA_P ++#define TARGET_IN_SMALL_DATA_P sw_64_in_small_data_p ++ ++#undef TARGET_ASM_ALIGNED_HI_OP ++#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" ++#undef TARGET_ASM_ALIGNED_DI_OP ++#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t" ++ ++/* Default unaligned ops are provided for ELF systems. To get unaligned ++ data for non-ELF systems, we have to turn off auto alignment. */ ++#undef TARGET_ASM_RELOC_RW_MASK ++#define TARGET_ASM_RELOC_RW_MASK sw_64_elf_reloc_rw_mask ++#undef TARGET_ASM_SELECT_RTX_SECTION ++#define TARGET_ASM_SELECT_RTX_SECTION sw_64_elf_select_rtx_section ++#undef TARGET_SECTION_TYPE_FLAGS ++#define TARGET_SECTION_TYPE_FLAGS sw_64_elf_section_type_flags ++ ++#undef TARGET_ASM_FUNCTION_END_PROLOGUE ++#define TARGET_ASM_FUNCTION_END_PROLOGUE sw_64_output_function_end_prologue ++ ++#undef TARGET_LEGITIMIZE_ADDRESS ++#define TARGET_LEGITIMIZE_ADDRESS sw_64_legitimize_address ++#undef TARGET_MODE_DEPENDENT_ADDRESS_P ++#define TARGET_MODE_DEPENDENT_ADDRESS_P sw_64_mode_dependent_address_p ++ ++#undef TARGET_ASM_FILE_START ++#define TARGET_ASM_FILE_START sw_64_file_start ++ ++#undef TARGET_SCHED_ADJUST_COST ++#define TARGET_SCHED_ADJUST_COST sw_64_adjust_cost ++#undef TARGET_SCHED_ISSUE_RATE ++#define TARGET_SCHED_ISSUE_RATE sw_64_issue_rate ++#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ++#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ ++ sw_64_multipass_dfa_lookahead ++ ++#undef TARGET_HAVE_TLS ++#define TARGET_HAVE_TLS HAVE_AS_TLS ++ ++#undef TARGET_BUILTIN_DECL ++#define TARGET_BUILTIN_DECL sw_64_builtin_decl ++#undef TARGET_INIT_BUILTINS ++#define TARGET_INIT_BUILTINS sw_64_init_builtins ++#undef TARGET_EXPAND_BUILTIN ++#define TARGET_EXPAND_BUILTIN sw_64_expand_builtin ++#undef TARGET_FOLD_BUILTIN ++#define TARGET_FOLD_BUILTIN sw_64_fold_builtin ++#undef TARGET_GIMPLE_FOLD_BUILTIN ++#define TARGET_GIMPLE_FOLD_BUILTIN sw_64_gimple_fold_builtin ++ ++#undef TARGET_FUNCTION_OK_FOR_SIBCALL ++#define TARGET_FUNCTION_OK_FOR_SIBCALL sw_64_function_ok_for_sibcall ++#undef TARGET_CANNOT_COPY_INSN_P ++#define TARGET_CANNOT_COPY_INSN_P sw_64_cannot_copy_insn_p ++#undef TARGET_LEGITIMATE_CONSTANT_P ++#define TARGET_LEGITIMATE_CONSTANT_P sw_64_legitimate_constant_p ++#undef TARGET_CANNOT_FORCE_CONST_MEM ++#define TARGET_CANNOT_FORCE_CONST_MEM sw_64_cannot_force_const_mem ++ ++#undef TARGET_ASM_OUTPUT_MI_THUNK ++#define TARGET_ASM_OUTPUT_MI_THUNK sw_64_output_mi_thunk_osf ++#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK ++#define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ ++ hook_bool_const_tree_hwi_hwi_const_tree_true ++#undef TARGET_STDARG_OPTIMIZE_HOOK ++#define TARGET_STDARG_OPTIMIZE_HOOK sw_64_stdarg_optimize_hook ++ ++#undef TARGET_PRINT_OPERAND ++#define TARGET_PRINT_OPERAND sw_64_print_operand ++#undef TARGET_PRINT_OPERAND_ADDRESS ++#define TARGET_PRINT_OPERAND_ADDRESS sw_64_print_operand_address ++#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P ++#define TARGET_PRINT_OPERAND_PUNCT_VALID_P sw_64_print_operand_punct_valid_p ++ ++/* Use 16-bits anchor. */ ++#undef TARGET_MIN_ANCHOR_OFFSET ++#define TARGET_MIN_ANCHOR_OFFSET -0x7fff - 1 ++#undef TARGET_MAX_ANCHOR_OFFSET ++#define TARGET_MAX_ANCHOR_OFFSET 0x7fff ++#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P ++#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true ++ ++#undef TARGET_REGISTER_MOVE_COST ++#define TARGET_REGISTER_MOVE_COST sw_64_register_move_cost ++#undef TARGET_MEMORY_MOVE_COST ++#define TARGET_MEMORY_MOVE_COST sw_64_memory_move_cost ++#undef TARGET_RTX_COSTS ++#define TARGET_RTX_COSTS sw_64_rtx_costs ++#undef TARGET_ADDRESS_COST ++#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 ++ ++#undef TARGET_MACHINE_DEPENDENT_REORG ++#define TARGET_MACHINE_DEPENDENT_REORG sw_64_reorg ++ ++#undef TARGET_PROMOTE_FUNCTION_MODE ++#define TARGET_PROMOTE_FUNCTION_MODE \ ++ default_promote_function_mode_always_promote ++#undef TARGET_PROMOTE_PROTOTYPES ++#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false ++ ++#undef TARGET_FUNCTION_VALUE ++#define TARGET_FUNCTION_VALUE sw_64_function_value ++#undef TARGET_LIBCALL_VALUE ++#define TARGET_LIBCALL_VALUE sw_64_libcall_value ++#undef TARGET_FUNCTION_VALUE_REGNO_P ++#define TARGET_FUNCTION_VALUE_REGNO_P sw_64_function_value_regno_p ++#undef TARGET_RETURN_IN_MEMORY ++#define TARGET_RETURN_IN_MEMORY sw_64_return_in_memory ++#undef TARGET_PASS_BY_REFERENCE ++#define TARGET_PASS_BY_REFERENCE sw_64_pass_by_reference ++#undef TARGET_SETUP_INCOMING_VARARGS ++#define TARGET_SETUP_INCOMING_VARARGS sw_64_setup_incoming_varargs ++#undef TARGET_STRICT_ARGUMENT_NAMING ++#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true ++#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED ++#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true ++#undef TARGET_SPLIT_COMPLEX_ARG ++#define TARGET_SPLIT_COMPLEX_ARG sw_64_split_complex_arg ++#undef TARGET_GIMPLIFY_VA_ARG_EXPR ++#define TARGET_GIMPLIFY_VA_ARG_EXPR sw_64_gimplify_va_arg ++#undef TARGET_ARG_PARTIAL_BYTES ++#define TARGET_ARG_PARTIAL_BYTES sw_64_arg_partial_bytes ++#undef TARGET_FUNCTION_ARG ++#define TARGET_FUNCTION_ARG sw_64_function_arg ++#undef TARGET_FUNCTION_ARG_ADVANCE ++#define TARGET_FUNCTION_ARG_ADVANCE sw_64_function_arg_advance ++#undef TARGET_TRAMPOLINE_INIT ++#define TARGET_TRAMPOLINE_INIT sw_64_trampoline_init ++ ++#undef TARGET_INSTANTIATE_DECLS ++#define TARGET_INSTANTIATE_DECLS sw_64_instantiate_decls ++ ++#undef TARGET_SECONDARY_RELOAD ++#define TARGET_SECONDARY_RELOAD sw_64_secondary_reload ++#undef TARGET_SECONDARY_MEMORY_NEEDED ++#define TARGET_SECONDARY_MEMORY_NEEDED sw_64_secondary_memory_needed ++#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE ++#define TARGET_SECONDARY_MEMORY_NEEDED_MODE sw_64_secondary_memory_needed_mode ++ ++#undef TARGET_SCALAR_MODE_SUPPORTED_P ++#define TARGET_SCALAR_MODE_SUPPORTED_P sw_64_scalar_mode_supported_p ++#undef TARGET_VECTOR_MODE_SUPPORTED_P ++#define TARGET_VECTOR_MODE_SUPPORTED_P sw_64_vector_mode_supported_p ++ ++#undef TARGET_BUILD_BUILTIN_VA_LIST ++#define TARGET_BUILD_BUILTIN_VA_LIST sw_64_build_builtin_va_list ++ ++#undef TARGET_EXPAND_BUILTIN_VA_START ++#define TARGET_EXPAND_BUILTIN_VA_START sw_64_va_start ++ ++#undef TARGET_OPTION_OVERRIDE ++#define TARGET_OPTION_OVERRIDE sw_64_option_override ++ ++#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ++#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE sw_64_override_options_after_change ++ ++#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING ++#undef TARGET_MANGLE_TYPE ++#define TARGET_MANGLE_TYPE sw_64_mangle_type ++#endif ++ ++#undef TARGET_LRA_P ++#define TARGET_LRA_P hook_bool_void_false ++ ++#undef TARGET_LEGITIMATE_ADDRESS_P ++#define TARGET_LEGITIMATE_ADDRESS_P sw_64_legitimate_address_p ++ ++#undef TARGET_CONDITIONAL_REGISTER_USAGE ++#define TARGET_CONDITIONAL_REGISTER_USAGE sw_64_conditional_register_usage ++ ++#undef TARGET_CANONICALIZE_COMPARISON ++#define TARGET_CANONICALIZE_COMPARISON sw_64_canonicalize_comparison ++ ++#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV ++#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV sw_64_atomic_assign_expand_fenv ++ ++#undef TARGET_HARD_REGNO_MODE_OK ++#define TARGET_HARD_REGNO_MODE_OK sw_64_hard_regno_mode_ok ++ ++#undef TARGET_SLOW_UNALIGNED_ACCESS ++#define TARGET_SLOW_UNALIGNED_ACCESS sw_64_slow_unaligned_access ++ ++#undef TARGET_MODES_TIEABLE_P ++#define TARGET_MODES_TIEABLE_P sw_64_modes_tieable_p ++ ++#undef TARGET_CAN_CHANGE_MODE_CLASS ++#define TARGET_CAN_CHANGE_MODE_CLASS sw_64_can_change_mode_class ++ ++#undef TARGET_SCHED_MACRO_FUSION_P ++#define TARGET_SCHED_MACRO_FUSION_P sw_64_macro_fusion_p ++ ++#undef TARGET_SCHED_MACRO_FUSION_PAIR_P ++#define TARGET_SCHED_MACRO_FUSION_PAIR_P sw_64_macro_fusion_pair_p ++#undef TARGET_ASAN_SHADOW_OFFSET ++#define TARGET_ASAN_SHADOW_OFFSET sw_64_asan_shadow_offset ++ ++struct gcc_target targetm = TARGET_INITIALIZER; ++ ++#include "gt-sw-64.h" +diff --git a/gcc/config/sw_64/sw_64.h b/gcc/config/sw_64/sw_64.h +new file mode 100644 +index 000000000..fdf61ba04 +--- /dev/null ++++ b/gcc/config/sw_64/sw_64.h +@@ -0,0 +1,1001 @@ ++/* Definitions of target machine for GNU compiler, for Sw64. ++ Copyright (C) 1992-2022 Free Software Foundation, Inc. ++ Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++/* Target CPU builtins. */ ++#define TARGET_CPU_CPP_BUILTINS() \ ++ do \ ++ { \ ++ builtin_define ("__sw_64"); \ ++ builtin_define ("__sw_64__"); \ ++ builtin_assert ("cpu=sw_64"); \ ++ builtin_assert ("machine=sw_64"); \ ++ if (TARGET_CIX) \ ++ { \ ++ builtin_define ("__sw_64_cix__"); \ ++ builtin_assert ("cpu=cix"); \ ++ } \ ++ if (TARGET_FIX) \ ++ { \ ++ builtin_define ("__sw_64_fix__"); \ ++ builtin_assert ("cpu=fix"); \ ++ } \ ++ if (TARGET_BWX) \ ++ { \ ++ builtin_define ("__sw_64_bwx__"); \ ++ builtin_assert ("cpu=bwx"); \ ++ } \ ++ if (TARGET_MAX) \ ++ { \ ++ builtin_define ("__sw_64_max__"); \ ++ builtin_assert ("cpu=max"); \ ++ } \ ++ if (sw_64_cpu_string) \ ++ { \ ++ if (strcmp (sw_64_cpu_string, "sw6a") == 0) \ ++ { \ ++ builtin_define ("__sw_64_sw6a__"); \ ++ builtin_assert ("cpu=sw6a"); \ ++ } \ ++ else if (strcmp (sw_64_cpu_string, "sw6b") == 0) \ ++ { \ ++ builtin_define ("__sw_64_sw6b__"); \ ++ builtin_assert ("cpu=sw6b"); \ ++ } \ ++ else if (strcmp (sw_64_cpu_string, "sw4d") == 0) \ ++ { \ ++ builtin_define ("__sw_64_sw4d__"); \ ++ builtin_assert ("cpu=sw4d"); \ ++ } \ ++ else if (strcmp (sw_64_cpu_string, "sw8a") == 0) \ ++ { \ ++ builtin_define ("__sw_64_sw8a__"); \ ++ builtin_assert ("cpu=sw8a"); \ ++ } \ ++ } \ ++ else /* Presumably sw6b. */ \ ++ { \ ++ builtin_define ("__sw_64_sw6b__"); \ ++ builtin_assert ("cpu=sw6b"); \ ++ } \ ++ if (TARGET_IEEE || TARGET_IEEE_WITH_INEXACT) \ ++ builtin_define ("_IEEE_FP"); \ ++ if (TARGET_IEEE_WITH_INEXACT) \ ++ builtin_define ("_IEEE_FP_INEXACT"); \ ++ if (TARGET_LONG_DOUBLE_128) \ ++ builtin_define ("__LONG_DOUBLE_128__"); \ ++ \ ++ /* Macros dependent on the C dialect. */ \ ++ SUBTARGET_LANGUAGE_CPP_BUILTINS (); \ ++ } while (0) ++ ++#ifndef SUBTARGET_LANGUAGE_CPP_BUILTINS ++#define SUBTARGET_LANGUAGE_CPP_BUILTINS() \ ++ do \ ++ { \ ++ if (preprocessing_asm_p ()) \ ++ builtin_define_std ("LANGUAGE_ASSEMBLY"); \ ++ else if (c_dialect_cxx ()) \ ++ { \ ++ builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \ ++ builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \ ++ } \ ++ else \ ++ builtin_define_std ("LANGUAGE_C"); \ ++ if (c_dialect_objc ()) \ ++ { \ ++ builtin_define ("__LANGUAGE_OBJECTIVE_C"); \ ++ builtin_define ("__LANGUAGE_OBJECTIVE_C__"); \ ++ } \ ++ } while (0) ++#endif ++ ++/* Run-time compilation parameters selecting different hardware subsets. */ ++ ++/* Which processor to schedule for. The cpu attribute defines a list that ++ mirrors this list, so changes to sw_64.md must be made at the same time. */ ++ ++enum processor_type ++{ ++ PROCESSOR_SW6, /* SW6 */ ++ PROCESSOR_SW8, /* SW8 */ ++ PROCESSOR_MAX ++}; ++ ++extern enum processor_type sw_64_cpu; ++extern enum processor_type sw_64_tune; ++ ++enum sw_64_trap_precision ++{ ++ SW_64_TP_PROG, /* No precision (default). */ ++ SW_64_TP_FUNC, /* Trap contained within originating function. */ ++ SW_64_TP_INSN /* Instruction accuracy and code is resumption safe. */ ++}; ++ ++enum sw_64_fp_rounding_mode ++{ ++ SW_64_FPRM_NORM, /* Normal rounding mode. */ ++ SW_64_FPRM_MINF, /* Round towards minus-infinity. */ ++ SW_64_FPRM_CHOP, /* Chopped rounding mode (towards 0). */ ++ SW_64_FPRM_DYN /* Dynamic rounding mode. */ ++}; ++ ++enum sw_64_fp_trap_mode ++{ ++ SW_64_FPTM_N, /* Normal trap mode. */ ++ SW_64_FPTM_U, /* Underflow traps enabled. */ ++ SW_64_FPTM_SU, /* Software completion, w/underflow traps */ ++ SW_64_FPTM_SUI /* Software completion, w/underflow & inexact traps */ ++}; ++ ++extern enum sw_64_trap_precision sw_64_tp; ++extern enum sw_64_fp_rounding_mode sw_64_fprm; ++extern enum sw_64_fp_trap_mode sw_64_fptm; ++ ++/* Invert the easy way to make options work. */ ++#define TARGET_FP (!TARGET_SOFT_FP) ++ ++/* Macros to silence warnings about numbers being signed in traditional ++ * C and unsigned in ISO C when compiled on 32-bit hosts. */ ++ ++#define BITMASK_HIGH (((unsigned long) 1) << 31) /* 0x80000000 */ ++ ++/* These are for target os support and cannot be changed at runtime. */ ++#define TARGET_ABI_OSF 1 ++ ++#ifndef TARGET_CAN_FAULT_IN_PROLOGUE ++#define TARGET_CAN_FAULT_IN_PROLOGUE 0 ++#endif ++#ifndef TARGET_HAS_XFLOATING_LIBS ++#define TARGET_HAS_XFLOATING_LIBS TARGET_LONG_DOUBLE_128 ++#endif ++#ifndef TARGET_PROFILING_NEEDS_GP ++#define TARGET_PROFILING_NEEDS_GP 0 ++#endif ++#ifndef HAVE_AS_TLS ++#define HAVE_AS_TLS 0 ++#endif ++ ++#define TARGET_DEFAULT MASK_FPREGS ++ ++#ifndef TARGET_CPU_DEFAULT ++#define TARGET_CPU_DEFAULT 0 ++#endif ++ ++#ifndef TARGET_DEFAULT_EXPLICIT_RELOCS ++#ifdef HAVE_AS_EXPLICIT_RELOCS ++#define TARGET_DEFAULT_EXPLICIT_RELOCS MASK_EXPLICIT_RELOCS ++#define TARGET_SUPPORT_ARCH 1 ++#else ++#define TARGET_DEFAULT_EXPLICIT_RELOCS 0 ++#endif ++#endif ++ ++#ifndef TARGET_SUPPORT_ARCH ++#define TARGET_SUPPORT_ARCH 0 ++#endif ++ ++/* Support for a compile-time default CPU, et cetera. The rules are: ++ --with-cpu is ignored if -mcpu is specified. ++ --with-tune is ignored if -mtune is specified. */ ++#define OPTION_DEFAULT_SPECS \ ++ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}"}, \ ++ { \ ++ "tune", "%{!mtune=*:-mtune=%(VALUE)}" \ ++ } ++ ++/* target machine storage layout */ ++ ++/* Define the size of `int'. The default is the same as the word size. */ ++#define INT_TYPE_SIZE 32 ++ ++/* Define the size of `long long'. The default is the twice the word size. */ ++#define LONG_LONG_TYPE_SIZE 64 ++ ++/* The two floating-point formats we support are S-floating, which is ++ 4 bytes, and T-floating, which is 8 bytes. `float' is S and `double' ++ and `long double' are T. */ ++ ++#define FLOAT_TYPE_SIZE 32 ++#define DOUBLE_TYPE_SIZE 64 ++#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64) ++ ++/* Work around target_flags dependency in ada/targtyps.c. */ ++#define WIDEST_HARDWARE_FP_SIZE 64 ++ ++#define WCHAR_TYPE "unsigned int" ++#define WCHAR_TYPE_SIZE 32 ++ ++/* Define this macro if it is advisable to hold scalars in registers ++ in a wider mode than that declared by the program. In such cases, ++ the value is constrained to be within the bounds of the declared ++ type, but kept valid in the wider mode. The signedness of the ++ extension may differ from that of the type. ++ ++ For Sw_64, we always store objects in a full register. 32-bit integers ++ are always sign-extended, but smaller objects retain their signedness. ++ ++ Note that small vector types can get mapped onto integer modes at the ++ whim of not appearing in sw_64-modes.def. We never promoted these ++ values before; don't do so now that we've trimmed the set of modes to ++ those actually implemented in the backend. */ ++ ++#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ ++ if (GET_MODE_CLASS (MODE) == MODE_INT \ ++ && (TYPE == NULL || TREE_CODE (TYPE) != VECTOR_TYPE) \ ++ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ ++ { \ ++ if ((MODE) == SImode) \ ++ (UNSIGNEDP) = 0; \ ++ (MODE) = DImode; \ ++ } ++ ++/* Define this if most significant bit is lowest numbered ++ in instructions that operate on numbered bit-fields. ++ ++ There are no such instructions on the Sw_64, but the documentation ++ is little endian. */ ++#define BITS_BIG_ENDIAN 0 ++ ++/* Define this if most significant byte of a word is the lowest numbered. ++ This is false on the Sw_64. */ ++#define BYTES_BIG_ENDIAN 0 ++ ++/* Define this if most significant word of a multiword number is lowest ++ numbered. ++ ++ For Sw_64 we can decide arbitrarily since there are no machine instructions ++ for them. Might as well be consistent with bytes. */ ++#define WORDS_BIG_ENDIAN 0 ++ ++/* Width of a word, in units (bytes). */ ++#define UNITS_PER_WORD 8 ++ ++/* Width in bits of a pointer. ++ See also the macro `Pmode' defined below. */ ++#define POINTER_SIZE 64 ++ ++/* Allocation boundary (in *bits*) for storing arguments in argument list. */ ++#define PARM_BOUNDARY 64 ++ ++/* Boundary (in *bits*) on which stack pointer should be aligned. */ ++#define STACK_BOUNDARY (TARGET_SW_32ALIGN ? 256 : 128) ++ ++/* Allocation boundary (in *bits*) for the code of a function. */ ++#define FUNCTION_BOUNDARY 32 ++ ++/* Alignment of field after `int : 0' in a structure. */ ++#define EMPTY_FIELD_BOUNDARY 64 ++ ++/* Every structure's size must be a multiple of this. */ ++#define STRUCTURE_SIZE_BOUNDARY 8 ++ ++/* A bit-field declared as `int' forces `int' alignment for the struct. */ ++#undef PCC_BITFILED_TYPE_MATTERS ++#define PCC_BITFIELD_TYPE_MATTERS 1 ++ ++/* No data type wants to be aligned rounder than this. */ ++#define BIGGEST_ALIGNMENT (TARGET_SW_32ALIGN ? 256 : 128) ++ ++/* For atomic access to objects, must have at least 32-bit alignment ++ unless the machine has byte operations. */ ++#define MINIMUM_ATOMIC_ALIGNMENT ((unsigned int) (TARGET_BWX ? 8 : 32)) ++ ++/* Align all constants and variables to at least a word boundary so ++ we can pick up pieces of them faster. */ ++/* ??? Only if block-move stuff knows about different source/destination ++ alignment. */ ++#if 0 ++#define DATA_ALIGNMENT(EXP, ALIGN) MAX ((ALIGN), BITS_PER_WORD) ++#endif ++ ++/* Set this nonzero if move instructions will actually fail to work ++ when given unaligned data. ++ ++ Since we get an error message when we do one, call them invalid. */ ++ ++#define STRICT_ALIGNMENT (flag_sw_unalign_byte != 1 || TARGET_SW8A == 0) ++ ++#define SW64_EXPAND_ALIGNMENT(COND, EXP, ALIGN) \ ++ (((COND) && ((ALIGN) < BITS_PER_WORD) \ ++ && (TREE_CODE (EXP) == ARRAY_TYPE || TREE_CODE (EXP) == UNION_TYPE \ ++ || TREE_CODE (EXP) == RECORD_TYPE)) \ ++ ? BITS_PER_WORD \ ++ : (ALIGN)) ++ ++/* Similarly, make sure that objects on the stack are sensibly aligned. */ ++#define LOCAL_ALIGNMENT(EXP, ALIGN) \ ++ SW64_EXPAND_ALIGNMENT (!flag_conserve_stack, EXP, ALIGN) ++ ++/* Standard register usage. */ ++ ++/* Number of actual hardware registers. ++ The hardware registers are assigned numbers for the compiler ++ from 0 to just below FIRST_PSEUDO_REGISTER. ++ All registers that the compiler knows about must be given numbers, ++ even those that are not normally considered general registers. ++ ++ We define all 32 integer registers, even though $31 is always zero, ++ and all 32 floating-point registers, even though $f31 is also ++ always zero. We do not bother defining the FP status register and ++ there are no other registers. ++ ++ Since $31 is always zero, we will use register number 31 as the ++ argument pointer. It will never appear in the generated code ++ because we will always be eliminating it in favor of the stack ++ pointer or hardware frame pointer. ++ ++ Likewise, we use $f31 for the frame pointer, which will always ++ be eliminated in favor of the hardware frame pointer or the ++ stack pointer. */ ++ ++#define FIRST_PSEUDO_REGISTER 64 ++ ++/* 1 for registers that have pervasive standard uses ++ and are not available for the register allocator. */ ++ ++#define FIXED_REGISTERS \ ++ { \ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ ++ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \ ++ } ++ ++/* 1 for registers not available across function calls. ++ These must include the FIXED_REGISTERS and also any ++ registers that can be used without being saved. ++ The latter must include the registers where values are returned ++ and the register where structure-value addresses are passed. ++ Aside from that, you can include as many other registers as you like. */ ++#define CALL_USED_REGISTERS \ ++ { \ ++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ ++ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, \ ++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \ ++ } ++ ++/* List the order in which to allocate registers. Each register must be ++ listed once, even those in FIXED_REGISTERS. */ ++ ++#define REG_ALLOC_ORDER \ ++ { \ ++ 1, 2, 3, 4, 5, 6, 7, 8, /* nonsaved integer registers */ \ ++ 22, 23, 24, 25, 28, /* likewise */ \ ++ 0, /* likewise, but return value */ \ ++ 21, 20, 19, 18, 17, 16, /* likewise, but input args */ \ ++ 27, /* likewise, but SYSV procedure value */ \ ++ \ ++ 42, 43, 44, 45, 46, 47, /* nonsaved floating-point registers */ \ ++ 54, 55, 56, 57, 58, 59, /* likewise */ \ ++ 60, 61, 62, /* likewise */ \ ++ 32, 33, /* likewise, but return values */ \ ++ 53, 52, 51, 50, 49, 48, /* likewise, but input args */ \ ++ \ ++ 9, 10, 11, 12, 13, 14, /* saved integer registers */ \ ++ 26, /* return address */ \ ++ 15, /* hard frame pointer */ \ ++ \ ++ 34, 35, 36, 37, 38, 39, /* saved floating-point registers */ \ ++ 40, 41, /* likewise */ \ ++ \ ++ 29, 30, 31, 63 /* gp, sp, ap, sfp */ \ ++ } ++ ++/* Specify the registers used for certain standard purposes. ++ The values of these macros are register numbers. */ ++ ++/* Sw_64 pc isn't overloaded on a register that the compiler knows about. */ ++/* #define PC_REGNUM */ ++ ++/* Register to use for pushing function arguments. */ ++#define STACK_POINTER_REGNUM 30 ++ ++/* Base register for access to local variables of the function. */ ++#define HARD_FRAME_POINTER_REGNUM 15 ++ ++/* Base register for access to arguments of the function. */ ++#define ARG_POINTER_REGNUM 31 ++ ++/* Base register for access to local variables of function. */ ++#define FRAME_POINTER_REGNUM 63 ++ ++/* Register in which static-chain is passed to a function. ++ ++ For the Sw_64, this is based on an example; the calling sequence ++ doesn't seem to specify this. */ ++#define STATIC_CHAIN_REGNUM 1 ++ ++/* The register number of the register used to address a table of ++ static data addresses in memory. */ ++#define PIC_OFFSET_TABLE_REGNUM 29 ++ ++/* Define this macro if the register defined by `PIC_OFFSET_TABLE_REGNUM' ++ is clobbered by calls. */ ++/* ??? It is and it isn't. It's required to be valid for a given ++ function when the function returns. It isn't clobbered by ++ current_file functions. Moreover, we do not expose the ldgp ++ until after reload, so we're probably safe. */ ++/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */ ++ ++/* Define the classes of registers for register constraints in the ++ machine description. Also define ranges of constants. ++ ++ One of the classes must always be named ALL_REGS and include all hard regs. ++ If there is more than one class, another class must be named NO_REGS ++ and contain no registers. ++ ++ The name GENERAL_REGS must be the name of a class (or an alias for ++ another name such as ALL_REGS). This is the class of registers ++ that is allowed by "g" or "r" in a register constraint. ++ Also, registers outside this class are allocated only when ++ instructions express preferences for them. ++ ++ The classes must be numbered in nondecreasing order; that is, ++ a larger-numbered class must never be contained completely ++ in a smaller-numbered class. ++ ++ For any two classes, it is very desirable that there be another ++ class that represents their union. */ ++ ++enum reg_class ++{ ++ NO_REGS, ++ R0_REG, ++ R24_REG, ++ R25_REG, ++ R27_REG, ++ GENERAL_REGS, ++ FLOAT_REGS, ++ ALL_REGS, ++ LIM_REG_CLASSES ++}; ++ ++#define N_REG_CLASSES (int) LIM_REG_CLASSES ++ ++/* Give names of register classes as strings for dump file. */ ++ ++#define REG_CLASS_NAMES \ ++ { \ ++ "NO_REGS", "R0_REG", "R24_REG", "R25_REG", "R27_REG", "GENERAL_REGS", \ ++ "FLOAT_REGS", "ALL_REGS" \ ++ } ++ ++/* Define which registers fit in which classes. ++ This is an initializer for a vector of HARD_REG_SET ++ of length N_REG_CLASSES. */ ++ ++#define REG_CLASS_CONTENTS \ ++ { \ ++ {0x00000000, 0x00000000}, /* NO_REGS */ \ ++ {0x00000001, 0x00000000}, /* R0_REG */ \ ++ {0x01000000, 0x00000000}, /* R24_REG */ \ ++ {0x02000000, 0x00000000}, /* R25_REG */ \ ++ {0x08000000, 0x00000000}, /* R27_REG */ \ ++ {0xffffffff, 0x80000000}, /* GENERAL_REGS */ \ ++ {0x00000000, 0x7fffffff}, /* FLOAT_REGS */ \ ++ { \ ++ 0xffffffff, 0xffffffff \ ++ } \ ++ } ++ ++/* The same information, inverted: ++ Return the class number of the smallest class containing ++ reg number REGNO. This could be a conditional expression ++ or could index an array. */ ++ ++#define REGNO_REG_CLASS(REGNO) \ ++ ((REGNO) == 0 ? R0_REG \ ++ : (REGNO) == 24 ? R24_REG \ ++ : (REGNO) == 25 ? R25_REG \ ++ : (REGNO) == 27 ? R27_REG \ ++ : IN_RANGE ((REGNO), 32, 62) ? FLOAT_REGS \ ++ : GENERAL_REGS) ++ ++/* The class value for index registers, and the one for base regs. */ ++#define INDEX_REG_CLASS NO_REGS ++#define BASE_REG_CLASS GENERAL_REGS ++ ++/* Given an rtx X being reloaded into a reg required to be ++ in class CLASS, return the class of reg to actually use. ++ In general this is just CLASS; but on some machines ++ in some cases it is preferable to use a more restrictive class. */ ++ ++#define PREFERRED_RELOAD_CLASS sw_64_preferred_reload_class ++ ++/* Provide the cost of a branch. Exact meaning under development. */ ++#define BRANCH_COST(speed_p, predictable_p) 5 ++ ++/* Stack layout; function entry, exit and calling. */ ++ ++/* Define this if pushing a word on the stack ++ makes the stack pointer a smaller address. */ ++#define STACK_GROWS_DOWNWARD 1 ++ ++/* Define this to nonzero if the nominal address of the stack frame ++ is at the high-address end of the local variables; ++ that is, each additional local variable allocated ++ goes at a more negative offset in the frame. */ ++//#define FRAME_GROWS_DOWNWARD SW_64_ENABLE_ASAN ++#define FRAME_GROWS_DOWNWARD 1 ++ ++/* If we generate an insn to push BYTES bytes, ++ this says how many the stack pointer really advances by. ++ On Sw_64, don't define this because there are no push insns. */ ++/* #define PUSH_ROUNDING(BYTES) */ ++ ++/* Define this to be nonzero if stack checking is built into the ABI. */ ++#define STACK_CHECK_BUILTIN 1 ++ ++/* Define this if the maximum size of all the outgoing args is to be ++ accumulated and pushed during the prologue. The amount can be ++ found in the variable crtl->outgoing_args_size. */ ++#define ACCUMULATE_OUTGOING_ARGS 1 ++ ++/* Offset of first parameter from the argument pointer register value. */ ++ ++#define FIRST_PARM_OFFSET(FNDECL) 0 ++ ++/* Definitions for register eliminations. ++ ++ We have two registers that can be eliminated on the Sw_64. First, the ++ frame pointer register can often be eliminated in favor of the stack ++ pointer register. Secondly, the argument pointer register can always be ++ eliminated; it is replaced with either the stack or frame pointer. */ ++ ++/* This is an array of structures. Each structure initializes one pair ++ of eliminable registers. The "from" register number is given first, ++ followed by "to". Eliminations of the same "from" register are listed ++ in order of preference. */ ++ ++#define ELIMINABLE_REGS \ ++ { \ ++ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ ++ {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ ++ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ ++ { \ ++ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM \ ++ } \ ++ } ++ ++/* Round up to a multiple of 16 bytes. */ ++#define SW_64_ROUND(X) \ ++ (TARGET_SW_32ALIGN ? ROUND_UP ((X), 32) : ROUND_UP ((X), 16)) ++ ++/* Define the offset between two registers, one to be eliminated, and the other ++ its replacement, at the start of a routine. */ ++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ ++ ((OFFSET) = sw_64_initial_elimination_offset (FROM, TO)) ++ ++/* Define this if stack space is still allocated for a parameter passed ++ in a register. */ ++/* #define REG_PARM_STACK_SPACE */ ++ ++/* 1 if N is a possible register number for function argument passing. ++ On Sw_64, these are $16-$21 and $f16-$f21. */ ++ ++#define FUNCTION_ARG_REGNO_P(N) \ ++ (IN_RANGE ((N), 16, 21) || ((N) >= 16 + 32 && (N) <= 21 + 32)) ++ ++/* Define a data type for recording info about an argument list ++ during the scan of that argument list. This data type should ++ hold all necessary information about the function itself ++ and about the args processed so far, enough to enable macros ++ such as FUNCTION_ARG to determine where the next arg should go. ++ ++ On Sw_64, this is a single integer, which is a number of words ++ of arguments scanned so far. ++ Thus 6 or more means all following args should go on the stack. */ ++ ++#define CUMULATIVE_ARGS int ++ ++/* Initialize a variable CUM of type CUMULATIVE_ARGS ++ for a call to a function whose data type is FNTYPE. ++ For a library call, FNTYPE is 0. */ ++ ++#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ ++ (CUM) = 0 ++ ++/* Define intermediate macro to compute ++ the size (in registers) of an argument. */ ++ ++#define SW_64_ARG_SIZE(MODE, TYPE) \ ++ ((MODE) == TFmode || (MODE) == TCmode \ ++ ? 1 \ ++ : CEIL (((MODE) == BLKmode ? int_size_in_bytes (TYPE) \ ++ : GET_MODE_SIZE (MODE)), \ ++ UNITS_PER_WORD)) ++ ++/* Make (or fake) .linkage entry for function call. ++ IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */ ++ ++/* This macro defines the start of an assembly comment. */ ++ ++#define ASM_COMMENT_START " #" ++ ++/* This macro produces the initial definition of a function. */ ++ ++#undef ASM_DECLARE_FUNCTION_NAME ++#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ ++ sw_64_start_function (FILE, NAME, DECL); ++ ++/* This macro closes up a function definition for the assembler. */ ++ ++#undef ASM_DECLARE_FUNCTION_SIZE ++#define ASM_DECLARE_FUNCTION_SIZE(FILE, NAME, DECL) \ ++ sw_64_end_function (FILE, NAME, DECL) ++ ++/* Output any profiling code before the prologue. */ ++ ++#define PROFILE_BEFORE_PROLOGUE 1 ++ ++/* Never use profile counters. */ ++ ++#define NO_PROFILE_COUNTERS 1 ++ ++/* Output assembler code to FILE to increment profiler label # LABELNO ++ for profiling a function entry. Under SYSV, profiling is enabled ++ by simply passing -pg to the assembler and linker. */ ++ ++#define FUNCTION_PROFILER(FILE, LABELNO) ++ ++/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, ++ the stack pointer does not matter. The value is tested only in ++ functions that have frame pointers. ++ No definition is equivalent to always zero. */ ++ ++#define EXIT_IGNORE_STACK 1 ++ ++/* Define registers used by the epilogue and return instruction. */ ++ ++#define EPILOGUE_USES(REGNO) ((REGNO) == 26) ++ ++/* Length in units of the trampoline for entering a nested function. */ ++ ++#define TRAMPOLINE_SIZE 32 ++ ++/* The alignment of a trampoline, in bits. */ ++ ++#define TRAMPOLINE_ALIGNMENT 64 ++ ++/* A C expression whose value is RTL representing the value of the return ++ address for the frame COUNT steps up from the current frame. ++ FRAMEADDR is the frame pointer of the COUNT frame, or the frame pointer of ++ the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME is defined. */ ++ ++#define RETURN_ADDR_RTX sw_64_return_addr ++ ++/* Provide a definition of DWARF_FRAME_REGNUM here so that fallback unwinders ++ can use DWARF_ALT_FRAME_RETURN_COLUMN defined below. This is just the same ++ as the default definition in dwarf2out.c. */ ++#undef DWARF_FRAME_REGNUM ++#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG) ++ ++/* Before the prologue, RA lives in $26. */ ++#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26) ++#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26) ++#define DWARF_ALT_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (64) ++#define DWARF_ZERO_REG 31 ++ ++/* Describe how we implement __builtin_eh_return. */ ++#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM) ++#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 28) ++#define EH_RETURN_HANDLER_RTX \ ++ gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, \ ++ crtl->outgoing_args_size)) ++ ++/* Addressing modes, and classification of registers for them. */ ++ ++/* Macros to check register numbers against specific register classes. */ ++ ++/* These assume that REGNO is a hard or pseudo reg number. ++ They give nonzero only if REGNO is a hard reg of the suitable class ++ or a pseudo reg currently allocated to a suitable hard reg. ++ Since they use reg_renumber, they are safe only once reg_renumber ++ has been allocated, which happens in reginfo.c during register ++ allocation. */ ++ ++#define REGNO_OK_FOR_INDEX_P(REGNO) 0 ++#define REGNO_OK_FOR_BASE_P(REGNO) \ ++ ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32 || (REGNO) == 63 \ ++ || reg_renumber[REGNO] == 63) ++ ++/* Maximum number of registers that can appear in a valid memory address. */ ++#define MAX_REGS_PER_ADDRESS 1 ++ ++/* Recognize any constant value that is a valid address. For the Sw_64, ++ there are only constants none since we want to use LDI to load any ++ symbolic addresses into registers. */ ++ ++#define CONSTANT_ADDRESS_P(X) \ ++ (CONST_INT_P (X) && ((UINTVAL (X) + 0x8000) < 0x10000)) ++ ++/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx ++ and check its validity for a certain class. ++ We have two alternate definitions for each of them. ++ The usual definition accepts all pseudo regs; the other rejects ++ them unless they have been allocated suitable hard regs. ++ The symbol REG_OK_STRICT causes the latter definition to be used. ++ ++ Most source files want to accept pseudo regs in the hope that ++ they will get allocated to the class that the insn wants them to be in. ++ Source files for reload pass need to be strict. ++ After reload, it makes no difference, since pseudo regs have ++ been eliminated by then. */ ++ ++/* Nonzero if X is a hard reg that can be used as an index ++ or if it is a pseudo reg. */ ++#define REG_OK_FOR_INDEX_P(X) 0 ++ ++/* Nonzero if X is a hard reg that can be used as a base reg ++ or if it is a pseudo reg. */ ++#define NONSTRICT_REG_OK_FOR_BASE_P(X) \ ++ (REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER) ++ ++/* ??? Nonzero if X is the frame pointer, or some virtual register ++ that may eliminate to the frame pointer. These will be allowed to ++ have offsets greater than 32K. This is done because register ++ elimination offsets will change the hi/lo split, and if we split ++ before reload, we will require additional instructions. */ ++#define NONSTRICT_REG_OK_FP_BASE_P(X) \ ++ (REGNO (X) == 31 || REGNO (X) == 63 \ ++ || (REGNO (X) >= FIRST_PSEUDO_REGISTER \ ++ && REGNO (X) < LAST_VIRTUAL_POINTER_REGISTER)) ++ ++/* Nonzero if X is a hard reg that can be used as a base reg. */ ++#define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) ++ ++#ifdef REG_OK_STRICT ++#define REG_OK_FOR_BASE_P(X) STRICT_REG_OK_FOR_BASE_P (X) ++#else ++#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P (X) ++#endif ++ ++/* Try a machine-dependent way of reloading an illegitimate address ++ operand. If we find one, push the reload and jump to WIN. This ++ macro is used in only one place: `find_reloads_address' in reload.c. */ ++ ++#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_L, WIN) \ ++ do \ ++ { \ ++ rtx new_x \ ++ = sw_64_legitimize_reload_address (X, MODE, OPNUM, TYPE, IND_L); \ ++ if (new_x) \ ++ { \ ++ X = new_x; \ ++ goto WIN; \ ++ } \ ++ } while (0) ++ ++/* Specify the machine mode that this machine uses ++ for the index in the tablejump instruction. */ ++#define CASE_VECTOR_MODE SImode ++ ++/* Define as C expression which evaluates to nonzero if the tablejump ++ instruction expects the table to contain offsets from the address of the ++ table. ++ ++ Do not define this if the table should contain absolute addresses. ++ On the Sw_64, the table is really GP-relative, not relative to the PC ++ of the table, but we pretend that it is PC-relative; this should be OK, ++ but we should try to find some better way sometime. */ ++#define CASE_VECTOR_PC_RELATIVE 1 ++ ++/* Define this as 1 if `char' should by default be signed; else as 0. */ ++#define DEFAULT_SIGNED_CHAR 1 ++ ++/* Max number of bytes we can move to or from memory ++ in one reasonably fast instruction. */ ++ ++#define MOVE_MAX 8 ++ ++/* If a memory-to-memory move would take MOVE_RATIO or more simple ++ move-instruction pairs, we will do a movmem or libcall instead. ++ ++ Without byte/word accesses, we want no more than four instructions; ++ with, several single byte accesses are better. */ ++ ++#define MOVE_RATIO(speed) (TARGET_BWX ? 7 : 2) ++ ++/* Largest number of bytes of an object that can be placed in a register. ++ On the Sw_64 we have plenty of registers, so use TImode. */ ++#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode) ++ ++/* Nonzero if access to memory by bytes is no faster than for words. ++ Also nonzero if doing byte operations (specifically shifts) in registers ++ is undesirable. ++ ++ On the Sw_64, we want to not use the byte operation and instead use ++ masking operations to access fields; these will save instructions. */ ++ ++#define SLOW_BYTE_ACCESS 1 ++ ++/* Define if operations between registers always perform the operation ++ on the full register even if a narrower mode is specified. */ ++#define WORD_REGISTER_OPERATIONS 1 ++ ++/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ++ will either zero-extend or sign-extend. The value of this macro should ++ be the code that says which one of the two operations is implicitly ++ done, UNKNOWN if none. */ ++#define LOAD_EXTEND_OP(MODE) ((MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND) ++ ++/* Define if loading short immediate values into registers sign extends. */ ++#define SHORT_IMMEDIATES_SIGN_EXTEND 1 ++ ++/* The CIX ctlz and cttz instructions return 64 for zero. */ ++#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ ++ ((VALUE) = 64, TARGET_CIX ? 1 : 0) ++#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ ++ ((VALUE) = 64, TARGET_CIX ? 1 : 0) ++ ++/* Define the value returned by a floating-point comparison instruction. */ ++ ++#define FLOAT_STORE_FLAG_VALUE(MODE) \ ++ REAL_VALUE_ATOF ((TARGET_FLOAT_VAX ? "0.5" : "2.0"), (MODE)) ++ ++/* Specify the machine mode that pointers have. ++ After generation of rtl, the compiler makes no further distinction ++ between pointers and any other objects of this machine mode. */ ++#define Pmode DImode ++ ++/* Mode of a function address in a call instruction (for indexing purposes). */ ++ ++#define FUNCTION_MODE Pmode ++ ++/* Define this if addresses of constant functions ++ shouldn't be put through pseudo regs where they can be cse'd. ++ Desirable on machines where ordinary constants are expensive ++ but a CALL with constant address is cheap. ++ ++ We define this on the Sw_64 so that gen_call and gen_call_value ++ get to see the SYMBOL_REF (for the hint field of the jsr). It will ++ then copy it into a register, thus actually letting the address be ++ cse'ed. */ ++ ++#define NO_FUNCTION_CSE 1 ++ ++/* Define this to be nonzero if shift instructions ignore all but the low-order ++ few bits. */ ++#define SHIFT_COUNT_TRUNCATED 1 ++ ++/* Control the assembler format that we output. */ ++ ++/* Output to assembler file text saying following lines ++ may contain character constants, extra white space, comments, etc. */ ++#define ASM_APP_ON (TARGET_EXPLICIT_RELOCS ? "\t.set\tmacro\n" : "") ++ ++/* Output to assembler file text saying following lines ++ no longer contain unusual constructs. */ ++#define ASM_APP_OFF (TARGET_EXPLICIT_RELOCS ? "\t.set\tnomacro\n" : "") ++ ++#define TEXT_SECTION_ASM_OP "\t.text" ++ ++/* Output before writable data. */ ++ ++#define DATA_SECTION_ASM_OP "\t.data" ++ ++/* How to refer to registers in assembler output. ++ This sequence is indexed by compiler's hard-register-number (see above). */ ++ ++#define REGISTER_NAMES \ ++ { \ ++ "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", \ ++ "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", "$21", \ ++ "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", "AP", \ ++ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", \ ++ "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", \ ++ "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", \ ++ "$f28", "$f29", "$f30", "FP" \ ++ } ++ ++/* Strip name encoding when emitting labels. */ ++ ++#define ASM_OUTPUT_LABELREF(STREAM, NAME) \ ++ do \ ++ { \ ++ const char *name_ = NAME; \ ++ if (*name_ == '@' || *name_ == '%') \ ++ name_ += 2; \ ++ if (*name_ == '*') \ ++ name_++; \ ++ else \ ++ fputs (user_label_prefix, STREAM); \ ++ fputs (name_, STREAM); \ ++ } while (0) ++ ++/* Globalizing directive for a label. */ ++#define GLOBAL_ASM_OP "\t.globl " ++ ++/* Use dollar signs rather than periods in special g++ assembler names. */ ++ ++#undef NO_DOLLAR_IN_LABEL ++ ++/* This is how to store into the string LABEL ++ the symbol_ref name of an internal numbered label where ++ PREFIX is the class of label and NUM is the number within the class. ++ This is suitable for output with `assemble_name'. */ ++ ++#undef ASM_GENERATE_INTERNAL_LABEL ++#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ ++ sprintf ((LABEL), "*$%s%ld", (PREFIX), (long) (NUM)) ++ ++/* This is how to output an element of a case-vector that is relative. */ ++ ++#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ ++ fprintf (FILE, "\t.gprel32 $L%d\n", (VALUE)) ++ ++/* If we use NM, pass -g to it so it only lists globals. */ ++#define NM_FLAGS "-pg" ++ ++/* Definitions for debugging. */ ++ ++/* Correct the offset of automatic variables and arguments. Note that ++ the Sw_64 debug format wants all automatic variables and arguments ++ to be in terms of two different offsets from the virtual frame pointer, ++ which is the stack pointer before any adjustment in the function. ++ The offset for the argument pointer is fixed for the native compiler, ++ it is either zero (for the no arguments case) or large enough to hold ++ all argument registers. ++ The offset for the auto pointer is the fourth argument to the .frame ++ directive (local_offset). ++ To stay compatible with the native tools we use the same offsets ++ from the virtual frame pointer and adjust the debugger arg/auto offsets ++ accordingly. These debugger offsets are set up in output_prolog. */ ++ ++extern long sw_64_arg_offset; ++extern long sw_64_auto_offset; ++#define DEBUGGER_AUTO_OFFSET(X) \ ++ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) + sw_64_auto_offset) ++#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + sw_64_arg_offset) ++ ++#define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \ ++ sw_64_output_filename (STREAM, NAME) ++ ++/* By default, turn on GDB extensions. */ ++#define DEFAULT_GDB_EXTENSIONS 1 ++ ++/* This version don't define SYSTEM_IMPLICIT_EXTERN_C Replace ++ * NO_IMPLICIT_EXTERN_C with SYSTEM_IMPLICIT_EXTERN_C.*/ ++/* The system headers under Sw_64 systems are generally C++-aware. */ ++/*#define NO_IMPLICIT_EXTERN_C*/ ++ ++#define TARGET_SUPPORTS_WIDE_INT 1 ++#define SW64_TARGET_SUPPORT_FPCR 1 ++ ++/* Fence to use after loop using storent. */ ++#define FENCE_FOLLOWING_MOVNT \ ++ (builtin_decl_implicit (BUILT_IN_SYNC_SYNCHRONIZE)) ++ ++#undef ASM_DECLARE_OBJECT_NAME ++#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ ++ sw_64_declare_object (STREAM, NAME, "", ":\n") ++ ++#define HAVE_POST_INCREMENT (TARGET_SW8A ? 1 : 0) ++#define HAVE_POST_DECREMENT (TARGET_SW8A ? 1 : 0) ++#define HAVE_POST_MODIFY_DISP (TARGET_SW8A ? 1 : 0) ++#define USE_LOAD_POST_INCREMENT(MODE) 0 ++#define USE_STORE_POST_INCREMENT(MODE) 0 ++int ++enable_asan_check_stack (); ++#ifndef SW_64_ENABLE_ASAN ++#define SW_64_ENABLE_FULL_ASAN 1 ++#else ++#undef SW_64_ENABLE_FULL_ASAN ++#define SW_64_ENABLE_ASAN 0 ++#endif +diff --git a/gcc/config/sw_64/sw_64.md b/gcc/config/sw_64/sw_64.md +new file mode 100644 +index 000000000..a3751466a +--- /dev/null ++++ b/gcc/config/sw_64/sw_64.md +@@ -0,0 +1,7814 @@ ++;; Machine description for Sw64 for GNU C compiler ++;; Copyright (C) 1992-2022 Free Software Foundation, Inc. ++;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ++ ++;; Uses of UNSPEC in this file: ++ ++(define_c_enum "unspec" [ ++ UNSPEC_XFLT_COMPARE ++ UNSPEC_ARG_HOME ++ UNSPEC_LDGP1 ++ UNSPEC_INSXH ++ UNSPEC_MSKXH ++ UNSPEC_CVTQL ++ UNSPEC_CVTLQ ++ UNSPEC_LDGP2 ++ UNSPEC_LITERAL ++ UNSPEC_LITUSE ++ UNSPEC_SIBCALL ++ UNSPEC_SYMBOL ++ ++ UNSPEC_FRINTZ ++ UNSPEC_FRINTP ++ UNSPEC_FRINTG ++ UNSPEC_FRINTN ++ UNSPEC_FRINTI ++ ++ UNSPEC_FRECX ++ ++ ;; TLS Support ++ UNSPEC_TLSGD_CALL ++ UNSPEC_TLSLDM_CALL ++ UNSPEC_TLSGD ++ UNSPEC_TLSLDM ++ UNSPEC_DTPREL ++ UNSPEC_TPREL ++ UNSPEC_TP ++ UNSPEC_TLSRELGOT ++ UNSPEC_GOTDTPREL ++ ++ ;; Builtins ++ UNSPEC_CMPBGE ++ UNSPEC_ZAP ++ UNSPEC_AMASK ++ UNSPEC_IMPLVER ++ UNSPEC_PERR ++ UNSPEC_COPYSIGN ++ ++ ;; Atomic operations ++ UNSPEC_MB ++ UNSPEC_ATOMIC ++ UNSPEC_CMPXCHG ++ UNSPEC_XCHG ++ ++ UNSPECV_HARDWARE_PREFETCH_CNT ++ UNSPEC_PFSC ++ UNSPEC_PFTC ++ ++ UNSPEC_NTSI ++ UNSPEC_NTDI ++ UNSPEC_NTDF ++ UNSPEC_NTVEC ++ ++ UNSPEC_FIMOVS ++ ;;UNSPEC_FIMOVD ++]) ++ ++;; UNSPEC_VOLATILE: ++ ++(define_c_enum "unspecv" [ ++ UNSPECV_IMB ++ UNSPECV_BLOCKAGE ++ UNSPECV_SPECULATION_BARRIER ++ UNSPECV_SETJMPR ; builtin_setjmp_receiver ++ UNSPECV_LONGJMP ; builtin_longjmp ++ UNSPECV_TRAPB ++ UNSPECV_PSPL ; prologue_stack_probe_loop ++ UNSPECV_REALIGN ++ UNSPECV_EHR ; exception_receiver ++ UNSPECV_MCOUNT ++ UNSPECV_FORCE_MOV ++ UNSPECV_LDGP1 ++ UNSPECV_PLDGP2 ; prologue ldgp ++ UNSPECV_SET_TP ++ UNSPECV_RPCC ++ UNSPECV_SETJMPR_ER ; builtin_setjmp_receiver fragment ++ UNSPECV_LL ; load-locked ++ UNSPECV_SC ; store-conditional ++ UNSPECV_CMPXCHG ++ UNSPECV_LDGP2 ++ UNSPEC_TIE ;; TIE ++]) ++ ++;; CQImode must be handled the similarly to HImode ++;; when generating reloads. ++(define_mode_iterator RELOAD12 [QI HI CQI]) ++(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")]) ++ ++;; Other mode iterators ++(define_mode_iterator IMODE [QI HI SI DI]) ++(define_mode_iterator I12MODE [QI HI]) ++(define_mode_iterator I124MODE [QI HI SI]) ++(define_mode_iterator I24MODE [HI SI]) ++(define_mode_iterator I248MODE [HI SI DI]) ++(define_mode_iterator I48MODE [SI DI]) ++ ++(define_mode_attr DWI [(SI "DI") (DI "TI")]) ++(define_mode_attr modesuffix [(QI "b") (HI "h") (SI "w") (DI "l") ++ (V8QI "b8") (V4HI "w4") ++ (SF "%,") (DF "%-")]) ++(define_mode_attr vecmodesuffix [(QI "b8") (HI "w4")]) ++ ++(define_code_iterator any_maxmin [smax smin umax umin]) ++ ++(define_code_attr maxmin [(smax "maxs") (smin "mins") ++ (umax "maxu") (umin "minu")]) ++ ++(define_mode_iterator SFDF [SF DF]) ++(define_mode_attr SD [(SF "s") (DF "d")]) ++(define_int_iterator FRINT [UNSPEC_FRINTZ UNSPEC_FRINTP UNSPEC_FRINTN ++ UNSPEC_FRINTG UNSPEC_FRINTI]) ++ ++;; Standard pattern names for floating-point rounding instructions. ++(define_int_attr frint_pattern [(UNSPEC_FRINTZ "btrunc") ++ (UNSPEC_FRINTP "ceil") ++ (UNSPEC_FRINTN "floor") ++ (UNSPEC_FRINTI "nearbyint") ++ (UNSPEC_FRINTG "round")]) ++ ++;; frint suffix for floating-point rounding instructions. ++(define_int_attr frint_suffix [(UNSPEC_FRINTZ "_z") ++ (UNSPEC_FRINTP "_p") ++ (UNSPEC_FRINTN "_n") ++ (UNSPEC_FRINTG "_g") ++ (UNSPEC_FRINTI "")]) ++ ++;; Where necessary, the suffixes _le and _be are used to distinguish between ++;; little-endian and big-endian patterns. ++;; ++;; Note that the Unicos/Mk assembler does not support the following ++;; opcodes: mov, fmov, nop, fnop, unop. ++ ++;; Processor type -- this attribute must exactly match the processor_type ++;; enumeration in sw_64.h. ++ ++(define_attr "tune" "sw6,sw8" ++ (const (symbol_ref "((enum attr_tune) sw_64_tune)"))) ++ ++;; Define an insn type attribute. This is used in function unit delay ++;; computations, among other purposes. For the most part, we use the names ++;; defined in the documentation, but add a few that we have to know about ++;; separately. ++ ++(define_attr "type" ++ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,call,iadd,ilog,shift,icmov,fcmov, ++ icmp,imul,fadd,fmul,fmadd,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c, ++ multi,none,frint,fp" ++ (const_string "iadd")) ++ ++;; Describe a user's asm statement. ++(define_asm_attributes ++ [(set_attr "type" "multi")]) ++ ++;; Define the operand size an insn operates on. Used primarily by mul ++;; and div operations that have size dependent timings. ++ ++(define_attr "opsize" "si,di,udi" ++ (const_string "di")) ++ ++;; The TRAP attribute marks instructions that may generate traps ++;; (which are imprecise and may need a trapb if software completion ++;; is desired). ++ ++(define_attr "trap" "no,yes" ++ (const_string "no")) ++ ++;; The ROUND_SUFFIX attribute marks which instructions require a ++;; rounding-mode suffix. The value NONE indicates no suffix, ++;; the value NORMAL indicates a suffix controlled by sw_64_fprm. ++ ++(define_attr "round_suffix" "none,normal,c" ++ (const_string "none")) ++ ++;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix: ++;; NONE no suffix ++;; SU accepts only /su (cmpt et al) ++;; SUI accepts only /sui (cvtqt and cvtqs) ++;; V_SV accepts /v and /sv (cvtql only) ++;; V_SV_SVI accepts /v, /sv and /svi (cvttq only) ++;; U_SU_SUI accepts /u, /su and /sui (most fp instructions) ++;; ++;; The actual suffix emitted is controlled by sw_64_fptm. ++ ++(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui" ++ (const_string "none")) ++ ++;; The length of an instruction sequence in bytes. ++ ++(define_attr "length" "" ++ (const_int 4)) ++ ++;; The USEGP attribute marks instructions that have relocations that use ++;; the GP. ++ ++(define_attr "usegp" "no,yes" ++ (cond [(eq_attr "type" "ldsym,call") ++ (const_string "yes") ++ (eq_attr "type" "ild,fld,ist,fst") ++ (symbol_ref "((enum attr_usegp) sw_64_find_lo_sum_using_gp (insn))") ++ ] ++ (const_string "no"))) ++ ++;; The CANNOT_COPY attribute marks instructions with relocations that ++;; cannot easily be duplicated. This includes insns with gpdisp relocs ++;; since they have to stay in 1-1 correspondence with one another. This ++;; also includes call insns, since they must stay in correspondence with ++;; the immediately following gpdisp instructions. ++ ++(define_attr "cannot_copy" "false,true" ++ (const_string "false")) ++ ++;; Used to control the "enabled" attribute on a per-instruction basis. ++;; For convenience, conflate ABI issues re loading of addresses with ++;; an "isa". ++(define_attr "isa" "base,bwx,max,fix,cix,vms,ner,er,sw6a,sw6b,sw4d,sw8a" ++ (const_string "base")) ++ ++(define_attr "enabled" "" ++ (cond [(eq_attr "isa" "bwx") (symbol_ref "TARGET_BWX") ++ (eq_attr "isa" "max") (symbol_ref "TARGET_MAX") ++ (eq_attr "isa" "fix") (symbol_ref "TARGET_FIX") ++ (eq_attr "isa" "cix") (symbol_ref "TARGET_CIX") ++ (eq_attr "isa" "vms") (symbol_ref "!TARGET_ABI_OSF") ++ (eq_attr "isa" "ner") (symbol_ref "!TARGET_EXPLICIT_RELOCS") ++ (eq_attr "isa" "er") (symbol_ref "TARGET_EXPLICIT_RELOCS") ++ (eq_attr "isa" "sw6a") (symbol_ref "TARGET_SW6A") ++ (eq_attr "isa" "sw6b") (symbol_ref "TARGET_SW6B") ++ (eq_attr "isa" "sw4d") (symbol_ref "TARGET_SW4D") ++ (eq_attr "isa" "sw8a") (symbol_ref "TARGET_SW8A") ++ ] ++ (const_int 1))) ++ ++;; Include scheduling descriptions. ++ ++(include "sw6.md") ++(include "sw8.md") ++ ++ ++;; Operand and operator predicates and constraints ++ ++(include "predicates.md") ++(include "constraints.md") ++ ++ ++;; First define the arithmetic insns. Note that the 32-bit forms also ++;; sign-extend. ++ ++;; Handle 32-64 bit extension from memory to a floating point register ++;; specially, since this occurs frequently in int->double conversions. ++;; ++;; Note that while we must retain the =f case in the insn for reload's ++;; benefit, it should be eliminated after reload, so we should never emit ++;; code for that case. But we don't reject the possibility. ++ ++(define_expand "extendsidi2" ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]) ++ ++(define_insn "*cvtlq" ++ [(set (match_operand:DI 0 "register_operand" "=f") ++ (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")] ++ UNSPEC_CVTLQ))] ++ "" ++ "fcvtwl %1,%0" ++ [(set_attr "type" "fadd")]) ++ ++(define_insn "*extendsidi2_1" ++ [(set (match_operand:DI 0 "register_operand" "=r,r,!*f") ++ (sign_extend:DI ++ (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))] ++ "" ++;; "@ ++;; addw $31,%1,%0 ++;; ldw %0,%1 ++;; flds %0,%1\;fcvtwl %0,%0" ++;; else ++ "@ ++ addw $31,%1,%0 ++ ldw%U1 %0,%1 ++ flds %0,%1\;fcvtwl %0,%0" ++ [(set_attr "type" "iadd,ild,fld") ++ (set_attr "length" "*,*,8")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "hard_fp_register_operand") ++ (sign_extend:DI (match_operand:SI 1 "memory_operand")))] ++ "reload_completed" ++ [(set (match_dup 2) (match_dup 1)) ++ (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))] ++{ ++ operands[1] = adjust_address (operands[1], SFmode, 0); ++ operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0])); ++}) ++ ++;; Optimize sign-extension of SImode loads. This shows up in the wake of ++;; reload when converting fp->int. ++ ++(define_peephole2 ++ [(set (match_operand:SI 0 "hard_int_register_operand") ++ (match_operand:SI 1 "memory_operand")) ++ (set (match_operand:DI 2 "hard_int_register_operand") ++ (sign_extend:DI (match_dup 0)))] ++ "true_regnum (operands[0]) == true_regnum (operands[2]) ++ || peep2_reg_dead_p (2, operands[0])" ++ [(set (match_dup 2) ++ (sign_extend:DI (match_dup 1)))]) ++ ++(define_peephole2 ++[ ++(set (match_operand:DF 0 "register_operand") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "register_operand") ++ (match_operand:DF 3 "const0_operand")])) ++(set (match_operand:DF 4 "register_operand") ++ (match_operator:DF 5 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 6 "reg_or_0_operand") ++ (match_operand:DF 7 "reg_or_0_operand")])) ++(set (match_operand:SFDF 8 "register_operand") ++ (if_then_else:SFDF ++ (match_operand 9 "comparison_operator") ++ (match_operand:SFDF 10 "reg_or_8bit_operand") ++ (match_operand:SFDF 11 "reg_or_8bit_operand"))) ++] ++"(GET_CODE (operands[1])==LE || GET_CODE (operands[1])==LT) ++ && GET_CODE (operands[5])==EQ && GET_CODE (operands[9])==NE && flag_sw_fselect" ++ ++[ ++(set (match_operand:SFDF 8 "reg_or_0_operand") ++ (if_then_else:SFDF ++ (match_operator 1 "sw_64_fp_comparison_operator" ++ [(match_operand:SFDF 2 "reg_or_0_operand") ++ (match_operand:SFDF 3 "const0_operand")]) ++ (match_operand:SFDF 11 "reg_or_0_operand") ++ (match_operand:SFDF 10 "reg_or_0_operand"))) ++] ++) ++ ++(define_peephole2 ++[ ++(set (match_operand:DF 0 "register_operand") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "const0_operand") ++ (match_operand:DF 3 "reg_or_0_operand")])) ++(set (match_operand:DF 4 "register_operand") ++ (match_operator:DF 5 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 6 "reg_or_0_operand") ++ (match_operand:DF 7 "reg_or_0_operand")])) ++(set (match_operand:SFDF 8 "register_operand") ++ (if_then_else:SFDF ++ (match_operand 9 "comparison_operator") ++ (match_operand:SFDF 10 "reg_or_8bit_operand") ++ (match_operand:SFDF 11 "reg_or_8bit_operand"))) ++] ++"(GET_CODE (operands[1])==LE || GET_CODE (operands[1])==LT) ++ && GET_CODE (operands[5])==EQ && GET_CODE (operands[9])==NE && flag_sw_fselect" ++ ++[ ++(set (match_operand:SFDF 8 "reg_or_0_operand") ++ (if_then_else:SFDF ++ (match_operator 1 "sw_64_fp_comparison_operator" ++ [(match_operand:SFDF 3 "reg_or_0_operand") ++ (match_operand:SFDF 2 "const0_operand")]) ++ (match_operand:SFDF 10 "reg_or_0_operand") ++ (match_operand:SFDF 11 "reg_or_0_operand"))) ++] ++) ++ ++(define_peephole2 ++[ ++(set (match_operand:DF 0 "register_operand") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "register_operand") ++ (match_operand:DF 3 "const0_operand")])) ++(set (match_operand:DF 4 "register_operand") ++ (match_operator:DF 5 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 6 "register_operand") ++ (match_operand:DF 7 "const0_operand")])) ++(set (match_operand:SFDF 8 "register_operand") ++ (if_then_else:SFDF ++ (match_operand 9 "comparison_operator") ++ (match_operand:SFDF 10 "reg_or_8bit_operand") ++ (match_operand:SFDF 11 "reg_or_8bit_operand"))) ++] ++"GET_CODE (operands[1])==EQ && GET_CODE (operands[5])==EQ && ++ (GET_CODE (operands[9])==NE || GET_CODE (operands[9])==EQ)&& ++ (operands[0] == operands[6]) && flag_sw_fselect" ++[ ++(set (match_operand:SFDF 8 "reg_or_0_operand") ++ (if_then_else:SFDF ++ (match_operator 9 "sw_64_fp_comparison_operator" ++ [(match_operand:SFDF 2 "reg_or_0_operand") ++ (match_operand:SFDF 3 "const0_operand")]) ++ (match_operand:SFDF 10 "reg_or_0_operand") ++ (match_operand:SFDF 11 "reg_or_0_operand"))) ++] ++) ++ ++(define_insn "addsi3" ++ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ++ (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") ++ (match_operand:SI 2 "add_operand" "rI,O,K,L")))] ++ "" ++ "@ ++ addw %r1,%2,%0 ++ subw %r1,%n2,%0 ++ ldi %0,%2(%r1) ++ ldih %0,%h2(%r1)") ++ ++(define_split ++ [(set (match_operand:SI 0 "register_operand") ++ (plus:SI (match_operand:SI 1 "register_operand") ++ (match_operand:SI 2 "const_int_operand")))] ++ "! add_operand (operands[2], SImode)" ++ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) ++ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] ++{ ++ HOST_WIDE_INT val = INTVAL (operands[2]); ++ HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); ++ HOST_WIDE_INT rest = val - low; ++ ++ operands[3] = GEN_INT (rest); ++ operands[4] = GEN_INT (low); ++}) ++ ++(define_insn "*addsi_se" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (sign_extend:DI ++ (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") ++ (match_operand:SI 2 "sext_add_operand" "rI,O"))))] ++ "" ++ "@ ++ addw %r1,%2,%0 ++ subw %r1,%n2,%0") ++ ++(define_insn "*addsi_se2" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (sign_extend:DI ++ (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") ++ (match_operand:DI 2 "sext_add_operand" "rI,O")) ++ 0)))] ++ "" ++ "@ ++ addw %r1,%2,%0 ++ subw %r1,%n2,%0") ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extend:DI ++ (plus:SI (match_operand:SI 1 "reg_not_elim_operand") ++ (match_operand:SI 2 "const_int_operand")))) ++ (clobber (match_operand:SI 3 "reg_not_elim_operand"))] ++ "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0 ++ && INTVAL (operands[2]) % 4 == 0" ++ [(set (match_dup 3) (match_dup 4)) ++ (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3) ++ (match_dup 5)) ++ (match_dup 1))))] ++{ ++ HOST_WIDE_INT val = INTVAL (operands[2]) / 4; ++ int mult = 4; ++ ++ if (val % 2 == 0) ++ val /= 2, mult = 8; ++ ++ operands[4] = GEN_INT (val); ++ operands[5] = GEN_INT (mult); ++}) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extend:DI ++ (plus:SI (match_operator:SI 1 "comparison_operator" ++ [(match_operand 2) ++ (match_operand 3)]) ++ (match_operand:SI 4 "add_operand")))) ++ (clobber (match_operand:DI 5 "register_operand"))] ++ "" ++ [(set (match_dup 5) (match_dup 6)) ++ (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))] ++{ ++ operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode, ++ operands[2], operands[3]); ++ operands[7] = gen_lowpart (SImode, operands[5]); ++}) ++ ++(define_expand "adddi3" ++ [(set (match_operand:DI 0 "register_operand") ++ (plus:DI (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "add_operand")))]) ++ ++(define_insn "*adddi_er_lo16_dtp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lo_sum:DI (match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "dtp16_symbolic_operand")))] ++ "HAVE_AS_TLS" ++ "ldi %0,%2(%1)\t\t!dtprel") ++ ++(define_insn "*adddi_er_hi32_dtp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (plus:DI (match_operand:DI 1 "register_operand" "r") ++ (high:DI (match_operand:DI 2 "dtp32_symbolic_operand"))))] ++ "HAVE_AS_TLS" ++ "ldih %0,%2(%1)\t\t!dtprelhi") ++ ++(define_insn "*adddi_er_lo32_dtp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lo_sum:DI (match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "dtp32_symbolic_operand")))] ++ "HAVE_AS_TLS" ++ "ldi %0,%2(%1)\t\t!dtprello") ++ ++(define_insn "*adddi_er_lo16_tp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lo_sum:DI (match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "tp16_symbolic_operand")))] ++ "HAVE_AS_TLS" ++ "ldi %0,%2(%1)\t\t!tprel") ++ ++(define_insn "*adddi_er_hi32_tp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (plus:DI (match_operand:DI 1 "register_operand" "r") ++ (high:DI (match_operand:DI 2 "tp32_symbolic_operand"))))] ++ "HAVE_AS_TLS" ++ "ldih %0,%2(%1)\t\t!tprelhi") ++ ++(define_insn "*adddi_er_lo32_tp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lo_sum:DI (match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "tp32_symbolic_operand")))] ++ "HAVE_AS_TLS" ++ "ldi %0,%2(%1)\t\t!tprello") ++ ++(define_insn "*adddi_er_high_l" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (plus:DI (match_operand:DI 1 "register_operand" "r") ++ (high:DI (match_operand:DI 2 "local_symbolic_operand"))))] ++ "TARGET_EXPLICIT_RELOCS && reload_completed" ++ "ldih %0,%2(%1)\t\t!gprelhigh" ++ [(set_attr "usegp" "yes")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (high:DI (match_operand:DI 1 "local_symbolic_operand")))] ++ "TARGET_EXPLICIT_RELOCS && reload_completed" ++ [(set (match_dup 0) ++ (plus:DI (match_dup 2) (high:DI (match_dup 1))))] ++ "operands[2] = pic_offset_table_rtx;") ++ ++;; We used to expend quite a lot of effort choosing addl/subl/ldi. ++;; With complications like ++;; ++;; The NT stack unwind code can't handle a subl to adjust the stack ++;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3, ++;; the exception handling code will loop if a subl is used and an ++;; exception occurs. ++;; ++;; The 19980616 change to emit prologues as RTL also confused some ++;; versions of GDB, which also interprets prologues. This has been ++;; fixed as of GDB 4.18, but it does not harm to unconditionally ++;; use ldi here. ++;; ++;; and the fact that the three insns schedule exactly the same, it's ++;; just not worth the effort. ++ ++(define_insn "*adddi_internal" ++ [(set (match_operand:DI 0 "register_operand" "=r,r,r") ++ (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r") ++ (match_operand:DI 2 "add_operand" "r,K,L")))] ++ "" ++ "@ ++ addl %1,%2,%0 ++ ldi %0,%2(%1) ++ ldih %0,%h2(%1)") ++ ++;; ??? Allow large constants when basing off the frame pointer or some ++;; virtual register that may eliminate to the frame pointer. This is ++;; done because register elimination offsets will change the hi/lo split, ++;; and if we split before reload, we will require additional instructions. ++ ++(define_insn "*adddi_fp_hack" ++ [(set (match_operand:DI 0 "register_operand" "=r,r,r") ++ (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r") ++ (match_operand:DI 2 "const_int_operand" "K,L,n")))] ++ "NONSTRICT_REG_OK_FP_BASE_P (operands[1]) ++ && INTVAL (operands[2]) >= 0 ++ /* This is the largest constant an ldi+ldih pair can add, minus ++ an upper bound on the displacement between SP and AP during ++ register elimination. See INITIAL_ELIMINATION_OFFSET. */ ++ && INTVAL (operands[2]) ++ < (0x7fff8000 ++ - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD ++ - SW_64_ROUND (crtl->outgoing_args_size) ++ - (SW_64_ROUND (get_frame_size () ++ + max_reg_num () * UNITS_PER_WORD ++ + crtl->args.pretend_args_size) ++ - crtl->args.pretend_args_size))" ++ "@ ++ ldi %0,%2(%1) ++ ldih %0,%h2(%1) ++ #") ++ ++;; Don't do this if we are adjusting SP since we don't want to do it ++;; in two steps. Don't split FP sources for the reason listed above. ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (plus:DI (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "const_int_operand")))] ++ "! add_operand (operands[2], DImode) ++ && operands[0] != stack_pointer_rtx ++ && operands[1] != frame_pointer_rtx ++ && operands[1] != arg_pointer_rtx" ++ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) ++ (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] ++{ ++ HOST_WIDE_INT val = INTVAL (operands[2]); ++ HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); ++ HOST_WIDE_INT rest = val - low; ++ rtx rest_rtx = GEN_INT (rest); ++ ++ operands[4] = GEN_INT (low); ++ if (satisfies_constraint_L (rest_rtx)) ++ operands[3] = rest_rtx; ++ else if (can_create_pseudo_p ()) ++ { ++ operands[3] = gen_reg_rtx (DImode); ++ emit_move_insn (operands[3], operands[2]); ++ emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); ++ DONE; ++ } ++ else ++ FAIL; ++}) ++ ++; *sadd->*saddl/*saddq ++(define_insn "*saddl" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (plus:SI ++ (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") ++ (match_operand:SI 2 "const48_operand" "I,I")) ++ (match_operand:SI 3 "sext_add_operand" "rI,O")))] ++ "" ++ "@ ++ s%2addw %1,%3,%0 ++ s%2subw %1,%n3,%0") ++ ++(define_insn "*saddq" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (plus:DI ++ (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r") ++ (match_operand:DI 2 "const48_operand" "I,I")) ++ (match_operand:DI 3 "sext_add_operand" "rI,O")))] ++ "" ++ "@ ++ s%2addl %1,%3,%0 ++ s%2subl %1,%n3,%0") ++ ++(define_insn "*saddl_se" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (sign_extend:DI ++ (plus:SI ++ (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") ++ (match_operand:SI 2 "const48_operand" "I,I")) ++ (match_operand:SI 3 "sext_add_operand" "rI,O"))))] ++ "" ++ "@ ++ s%2addw %1,%3,%0 ++ s%2subw %1,%n3,%0") ++ ++(define_insn "*sxaddw" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (plus:SI ++ (subreg:SI ++ (ashift:DI ++ (subreg:DI (match_operand:SI 1 "reg_not_elim_operand" "r,r") 0) ++ (match_operand:DI 2 "const_int_operand" "I,I")) ++ 0) ++ (match_operand:SI 3 "sext_add_operand" "rI,O")))] ++ "flag_sw_sxaddl==1 && (INTVAL (operands[2])==3 || INTVAL (operands[2])==2)" ++ { ++ switch (which_alternative) ++ { ++ case 0: ++ if (INTVAL (operands[2]) == 3) ++ return "s8addw %1,%3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4addw %1,%3,%0"; ++ case 1: ++ if (INTVAL (operands[2]) == 3) ++ return "s8subw %1,%n3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4subw %1,%n3,%0"; ++ default: ++ gcc_unreachable (); ++ } ++ }) ++ ++(define_insn "*sxsubw" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (minus:SI ++ (subreg:SI ++ (ashift:DI ++ (subreg:DI(match_operand:SI 1 "reg_not_elim_operand" "r,r") 0) ++ (match_operand:DI 2 "const_int_operand" "I,I")) ++ 0) ++ (match_operand:SI 3 "sext_add_operand" "rI,O")))] ++ "flag_sw_sxaddl==1 && (INTVAL (operands[2])==3 || INTVAL (operands[2])==2)" ++ { ++ switch (which_alternative) ++ { ++ case 0: ++ if (INTVAL (operands[2]) == 3) ++ return "s8subw %1,%3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4subw %1,%3,%0"; ++ case 1: ++ if (INTVAL (operands[2]) == 3) ++ return "s8addw %1,%n3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4addw %1,%n3,%0"; ++ default: ++ gcc_unreachable (); ++ } ++ }) ++ ++(define_insn "*sxaddl" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (plus:DI ++ (ashift:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r") ++ (match_operand:DI 2 "const_int_operand" "I,I")) ++ (match_operand:DI 3 "sext_add_operand" "rI,O")))] ++ "flag_sw_sxaddl==1 && (INTVAL (operands[2])==3 || INTVAL (operands[2])==2)" ++ { ++ switch (which_alternative) ++ { ++ case 0: ++ if (INTVAL (operands[2]) == 3) ++ return "s8addl %1,%3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4addl %1,%3,%0"; ++ case 1: ++ if (INTVAL (operands[2]) == 3) ++ return "s8subl %1,%n3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4subl %1,%n3,%0"; ++ default: ++ gcc_unreachable (); ++ } ++ }) ++ ++ ++ ++(define_insn "*sxsubl" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (minus:DI ++ (ashift:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r") ++ (match_operand:DI 2 "const_int_operand" "I,I")) ++ (match_operand:DI 3 "sext_add_operand" "rI,O")))] ++ "flag_sw_sxaddl==1 && (INTVAL (operands[2])==3 || INTVAL (operands[2])==2)" ++ { ++ switch (which_alternative) ++ { ++ case 0: ++ if (INTVAL (operands[2]) == 3) ++ return "s8subl %1,%3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4subl %1,%3,%0"; ++ case 1: ++ if (INTVAL (operands[2]) == 3) ++ return "s8addl %1,%n3,%0"; ++ if (INTVAL (operands[2]) == 2) ++ return "s4addl %1,%n3,%0"; ++ default: ++ gcc_unreachable (); ++ } ++ }) ++ ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extend:DI ++ (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator" ++ [(match_operand 2) ++ (match_operand 3)]) ++ (match_operand:SI 4 "const48_operand")) ++ (match_operand:SI 5 "sext_add_operand")))) ++ (clobber (match_operand:DI 6 "reg_not_elim_operand"))] ++ "" ++ [(set (match_dup 6) (match_dup 7)) ++ (set (match_dup 0) ++ (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4)) ++ (match_dup 5))))] ++{ ++ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode, ++ operands[2], operands[3]); ++ operands[8] = gen_lowpart (SImode, operands[6]); ++}) ++ ++(define_insn "neg2" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (neg:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")))] ++ "" ++ "sub $31,%1,%0") ++ ++(define_insn "*negsi_se" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI (neg:SI ++ (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))] ++ "" ++ "subw $31,%1,%0") ++ ++(define_insn "sub3" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ") ++ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))] ++ "" ++ "sub %r1,%2,%0") ++ ++(define_insn "*subsi_se" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ++ (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] ++ "" ++ "subw %r1,%2,%0") ++ ++(define_insn "*subsi_se2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "reg_or_8bit_operand" "rI")) ++ 0)))] ++ "" ++ "subw %r1,%2,%0") ++ ++(define_insn "*ssubl" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (minus:SI ++ (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") ++ (match_operand:SI 2 "const48_operand" "I")) ++ (match_operand:SI 3 "reg_or_8bit_operand" "rI")))] ++ "" ++ "s%2subw %1,%3,%0") ++ ++(define_insn "*ssubq" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (minus:DI ++ (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r") ++ (match_operand:DI 2 "const48_operand" "I")) ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] ++ "" ++ "s%2subl %1,%3,%0") ++ ++(define_insn "*ssubl_se" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (minus:SI ++ (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") ++ (match_operand:SI 2 "const48_operand" "I")) ++ (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))] ++ "" ++ "s%2subw %1,%3,%0") ++ ++(define_insn "mul3" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ") ++ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))] ++ "" ++ "mul %r1,%2,%0" ++ [(set_attr "type" "imul") ++ (set_attr "opsize" "")]) ++ ++(define_insn "*mulsi_se" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") ++ (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] ++ "" ++ "mulw %r1,%2,%0" ++ [(set_attr "type" "imul") ++ (set_attr "opsize" "si")]) ++ ++(define_expand "umuldi3_highpart" ++ [(set (match_operand:DI 0 "register_operand") ++ (truncate:DI ++ (lshiftrt:TI ++ (mult:TI (zero_extend:TI ++ (match_operand:DI 1 "register_operand")) ++ (match_operand:DI 2 "reg_or_8bit_operand")) ++ (const_int 64))))] ++ "" ++{ ++ if (REG_P (operands[2])) ++ operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]); ++}) ++ ++(define_insn "*umuldi3_highpart_reg" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (truncate:DI ++ (lshiftrt:TI ++ (mult:TI (zero_extend:TI ++ (match_operand:DI 1 "register_operand" "r")) ++ (zero_extend:TI ++ (match_operand:DI 2 "register_operand" "r"))) ++ (const_int 64))))] ++ "" ++ "umulh %1,%2,%0" ++ [(set_attr "type" "imul") ++ (set_attr "opsize" "udi")]) ++ ++(define_insn "*umuldi3_highpart_const" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (truncate:DI ++ (lshiftrt:TI ++ (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) ++ (match_operand:TI 2 "cint8_operand" "I")) ++ (const_int 64))))] ++ "" ++ "umulh %1,%2,%0" ++ [(set_attr "type" "imul") ++ (set_attr "opsize" "udi")]) ++ ++(define_expand "umulditi3" ++ [(set (match_operand:TI 0 "register_operand") ++ (mult:TI ++ (zero_extend:TI (match_operand:DI 1 "reg_no_subreg_operand")) ++ (zero_extend:TI (match_operand:DI 2 "reg_no_subreg_operand"))))] ++ "" ++{ ++ rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); ++ emit_insn (gen_muldi3 (l, operands[1], operands[2])); ++ emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2])); ++ emit_move_insn (gen_lowpart (DImode, operands[0]), l); ++ emit_move_insn (gen_highpart (DImode, operands[0]), h); ++ DONE; ++}) ++ ++;; The divide and remainder operations take their inputs from r24 and ++;; r25, put their output in r27, and clobber r23 and r28 on all systems. ++;; ++;; ??? Force sign-extension here because some versions of SYSV and ++;; Interix/NT don't do the right thing if the inputs are not properly ++;; sign-extended. But Linux, for instance, does not have this ++;; problem. Is it worth the complication here to eliminate the sign ++;; extension? ++ ++(define_code_iterator any_divmod [div mod udiv umod]) ++ ++(define_expand "si3" ++ [(set (match_dup 3) ++ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"))) ++ (set (match_dup 4) ++ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand"))) ++ (parallel [(set (match_dup 5) ++ (sign_extend:DI ++ (any_divmod:SI (match_dup 3) (match_dup 4)))) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))]) ++ (set (match_operand:SI 0 "nonimmediate_operand") ++ (subreg:SI (match_dup 5) 0))] ++ "" ++{ ++ operands[3] = gen_reg_rtx (DImode); ++ operands[4] = gen_reg_rtx (DImode); ++ operands[5] = gen_reg_rtx (DImode); ++}) ++ ++(define_expand "di3" ++ [(parallel [(set (match_operand:DI 0 "register_operand") ++ (any_divmod:DI ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "register_operand"))) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))])] ++ "") ++ ++(define_insn "int_div_use_float_si" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")]))) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DF 56)) ++ (clobber (reg:DF 60))] ++ "flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==DIV)" ++ "ifmovd %1,$f23 ++ fcvtld $f23,$f28 ++ fcpys $f28,$f28,$f23 ++ ifmovd %2,$f24 ++ fcvtld $f24,$f28 ++ fdivd $f23,$f28,$f24 ++ fcvtdl_z $f24,$f23 ++ fimovd $f23,%0" ++ [(set_attr "type" "fdiv")]) ++ ++(define_insn "int_divu_use_float_si" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")]))) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DF 56)) ++ (clobber (reg:DF 60))] ++ "flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==UDIV)" ++ "zap %1,240,%1 ++ zap %2,240,%2 ++ ifmovd %1,$f23 ++ fcvtld $f23,$f28 ++ fcpys $f28,$f28,$f23 ++ ifmovd %2,$f24 ++ fcvtld $f24,$f28 ++ fdivd $f23,$f28,$f24 ++ fcvtdl_z $f24,$f23 ++ fimovd $f23,%0" ++ [(set_attr "type" "fdiv")]) ++ ++(define_insn "int_rem_use_float_si" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")]))) ++ (clobber (reg:DF 54)) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DF 56)) ++ (clobber (reg:DF 60))] ++ "flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==MOD)" ++ "ifmovd %1,$f24 ++ fcvtld $f24,$f28 ++ fcpys $f28,$f28,$f24 ++ ifmovd %2,$f23 ++ fcvtld $f23,$f28 ++ fdivd $f24,$f28,$f22 ++ fcvtdl_z $f22,$f23 ++ fcvtld $f23,$f22 ++ fnmad $f22,$f28,$f24,$f23 ++ fcvtdl_z $f23,$f22 ++ fimovd $f22,%0" ++ [(set_attr "type" "fdiv")]) ++ ++(define_insn "int_remu_use_float_si" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")]))) ++ (clobber (reg:DF 54)) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DF 56)) ++ (clobber (reg:DF 60))] ++ "flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==UMOD)" ++ "zap %1,240,%1 ++ zap %2,240,%2 ++ ifmovd %1,$f22 ++ fcvtld $f22,$f24 ++ ifmovd %2,$f22 ++ fcvtld $f22,$f28 ++ fdivd $f24,$f28,$f23 ++ fcvtdl_z $f23,$f22 ++ fcvtld $f22,$f23 ++ fnmad $f23,$f28,$f24,$f22 ++ fcvtdl_z $f22,$f23 ++ fimovd $f23,%0" ++ [(set_attr "type" "fdiv")]) ++ ++(define_insn_and_split "*divmodsi_internal_er" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")]))) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))] ++ "TARGET_EXPLICIT_RELOCS && !(TARGET_SW8A && flag_sw_int_divmod)" ++ "#" ++ "&& reload_completed" ++ [(parallel [(set (match_dup 0) ++ (sign_extend:DI (match_dup 3))) ++ (use (match_dup 0)) ++ (use (match_dup 4)) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))])] ++{ ++ if (flag_sw_int_div_opt) ++ { ++ const char *str; ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: ++ emit_insn (gen_int_div_use_float_si (operands[0], operands[1], operands[2], operands[3])); ++ break; ++ case UDIV: ++ emit_insn (gen_int_divu_use_float_si (operands[0], operands[1], operands[2], operands[3])); ++ break; ++ case MOD: ++ emit_insn (gen_int_rem_use_float_si (operands[0], operands[1], operands[2], operands[3])); ++ break; ++ case UMOD: ++ emit_insn (gen_int_remu_use_float_si (operands[0], operands[1], operands[2], operands[3])); ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ } ++ else ++ { ++ const char *str; ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: ++ str = "__divw"; ++ break; ++ case UDIV: ++ str = "__divwu"; ++ break; ++ case MOD: ++ str = "__remw"; ++ break; ++ case UMOD: ++ str = "__remwu"; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx, ++ gen_rtx_SYMBOL_REF (DImode, str), ++ operands[4])); ++ } ++} ++ [(set_attr "type" "call") ++ (set_attr "length" "8")]) ++ ++(define_insn "*divmodsi_internal_er_1" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")]))) ++ (use (match_operand:DI 4 "register_operand" "c")) ++ (use (match_operand 5 "const_int_operand")) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))] ++ "TARGET_EXPLICIT_RELOCS && !(TARGET_SW8A && flag_sw_int_divmod)" ++ { ++ if (flag_sw_int_div_opt) ++ { ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: ++ case UDIV: ++ case MOD: ++ case UMOD: ++ return ""; ++ } ++ } ++ else ++ { ++ return "call $23,($27),__%E3%j5"; ++ } ++ } ++ [(set_attr "type" "call") ++ (set_attr "length" "4")]) ++ ++(define_insn "*divmodsi_internal" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI (match_operator:SI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "register_operand" "r")]))) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))] ++ "TARGET_SW8A && flag_sw_int_divmod" ++ { ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: return "divw %1,%2,%0"; ++ case UDIV: return "udivw %1,%2,%0"; ++ case MOD: return "remw %1,%2,%0"; ++ case UMOD: return "uremw %1,%2,%0"; ++ } ++ } ++ [(set_attr "length" "4")]) ++ ++(define_insn "int_div_use_float_di" ++[(set (match_operand:DI 0 "register_operand" "=c") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")])) ++ (use (match_operand:DI 4 "register_operand" "r")) ++ (use (match_operand:DI 5 "symbolic_operand")) ++ (use (match_operand 6 "const_int_operand")) ++ (use (label_ref:DI (match_operand 7))) ++ (use (label_ref:DI (match_operand 8))) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DI 27)) ++ (clobber (reg:DI 28)) ++ (clobber (reg:DF 59)) ++ (clobber (reg:DF 60))] ++ "TARGET_EXPLICIT_RELOCS && flag_sw_int_div_opt == 1 &&(GET_CODE (operands[3])==DIV)" ++ "srl %1,52,$28 ++ srl %2,52,$27 ++ bis $28,$27,$28 ++ bne $28,%l7 ++ ifmovd %1,$f23 ++ fcvtld $f23,$f27 ++ ifmovd %2,$f28 ++ fcvtld $f28,$f23 ++ fdivd $f27,$f23,$f28 ++ fcvtdl_z $f28,$f23 ++ fimovd $f23,%0 ++ br %l8 ++%l7: ++ ldl %0,%5(%4)\t\t!literal!%6 ++ call $23,($27),__%E3%j6 ++%l8:" ++ [(set_attr "cannot_copy" "true") ++ (set_attr "type" "fdiv")]) ++ ++(define_insn "int_divu_use_float_di" ++[(set (match_operand:DI 0 "register_operand" "=c") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")])) ++ (use (match_operand:DI 4 "register_operand" "r")) ++ (use (match_operand:DI 5 "symbolic_operand")) ++ (use (match_operand 6 "const_int_operand")) ++ (use (label_ref:DI (match_operand 7))) ++ (use (label_ref:DI (match_operand 8))) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DI 27)) ++ (clobber (reg:DI 28)) ++ (clobber (reg:DF 59)) ++ (clobber (reg:DF 60))] ++ "TARGET_EXPLICIT_RELOCS && flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==UDIV)" ++ "srl %1,52,$28 ++ srl %2,52,$27 ++ bis $28,$27,$28 ++ bne $28,%l7 ++ ifmovd %1,$f23 ++ fcvtld $f23,$f27 ++ ifmovd %2,$f28 ++ fcvtld $f28,$f23 ++ fdivd $f27,$f23,$f28 ++ fcvtdl_z $f28,$f23 ++ fimovd $f23,%0 ++ br %l8 ++%l7: ++ ldl %0,%5(%4)\t\t!literal!%6 ++ call $23,($27),__%E3%j6 ++%l8:" ++ [(set_attr "cannot_copy" "true") ++ (set_attr "type" "fdiv")]) ++ ++(define_insn "int_rem_use_float_di" ++[(set (match_operand:DI 0 "register_operand" "=c") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")])) ++ (use (match_operand:DI 4 "register_operand" "r")) ++ (use (match_operand:DI 5 "symbolic_operand")) ++ (use (match_operand 6 "const_int_operand")) ++ (use (label_ref:DI (match_operand 7))) ++ (use (label_ref:DI (match_operand 8))) ++ (clobber (reg:DF 54)) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DI 27)) ++ (clobber (reg:DI 28)) ++ (clobber (reg:DF 56)) ++ (clobber (reg:DF 60))] ++ "TARGET_EXPLICIT_RELOCS && flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==MOD)" ++ "srl %1,52,$28 ++ srl %2,52,$27 ++ bis $28,$27,$28 ++ bne $28,%l7 ++ ifmovd %1,$f22 ++ fcvtld $f22,$f24 ++ ifmovd %2,$f22 ++ fcvtld $f22,$f28 ++ fdivd $f24,$f28,$f22 ++ fcvtdl_z $f22,$f23 ++ fcvtld $f23,$f22 ++ fnmad $f22,$f28,$f24,$f23 ++ fcvtdl_z $f23,$f22 ++ fimovd $f22,%0 ++ br %l8 ++%l7: ++ ldl %0,%5(%4)\t\t!literal!%6 ++ call $23,($27),__%E3%j6 ++%l8:" ++ [(set_attr "cannot_copy" "true") ++ (set_attr "type" "fdiv")]) ++ ++(define_insn "int_remu_use_float_di" ++[(set (match_operand:DI 0 "register_operand" "=c") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")])) ++ (use (match_operand:DI 4 "register_operand" "r")) ++ (use (match_operand:DI 5 "symbolic_operand")) ++ (use (match_operand 6 "const_int_operand")) ++ (use (label_ref:DI (match_operand 7))) ++ (use (label_ref:DI (match_operand 8))) ++ (clobber (reg:DF 54)) ++ (clobber (reg:DF 55)) ++ (clobber (reg:DI 27)) ++ (clobber (reg:DI 28)) ++ (clobber (reg:DF 56)) ++ (clobber (reg:DF 60))] ++ "TARGET_EXPLICIT_RELOCS && flag_sw_int_div_opt == 1 ++ &&(GET_CODE (operands[3])==UMOD)" ++ " srl %1,52,$28 ++ srl %2,52,$27 ++ bis $28,$27,$28 ++ bne $28,%l7 ++ ifmovd %1,$f22 ++ fcvtld $f22,$f24 ++ ifmovd %2,$f22 ++ fcvtld $f22,$f28 ++ fdivd $f24,$f28,$f23 ++ fcvtdl_z $f23,$f22 ++ fcvtld $f22,$f23 ++ fnmad $f23,$f28,$f24,$f22 ++ fcvtdl_z $f22,$f23 ++ fimovd $f23,%0 ++ br %l8 ++%l7: ++ ldl %0,%5(%4)\t\t!literal!%6 ++ call $23,($27),__%E3%j6 ++%l8:" ++ [(set_attr "cannot_copy" "true") ++ (set_attr "type" "fdiv")]) ++ ++(define_insn_and_split "*divmoddi_internal_er" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")])) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))] ++ "TARGET_EXPLICIT_RELOCS && !(TARGET_SW8A && flag_sw_int_divmod)" ++ "#" ++ "&& reload_completed" ++ [(parallel [(set (match_dup 0) (match_dup 3)) ++ (use (match_dup 0)) ++ (use (match_dup 4)) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))])] ++{ ++ if (flag_sw_int_div_opt) ++ { ++ const char *str; ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ operands[7] = gen_label_rtx (); ++ operands[8] = gen_label_rtx (); ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: ++ str = "__divl"; ++ emit_insn (gen_int_div_use_float_di (operands[0],operands[1],operands[2],operands[3],pic_offset_table_rtx ,gen_rtx_SYMBOL_REF (DImode, str),operands[4],operands[7],operands[8])); ++ break; ++ case UDIV: ++ str = "__divlu"; ++ emit_insn (gen_int_divu_use_float_di (operands[0],operands[1],operands[2],operands[3],pic_offset_table_rtx ,gen_rtx_SYMBOL_REF (DImode, str),operands[4],operands[7],operands[8])); ++ break; ++ case MOD: ++ str = "__reml"; ++ emit_insn (gen_int_rem_use_float_di (operands[0],operands[1],operands[2],operands[3],pic_offset_table_rtx ,gen_rtx_SYMBOL_REF (DImode, str),operands[4],operands[7],operands[8])); ++ break; ++ case UMOD: ++ str = "__remlu"; ++ emit_insn (gen_int_remu_use_float_di (operands[0],operands[1],operands[2],operands[3],pic_offset_table_rtx ,gen_rtx_SYMBOL_REF (DImode, str),operands[4],operands[7],operands[8])); ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ } ++ else ++ { ++ const char *str; ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: ++ str = "__divl"; ++ break; ++ case UDIV: ++ str = "__divlu"; ++ break; ++ case MOD: ++ str = "__reml"; ++ break; ++ case UMOD: ++ str = "__remlu"; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx, ++ gen_rtx_SYMBOL_REF (DImode, str), ++ operands[4])); ++ } ++} ++ [(set_attr "type" "call") ++ (set_attr "length" "8")]) ++ ++(define_insn "*divmoddi_internal_er_1" ++ [(set (match_operand:DI 0 "register_operand" "=c") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "a") ++ (match_operand:DI 2 "register_operand" "b")])) ++ (use (match_operand:DI 4 "register_operand" "c")) ++ (use (match_operand 5 "const_int_operand")) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))] ++ "TARGET_EXPLICIT_RELOCS && !(TARGET_SW8A && flag_sw_int_divmod)" ++ { ++ if (flag_sw_int_div_opt) ++ { ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: ++ case UDIV: ++ case MOD: ++ case UMOD: ++ return ""; ++ } ++ } ++ else ++ { ++ return "call $23,($27),__%E3%j5"; ++ } ++ } ++ [(set_attr "type" "call") ++ (set_attr "length" "4")]) ++ ++(define_insn "*divmoddi_internal" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (match_operator:DI 3 "divmod_operator" ++ [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "register_operand" "r")])) ++ (clobber (reg:DI 23)) ++ (clobber (reg:DI 28))] ++ "TARGET_SW8A && flag_sw_int_divmod" ++ { ++ switch (GET_CODE (operands[3])) ++ { ++ case DIV: return "divl %1,%2,%0"; ++ case UDIV: return "udivl %1,%2,%0"; ++ case MOD: return "reml %1,%2,%0"; ++ case UMOD: return "ureml %1,%2,%0"; ++ } ++ } ++ [(set_attr "length" "4")]) ++ ++;; Next are the basic logical operations. We only expose the DImode operations ++;; to the rtl expanders, but SImode versions exist for combine as well as for ++;; the atomic operation splitters. ++ ++(define_insn "*andsi_internal" ++ [(set (match_operand:SI 0 "register_operand" "=r,r,r") ++ (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ") ++ (match_operand:SI 2 "and_operand" "rI,N,M")))] ++ "" ++ "@ ++ and %r1,%2,%0 ++ bic %r1,%N2,%0 ++ zapnot %r1,%m2,%0" ++ [(set_attr "type" "ilog,ilog,shift")]) ++ ++(define_insn "anddi3" ++ [(set (match_operand:DI 0 "register_operand" "=r,r,r") ++ (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ") ++ (match_operand:DI 2 "and_operand" "rI,N,M")))] ++ "" ++ "@ ++ and %r1,%2,%0 ++ bic %r1,%N2,%0 ++ zapnot %r1,%m2,%0" ++ [(set_attr "type" "ilog,ilog,shift")]) ++ ++;; There are times when we can split an AND into two AND insns. This occurs ++;; when we can first clear any bytes and then clear anything else. For ++;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07". ++;; Only do this when running on 64-bit host since the computations are ++;; too messy otherwise. ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (and:DI (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "const_int_operand")))] ++ "! and_operand (operands[2], DImode)" ++ [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3))) ++ (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))] ++{ ++ unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]); ++ unsigned HOST_WIDE_INT mask2 = mask1; ++ int i; ++ ++ /* For each byte that isn't all zeros, make it all ones. */ ++ for (i = 0; i < 64; i += 8) ++ if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0) ++ mask1 |= (HOST_WIDE_INT) 0xff << i; ++ ++ /* Now turn on any bits we've just turned off. */ ++ mask2 |= ~ mask1; ++ ++ operands[3] = GEN_INT (mask1); ++ operands[4] = GEN_INT (mask2); ++}) ++ ++(define_insn "zero_extendqi2" ++ [(set (match_operand:I248MODE 0 "register_operand" "=r,r") ++ (zero_extend:I248MODE ++ (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))] ++ "" ++ "@ ++ and %1,0xff,%0 ++ ldbu%U1 %0,%1" ++ [(set_attr "type" "ilog,ild") ++ (set_attr "isa" "*,bwx")]) ++ ++(define_insn "zero_extendhi2" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r,r") ++ (zero_extend:I48MODE ++ (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))] ++ "" ++ "@ ++ zapnot %1,3,%0 ++ ldhu%U1 %0,%1" ++ [(set_attr "type" "shift,ild") ++ (set_attr "isa" "*,bwx")]) ++ ++(define_insn "zero_extendsidi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] ++ "" ++ "zapnot %1,15,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "andnot3" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (and:I48MODE ++ (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")) ++ (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))] ++ "" ++ "bic %r2,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*iorsi_internal" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") ++ (match_operand:SI 2 "or_operand" "rI,N")))] ++ "" ++ "@ ++ bis %r1,%2,%0 ++ ornot %r1,%N2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "iordi3" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") ++ (match_operand:DI 2 "or_operand" "rI,N")))] ++ "" ++ "@ ++ bis %r1,%2,%0 ++ ornot %r1,%N2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*one_cmplsi_internal" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] ++ "" ++ "ornot $31,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "one_cmpldi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] ++ "" ++ "ornot $31,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*iornot3" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (ior:I48MODE ++ (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")) ++ (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))] ++ "" ++ "ornot %r2,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*xorsi_internal" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") ++ (match_operand:SI 2 "or_operand" "rI,N")))] ++ "" ++ "@ ++ xor %r1,%2,%0 ++ eqv %r1,%N2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "xordi3" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") ++ (match_operand:DI 2 "or_operand" "rI,N")))] ++ "" ++ "@ ++ xor %r1,%2,%0 ++ eqv %r1,%N2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*xornot3" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (not:I48MODE (xor:I48MODE ++ (match_operand:I48MODE 1 "register_operand" "%rJ") ++ (match_operand:I48MODE 2 "register_operand" "rI"))))] ++ "" ++ "eqv %r1,%2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_expand "ffsdi2" ++ [(set (match_dup 2) ++ (ctz:DI (match_operand:DI 1 "register_operand"))) ++ (set (match_dup 3) ++ (plus:DI (match_dup 2) (const_int 1))) ++ (set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI (eq (match_dup 1) (const_int 0)) ++ (const_int 0) (match_dup 3)))] ++ "" ++{ ++ operands[2] = gen_reg_rtx (DImode); ++ operands[3] = gen_reg_rtx (DImode); ++}) ++ ++(define_insn "clzdi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (clz:DI (match_operand:DI 1 "register_operand" "r")))] ++ "" ++ "ctlz %1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_insn "ctzdi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ctz:DI (match_operand:DI 1 "register_operand" "r")))] ++ "" ++ "cttz %1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_insn "popcountdi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (popcount:DI (match_operand:DI 1 "register_operand" "r")))] ++ "" ++ "ctpop %1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_insn "popcountsi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (popcount:SI (match_operand:SI 1 "register_operand" "r")))] ++ "" ++ "zapnot %1,15,%0\;ctpop %0,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_insn "bswapsi2_internal" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (bswap:SI (match_operand:SI 1 "register_operand" "r")))] ++ "TARGET_SW8A && flag_sw_rev == 1" ++ "revbw %1,%0" ++ [(set_attr "isa" "sw8a")]) ++ ++(define_expand "bswapsi2" ++ [(set (match_operand:SI 0 "register_operand") ++ (bswap:SI (match_operand:SI 1 "register_operand")))] ++ "!optimize_size" ++{ ++ if (TARGET_SW8A == 0 || flag_sw_rev != 1) ++ { ++ rtx t0, t1; ++ ++ t0 = gen_reg_rtx (DImode); ++ t1 = gen_reg_rtx (DImode); ++ ++ emit_insn (gen_inslh (t0, gen_lowpart (DImode, operands[1]), GEN_INT (7))); ++ emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]), ++ GEN_INT (24))); ++ emit_insn (gen_iordi3 (t1, t0, t1)); ++ emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16))); ++ emit_insn (gen_anddi3 (t1, t1, sw_64_expand_zap_mask (0x5))); ++ emit_insn (gen_anddi3 (t0, t0, sw_64_expand_zap_mask (0xa))); ++ emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0), ++ gen_lowpart (SImode, t1))); ++ DONE; ++ } ++ else ++ { ++ emit_insn (gen_bswapsi2_internal (operands[0], operands[1])); ++ DONE; ++ } ++}) ++ ++;; Next come the shifts and the various extract and insert operations. ++ ++(define_insn "bswapdi2_internal" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (bswap:DI (match_operand:DI 1 "register_operand" "r")))] ++ "TARGET_SW8A && flag_sw_rev == 1" ++ "revbl %1,%0" ++ [(set_attr "isa" "sw8a")]) ++ ++(define_expand "bswapdi2" ++ [(set (match_operand:DI 0 "register_operand") ++ (bswap:DI (match_operand:DI 1 "register_operand")))] ++ "!optimize_size" ++{ ++ if (TARGET_SW8A == 0 || flag_sw_rev != 1) ++ { ++ rtx t0, t1; ++ ++ t0 = gen_reg_rtx (DImode); ++ t1 = gen_reg_rtx (DImode); ++ ++ /* This method of shifting and masking is not specific to Sw_64, but ++ is only profitable on Sw_64 because of our handy byte zap insn. */ ++ ++ emit_insn (gen_lshrdi3 (t0, operands[1], GEN_INT (32))); ++ emit_insn (gen_ashldi3 (t1, operands[1], GEN_INT (32))); ++ emit_insn (gen_iordi3 (t1, t0, t1)); ++ ++ emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16))); ++ emit_insn (gen_ashldi3 (t1, t1, GEN_INT (16))); ++ emit_insn (gen_anddi3 (t0, t0, sw_64_expand_zap_mask (0xcc))); ++ emit_insn (gen_anddi3 (t1, t1, sw_64_expand_zap_mask (0x33))); ++ emit_insn (gen_iordi3 (t1, t0, t1)); ++ ++ emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8))); ++ emit_insn (gen_ashldi3 (t1, t1, GEN_INT (8))); ++ emit_insn (gen_anddi3 (t0, t0, sw_64_expand_zap_mask (0xaa))); ++ emit_insn (gen_anddi3 (t1, t1, sw_64_expand_zap_mask (0x55))); ++ emit_insn (gen_iordi3 (operands[0], t0, t1)); ++ DONE; ++ } ++ else ++ { ++ emit_insn (gen_bswapdi2_internal (operands[0], operands[1])); ++ DONE; ++ } ++}) ++ ++(define_insn "lshrsi3" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (lshiftrt:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ++ (match_operand:SI 2 "reg_or_5bit_operand" "rY")))] ++ "TARGET_SW8A && flag_sw_shift_word == 1" ++ "srlw %r1,%2,%0" ++ [(set_attr "type" "shift") ++ (set_attr "isa" "sw8a")]) ++ ++(define_insn "ashrsi3" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ++ (match_operand:SI 2 "register_operand" "r")))] ++ "TARGET_SW8A && flag_sw_shift_word == 1" ++ "sraw %r1,%2,%0" ++ [(set_attr "type" "shift") ++ (set_attr "isa" "sw8a")]) ++ ++(define_insn "rotlsi3" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (subreg:SI ++ (zero_extend:DI (rotate:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ++ (match_operand:SI 2 "reg_or_5bit_operand" "rY"))) 0))] ++ "TARGET_SW8A && flag_sw_shift_word == 1" ++ "rolw %r1,%2,%0" ++ [(set_attr "type" "shift") ++ (set_attr "isa" "sw8a")]) ++ ++(define_insn "rotldi3" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (rotate:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] ++ "TARGET_SW8A && flag_sw_shift_word == 1" ++ "roll %r1,%2,%0" ++ [(set_attr "type" "shift") ++ (set_attr "isa" "sw8a")]) ++ ++(define_insn "ashldi3" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") ++ (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))] ++ "" ++{ ++ switch (which_alternative) ++ { ++ case 0: ++ if (operands[2] == const1_rtx) ++ return "addl %r1,%r1,%0"; ++ else ++ return "sll %r1,%2,%0"; ++ case 1: ++ if (TARGET_SW8A == 0 || flag_sw_shift_word != 1) ++ return "sll %r1,%2,%0"; ++ else ++ return "slll %r1,%2,%0"; ++ default: ++ gcc_unreachable (); ++ } ++} ++ [(set_attr "type" "iadd,shift")]) ++ ++(define_expand "ashlsi3" ++ [(set (match_operand:SI 0 "register_operand") ++ (ashift:SI (match_operand:SI 1 "reg_or_0_operand") ++ (match_operand:SI 2 "reg_or_5bit_operand")))]) ++ ++(define_insn "*ashlsi3_sll" ++ [(set (match_operand:SI 0 "register_operand" "=r,&r") ++ (ashift:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") ++ (match_operand:SI 2 "reg_or_5bit_operand" "P,rS")))] ++ "TARGET_SW8A == 0 || flag_sw_shift_word != 1" ++{ ++ switch (which_alternative) ++ { ++ case 0: ++ if (operands[2] == const1_rtx) ++ return "addw %r1,%r1,%0"; ++ else ++ return "s%P2addw %r1,0,%0"; ++ case 1: ++ if (REG_P (operands[2])) ++ return "and %2,31,%0\;sll %r1,%0,%0"; ++ else ++ return "sll %r1,%2,%0"; ++ default: ++ gcc_unreachable (); ++ } ++} ++ [(set_attr "type" "iadd,shift")]) ++ ++(define_insn "*ashlsi3_sllw" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (ashift:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") ++ (match_operand:SI 2 "reg_or_5bit_operand" "P,rY")))] ++ "TARGET_SW8A && flag_sw_shift_word == 1" ++{ ++ switch (which_alternative) ++ { ++ case 0: ++ if (operands[2] == const1_rtx) ++ return "addw %r1,%r1,%0"; ++ else ++ return "s%P2addw %r1,0,%0"; ++ case 1: ++ return "sllw %r1,%2,%0"; ++ default: ++ gcc_unreachable (); ++ } ++} ++ [(set_attr "type" "iadd,shift") ++ (set_attr "isa" "*,sw8a")]) ++ ++(define_insn "*ashldi_se" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "const_int_operand" "P")) ++ 0)))] ++ "IN_RANGE (INTVAL (operands[2]), 1, 3)" ++{ ++ if (operands[2] == const1_rtx) ++ return "addw %r1,%r1,%0"; ++ else ++ return "s%P2addw %r1,0,%0"; ++} ++ [(set_attr "type" "iadd")]) ++ ++(define_insn "lshrdi3" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] ++ "" ++{ ++ if (TARGET_SW8A == 0 || flag_sw_shift_word != 1) ++ return "srl %r1,%2,%0"; ++ else ++ return "srll %r1,%2,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++(define_insn "ashrdi3" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] ++ "" ++{ ++ if (TARGET_SW8A == 0 || flag_sw_shift_word != 1) ++ return "sra %r1,%2,%0"; ++ else ++ return "sral %r1,%2,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++(define_insn "extendqi2" ++ [(set (match_operand:I24MODE 0 "register_operand" "=r") ++ (sign_extend:I24MODE ++ (match_operand:QI 1 "register_operand" "r")))] ++ "" ++ "sextb %1,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_expand "extendqidi2" ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extend:DI (match_operand:QI 1 "general_operand")))] ++ "" ++{ ++ operands[1] = force_reg (QImode, operands[1]); ++}) ++ ++(define_insn "*extendqidi2_bwx" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))] ++ "" ++ "sextb %1,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "extendhisi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] ++ "" ++ "sexth %1,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_expand "extendhidi2" ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extend:DI (match_operand:HI 1 "general_operand")))] ++ "" ++{ ++ operands[1] = force_reg (HImode, operands[1]); ++}) ++ ++(define_insn "*extendhidi2_bwx" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))] ++ "" ++ "sexth %1,%0" ++ [(set_attr "type" "shift")]) ++ ++;; Here's how we sign extend an unaligned byte and halfword. Doing this ++;; as a pattern saves one instruction. The code is similar to that for ++;; the unaligned loads (see below). ++;; ++;; Operand 1 is the address, operand 0 is the result. ++ ++(define_expand "unaligned_extendqidi" ++ [(set (match_dup 3) ++ (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8)))) ++ (set (match_dup 4) ++ (ashift:DI (match_dup 3) ++ (minus:DI (const_int 64) ++ (ashift:DI ++ (and:DI (match_dup 2) (const_int 7)) ++ (const_int 3))))) ++ (set (match_operand:QI 0 "register_operand") ++ (ashiftrt:DI (match_dup 4) (const_int 56)))] ++ "" ++{ ++ operands[0] = gen_lowpart (DImode, operands[0]); ++ operands[2] = get_unaligned_offset (operands[1], 1); ++ operands[3] = gen_reg_rtx (DImode); ++ operands[4] = gen_reg_rtx (DImode); ++}) ++ ++(define_expand "unaligned_extendhidi" ++ [(set (match_dup 3) ++ (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8)))) ++ (set (match_dup 4) ++ (ashift:DI (match_dup 3) ++ (minus:DI (const_int 64) ++ (ashift:DI ++ (and:DI (match_dup 2) (const_int 7)) ++ (const_int 3))))) ++ (set (match_operand:HI 0 "register_operand") ++ (ashiftrt:DI (match_dup 4) (const_int 48)))] ++ "" ++{ ++ operands[0] = gen_lowpart (DImode, operands[0]); ++ operands[2] = get_unaligned_offset (operands[1], 2); ++ operands[3] = gen_reg_rtx (DImode); ++ operands[4] = gen_reg_rtx (DImode); ++}) ++ ++(define_insn "*extxl_const" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "mode_width_operand" "n") ++ (match_operand:DI 3 "mul8_operand" "I")))] ++ "" ++{ ++ if (INTVAL (operands[2])==8) ++ return "extlb %r1,%s3,%0"; ++ else if (INTVAL (operands[2])==16) ++ return "extlh %r1,%s3,%0"; ++ else if (INTVAL (operands[2])==32) ++ return "extlw %r1,%s3,%0"; ++ else if (INTVAL (operands[2])==64) ++ return "extll %r1,%s3,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++(define_insn "extxl" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extract:DI ++ (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "mode_width_operand" "n") ++ (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI") ++ (const_int 3))))] ++ "" ++{ ++ if (INTVAL (operands[2])==8) ++ return "extlb %r1,%3,%0"; ++ else if (INTVAL (operands[2])==16) ++ return "extlh %r1,%3,%0"; ++ else if (INTVAL (operands[2])==32) ++ return "extlw %r1,%3,%0"; ++ else if (INTVAL (operands[2])==64) ++ return "extll %r1,%3,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++;; Combine has some strange notion of preserving existing undefined behavior ++;; in shifts larger than a word size. So capture these patterns that it ++;; should have turned into zero_extracts. ++(define_insn "*extxl_1" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 3))) ++ (match_operand:DI 3 "mode_mask_operand" "n")))] ++ "" ++{ ++ if (INTVAL (operands[3]) == 0xff) ++ return "extlb %r1,%2,%0"; ++ else if (INTVAL (operands[3]) == 0xffff) ++ return "extlh %r1,%2,%0"; ++ else if (INTVAL (operands[3]) == 0xffffffff) ++ return "extlw %r1,%2,%0"; ++ else if (INTVAL (operands[3]) == -1) ++ return "extll %r1,%2,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++(define_insn "*extql_2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 3))))] ++ "" ++ "extll %1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "extqh" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI ++ (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (minus:DI (const_int 64) ++ (ashift:DI ++ (and:DI ++ (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 7)) ++ (const_int 3)))))] ++ "" ++ "exthl %r1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "extwh" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI ++ (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (const_int 65535)) ++ (minus:DI (const_int 64) ++ (ashift:DI ++ (and:DI ++ (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 7)) ++ (const_int 3)))))] ++ "" ++ "exthh %r1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "extlh" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI ++ (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (const_int 2147483647)) ++ (minus:DI (const_int 64) ++ (ashift:DI ++ (and:DI ++ (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 7)) ++ (const_int 3)))))] ++ "" ++ "exthw %r1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++;; This converts an extXl into an extXh with an appropriate adjustment ++;; to the address calculation. ++(define_insn "insbl_const" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (zero_extend:DI ++ (match_operand:QI 1 "register_operand" "r")) ++ (match_operand:DI 2 "mul8_operand" "I")))] ++ "" ++ "inslb %1,%s2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "inswl_const" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (zero_extend:DI ++ (match_operand:HI 1 "register_operand" "r")) ++ (match_operand:DI 2 "mul8_operand" "I")))] ++ "" ++ "inslh %1,%s2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "insll_const" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (zero_extend:DI ++ (match_operand:SI 1 "register_operand" "r")) ++ (match_operand:DI 2 "mul8_operand" "I")))] ++ "" ++ "inslw %1,%s2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "insbl" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (zero_extend:DI ++ (match_operand:QI 1 "register_operand" "r")) ++ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 3))))] ++ "" ++ "inslb %1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "inswl" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (zero_extend:DI ++ (match_operand:HI 1 "register_operand" "r")) ++ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 3))))] ++ "" ++ "inslh %1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "insll" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (zero_extend:DI ++ (match_operand:SI 1 "register_operand" "r")) ++ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 3))))] ++ "" ++ "inslw %1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "insql" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (ashift:DI (match_operand:DI 1 "register_operand" "r") ++ (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ++ (const_int 3))))] ++ "" ++ "insll %1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++;; Combine has this sometimes habit of moving the and outside of the ++;; shift, making life more interesting. ++(define_insn "*insxl" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "mul8_operand" "I")) ++ (match_operand:DI 3 "const_int_operand" "i")))] ++ "((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) ++ == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) ++ || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) ++ == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) ++ || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2]) ++ == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))" ++{ ++#if HOST_BITS_PER_WIDE_INT == 64 ++ if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) ++ == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) ++ return "inslb %1,%s2,%0"; ++ if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) ++ == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) ++ return "inslh %1,%s2,%0"; ++ if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2]) ++ == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) ++ return "inslw %1,%s2,%0"; ++#endif ++ gcc_unreachable (); ++} ++ [(set_attr "type" "shift")]) ++ ++;; We do not include the insXh insns because they are complex to express ++;; and it does not appear that we would ever want to generate them. ++;; ++;; Since we need them for block moves, though, cop out and use unspec. ++(define_insn "insxh" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "mode_width_operand" "n") ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI")] ++ UNSPEC_INSXH))] ++ "" ++{ ++ if (INTVAL (operands[2])==16) ++ return "inshh %r1,%3,%0"; ++ else if (INTVAL (operands[2])==32) ++ return "inshw %r1,%3,%0"; ++ else if (INTVAL (operands[2])==64) ++ return "inshl %r1,%3,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++(define_insn "mskxl" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (and:DI (not:DI (ashift:DI ++ (match_operand:DI 2 "mode_mask_operand" "n") ++ (ashift:DI ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI") ++ (const_int 3)))) ++ (match_operand:DI 1 "reg_or_0_operand" "rJ")))] ++ "" ++{ ++ if (INTVAL (operands[2]) == 0xff) ++ return "masklb %r1,%3,%0"; ++ else if (INTVAL (operands[2]) == 0xffff) ++ return "masklh %r1,%3,%0"; ++ else if (INTVAL (operands[2]) == 0xffffffff) ++ return "masklw %r1,%3,%0"; ++ else if (INTVAL (operands[2]) == -1) ++ return "maskll %r1,%3,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++;; We do not include the mskXh insns because it does not appear we would ++;; ever generate one. ++;; ++;; Again, we do for block moves and we use unspec again. ++ ++(define_insn "mskxh" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "mode_width_operand" "n") ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI")] ++ UNSPEC_MSKXH))] ++ "" ++{ ++ if (INTVAL (operands[2])==16) ++ return "maskhh %r1,%3,%0"; ++ else if (INTVAL (operands[2])==32) ++ return "maskhw %r1,%3,%0"; ++ else if (INTVAL (operands[2])==64) ++ return "maskhl %r1,%3,%0"; ++} ++ [(set_attr "type" "shift")]) ++ ++(define_insn_and_split "*ze_and_ne" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (const_int 1) ++ (match_operand 2 "const_int_operand" "I")))] ++ "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8" ++ "#" ++ "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8" ++ [(set (match_dup 0) ++ (and:DI (match_dup 1) (match_dup 3))) ++ (set (match_dup 0) ++ (ne:DI (match_dup 0) (const_int 0)))] ++ "operands[3] = GEN_INT (1 << INTVAL (operands[2]));") ++ ++;; Floating-point operations. All the double-precision insns can extend ++;; from single, so indicate that. The exception are the ones that simply ++;; play with the sign bits; it's not clear what to do there. ++ ++(define_mode_iterator FMODE [SF DF]) ++ ++(define_mode_attr opmode [(SF "si") (DF "di")]) ++ ++(define_insn "abs2" ++ [(set (match_operand:FMODE 0 "register_operand" "=f") ++ (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))] ++ "TARGET_FP" ++ "fcpys $f31,%R1,%0" ++ [(set_attr "type" "fcpys")]) ++ ++(define_insn "*nabs2" ++ [(set (match_operand:FMODE 0 "register_operand" "=f") ++ (neg:FMODE ++ (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP" ++ "fcpysn $f31,%R1,%0" ++ [(set_attr "type" "fadd")]) ++ ++(define_expand "abstf2" ++ [(parallel [(set (match_operand:TF 0 "register_operand") ++ (abs:TF (match_operand:TF 1 "reg_or_0_operand"))) ++ (use (match_dup 2))])] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));") ++ ++(define_insn_and_split "*abstf_internal" ++ [(set (match_operand:TF 0 "register_operand" "=r") ++ (abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG"))) ++ (use (match_operand:DI 2 "register_operand" "r"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "#" ++ "&& reload_completed" ++ [(const_int 0)] ++ "sw_64_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;") ++ ++(define_insn "neg2" ++ [(set (match_operand:FMODE 0 "register_operand" "=f") ++ (neg:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))] ++ "TARGET_FP" ++ "fcpysn %R1,%R1,%0" ++ [(set_attr "type" "fadd")]) ++ ++(define_expand "negtf2" ++ [(parallel [(set (match_operand:TF 0 "register_operand") ++ (neg:TF (match_operand:TF 1 "reg_or_0_operand"))) ++ (use (match_dup 2))])] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));") ++ ++(define_insn_and_split "*negtf_internal" ++ [(set (match_operand:TF 0 "register_operand" "=r") ++ (neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG"))) ++ (use (match_operand:DI 2 "register_operand" "r"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "#" ++ "&& reload_completed" ++ [(const_int 0)] ++ "sw_64_split_tfmode_frobsign (operands, gen_xordi3); DONE;") ++ ++(define_insn "copysign3" ++ [(set (match_operand:FMODE 0 "register_operand" "=f") ++ (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG")] ++ UNSPEC_COPYSIGN))] ++ "TARGET_FP" ++ "fcpys %R2,%R1,%0" ++ [(set_attr "type" "fadd")]) ++ ++(define_insn "*ncopysign3" ++ [(set (match_operand:FMODE 0 "register_operand" "=f") ++ (neg:FMODE ++ (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG")] ++ UNSPEC_COPYSIGN)))] ++ "TARGET_FP" ++ "fcpysn %R2,%R1,%0" ++ [(set_attr "type" "fadd")]) ++ ++(define_insn "*add3" ++ [(set (match_operand:FMODE 0 "register_operand" "=&f,&f") ++ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 0" ++ "fadd%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*add3_same" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 1" ++ "fadd%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "add3" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP" ++ "" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++ ++(define_insn "*fmasf4" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (fma:SF (match_operand:SF 1 "register_operand" "f") ++ (match_operand:SF 2 "register_operand" "f") ++ (match_operand:SF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 0" ++ "fmas %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fmasf4_same" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF (match_operand:SF 1 "register_operand" "f") ++ (match_operand:SF 2 "register_operand" "f") ++ (match_operand:SF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 1" ++ "fmas %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "fmasf4" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF (match_operand:SF 1 "register_operand" "f") ++ (match_operand:SF 2 "register_operand" "f") ++ (match_operand:SF 3 "register_operand" "f")))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fmadf4" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (fma:DF (match_operand:DF 1 "register_operand" "f") ++ (match_operand:DF 2 "register_operand" "f") ++ (match_operand:DF 3 "register_operand" "f")))] ++ "flag_sw_sdsame== 0" ++ "fmad %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fmadf4_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF (match_operand:DF 1 "register_operand" "f") ++ (match_operand:DF 2 "register_operand" "f") ++ (match_operand:DF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 1" ++ "fmad %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "fmadf4" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF (match_operand:DF 1 "register_operand" "f") ++ (match_operand:DF 2 "register_operand" "f") ++ (match_operand:DF 3 "register_operand" "f")))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fmssf4" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (fma:SF ++ (match_operand:SF 1 "register_operand" "f") ++ (match_operand:SF 2 "register_operand" "f") ++ (neg:SF (match_operand:SF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 0" ++ "fmss %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*fmssf4_same" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF ++ (match_operand:SF 1 "register_operand" "f") ++ (match_operand:SF 2 "register_operand" "f") ++ (neg:SF (match_operand:SF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 1" ++ "fmss %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fmsdf4" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (fma:DF ++ (match_operand:DF 1 "register_operand" "f") ++ (match_operand:DF 2 "register_operand" "f") ++ (neg:DF (match_operand:DF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 0" ++ "fmsd %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*fmsdf4_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF ++ (match_operand:DF 1 "register_operand" "f") ++ (match_operand:DF 2 "register_operand" "f") ++ (neg:DF (match_operand:DF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 1" ++ "fmsd %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "fmsdf4" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF ++ (match_operand:DF 1 "register_operand" "f") ++ (match_operand:DF 2 "register_operand" "f") ++ (neg:DF (match_operand:DF 3 "register_operand" "f"))))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fnmasf4" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (fma:SF ++ (neg:SF (match_operand:SF 1 "register_operand" "f")) ++ (match_operand:SF 2 "register_operand" "f") ++ (match_operand:SF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 0" ++ "fnmas %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fnmasf4_same" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF ++ (neg:SF (match_operand:SF 1 "register_operand" "f")) ++ (match_operand:SF 2 "register_operand" "f") ++ (match_operand:SF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 1" ++ "fnmas %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_expand "fnmasf4" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF ++ (neg:SF (match_operand:SF 1 "register_operand" "f")) ++ (match_operand:SF 2 "register_operand" "f") ++ (match_operand:SF 3 "register_operand" "f")))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*fnmadf4" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (fma:DF ++ (neg:DF (match_operand:DF 1 "register_operand" "f")) ++ (match_operand:DF 2 "register_operand" "f") ++ (match_operand:DF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 0" ++ "fnmad %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fnmadf4_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF ++ (neg:DF (match_operand:DF 1 "register_operand" "f")) ++ (match_operand:DF 2 "register_operand" "f") ++ (match_operand:DF 3 "register_operand" "f")))] ++ "flag_sw_sdsame == 1" ++ "fnmad %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_expand "fnmadf4" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF ++ (neg:DF (match_operand:DF 1 "register_operand" "f")) ++ (match_operand:DF 2 "register_operand" "f") ++ (match_operand:DF 3 "register_operand" "f")))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*fnmssf4" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (fma:SF ++ (neg:SF (match_operand:SF 1 "register_operand" "f")) ++ (match_operand:SF 2 "register_operand" "f") ++ (neg:SF (match_operand:SF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 0" ++ "fnmss %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fnmssf4_same" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF ++ (neg:SF (match_operand:SF 1 "register_operand" "f")) ++ (match_operand:SF 2 "register_operand" "f") ++ (neg:SF (match_operand:SF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 1" ++ "fnmss %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_expand "fnmssf4" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (fma:SF ++ (neg:SF (match_operand:SF 1 "register_operand" "f")) ++ (match_operand:SF 2 "register_operand" "f") ++ (neg:SF (match_operand:SF 3 "register_operand" "f"))))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*fnmsdf4" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (fma:DF ++ (neg:DF (match_operand:DF 1 "register_operand" "f")) ++ (match_operand:DF 2 "register_operand" "f") ++ (neg:DF (match_operand:DF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 0" ++ "fnmsd %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*fnmsdf4_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF ++ (neg:DF (match_operand:DF 1 "register_operand" "f")) ++ (match_operand:DF 2 "register_operand" "f") ++ (neg:DF (match_operand:DF 3 "register_operand" "f"))))] ++ "flag_sw_sdsame == 1" ++ "fnmsd %R1,%R2,%R3,%0" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_expand "fnmsdf4" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (fma:DF ++ (neg:DF (match_operand:DF 1 "register_operand" "f")) ++ (match_operand:DF 2 "register_operand" "f") ++ (neg:DF (match_operand:DF 3 "register_operand" "f"))))] ++ "flag_sw_fma==1 && TARGET_FP" ++ "" ++ [(set_attr "type" "fmadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++ ++(define_insn "*adddf_ext1" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (plus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fadd%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*adddf_ext1_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (plus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fadd%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*adddf_ext2" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (plus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "%fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fadd%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*adddf_ext2_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (plus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "%fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fadd%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "addtf3" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand")) ++ (use (match_operand:TF 2 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_arith (PLUS, operands); DONE;") ++ ++(define_insn "*sub3" ++ [(set (match_operand:FMODE 0 "register_operand" "=&f,&f") ++ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 0" ++ "fsub%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*sub3_same" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 1" ++ "fsub%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "sub3" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP" ++ "" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*subdf_ext1" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (minus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fsub%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*subdf_ext1_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (minus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fsub%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*subdf_ext2" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fsub%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*subdf_ext2_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fsub%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*subdf_ext3" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (minus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fsub%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*subdf_ext3_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (minus:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fsub%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "subtf3" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand")) ++ (use (match_operand:TF 2 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_arith (MINUS, operands); DONE;") ++ ++(define_insn "*mul3" ++ [(set (match_operand:FMODE 0 "register_operand" "=&f,&f") ++ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 0" ++ "fmul%/ %R1,%R2,%0" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*mul3_same" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 1" ++ "fmul%/ %R1,%R2,%0" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "mul3" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP" ++ "" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++ ++(define_insn "*muldf_ext1" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (mult:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fmul%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*muldf_ext1_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (mult:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fmul%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*muldf_ext2" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (mult:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "%fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fmul%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*muldf_ext2_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (mult:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "%fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fmul%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fmul") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "multf3" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand")) ++ (use (match_operand:TF 2 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_arith (MULT, operands); DONE;") ++ ++(define_insn "*div3" ++ [(set (match_operand:FMODE 0 "register_operand" "=&f,&f") ++ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 0" ++ "fdiv%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "opsize" "") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*div3_same" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 1" ++ "fdiv%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "opsize" "") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++;; Floating point reciprocal approximation ++(define_insn "fre" ++ [(set (match_operand:SFDF 0 "register_operand" "=f") ++ (unspec:SFDF [(match_operand:SFDF 1 "register_operand" "f")] ++ UNSPEC_FRECX))] ++ "(flag_sw_recip || flag_sw_recip_precision) && flag_reciprocal_math && TARGET_SW8A" ++ "frec %1,%0" ++ [(set_attr "type" "fp")]) ++ ++(define_expand "div3" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP" ++ { ++ if ((flag_sw_recip || flag_sw_recip_precision) && flag_reciprocal_math && TARGET_SW8A) ++ { ++ if (operands[1] == CONST0_RTX (mode)) ++ operands[1] = gen_move_reg (operands[1]); ++ ++ if (operands[2] == CONST0_RTX (mode)) ++ operands[2] = gen_move_reg (operands[2]); ++ ++ sw_64_emit_swdiv (operands[0], operands[1], operands[2], true); ++ DONE; ++ } ++ }) ++ ++(define_insn "*div3_fpr" ++ [(set (match_operand:FMODE 0 "register_operand" "=f") ++ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG") ++ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP" ++ "fdiv%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "opsize" "") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*divdf_ext1" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fdiv%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*divdf_ext1_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (match_operand:DF 2 "reg_or_0_operand" "fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fdiv%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*divdf_ext2" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fdiv%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*divdf_ext2_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fdiv%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_insn "*divdf_ext3" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (div:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fdiv%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++(define_insn "*divdf_ext3_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (div:DF (float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG")) ++ (float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG"))))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fdiv%-%/ %R1,%R2,%0" ++ [(set_attr "type" "fdiv") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui")]) ++ ++(define_expand "divtf3" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand")) ++ (use (match_operand:TF 2 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_arith (DIV, operands); DONE;") ++ ++(define_insn "2" ++ [(set (match_operand:SFDF 0 "register_operand" "=f") ++ (unspec:SFDF [(match_operand:SFDF 1 "register_operand" "f")] ++ FRINT))] ++ "TARGET_SW8A && flag_sw_fprnd == 1" ++ "fri %1, %0" ++ [(set_attr "type" "frint")]) ++ ++(define_insn "*sqrt2" ++ [(set (match_operand:FMODE 0 "register_operand" "=&f,&f") ++ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 0" ++ "fsqrt%/ %R1,%0" ++ [(set_attr "type" "fsqrt") ++ (set_attr "opsize" "") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*sqrt2_same" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 1" ++ "fsqrt%/ %R1,%0" ++ [(set_attr "type" "fsqrt") ++ (set_attr "opsize" "") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "sqrt2" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP && TARGET_FIX" ++ "" ++ [(set_attr "type" "fsqrt") ++ (set_attr "opsize" "") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++;; Define conversion operators between DFmode and SImode, using the cvtql ++;; instruction. To allow combine et al to do useful things, we keep the ++;; operation as a unit until after reload, at which point we split the ++;; instructions. ++;; ++;; Note that we (attempt to) only consider this optimization when the ++;; ultimate destination is memory. If we will be doing further integer ++;; processing, it is cheaper to do the truncation in the int regs. ++ ++(define_insn "*cvtql" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")] ++ UNSPEC_CVTQL))] ++ "TARGET_FP && flag_sw_sdsame == 0" ++ "fcvtlw%/ %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "v_sv")]) ++(define_insn "*cvtql_same" ++ [(set (match_operand:SF 0 "register_operand" "=f") ++ (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")] ++ UNSPEC_CVTQL))] ++ "TARGET_FP && flag_sw_sdsame == 1" ++ "fcvtlw%/ %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "v_sv")]) ++ ++(define_insn_and_split "*fix_truncdfsi_ieee" ++ [(set (match_operand:SI 0 "memory_operand" "=m") ++ (subreg:SI ++ (match_operator:DI 4 "fix_operator" ++ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0)) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && sw_64_fptm >= SW_64_FPTM_SU && flag_sw_cmov == 0" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)])) ++ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) ++ (set (match_dup 5) (match_dup 3))] ++{ ++ operands[5] = adjust_address (operands[0], SFmode, 0); ++} ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes")]) ++ ++(define_insn "fix_truncdfsi2_8a" ++ [(set (match_operand:SI 0 "reg_no_subreg_operand" "=&r,&r") ++ (fix:SI ++ (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-w%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++(define_expand "fix_truncdfsi2" ++ [(set (match_operand:SI 0 "reg_no_subreg_operand") ++ (fix:SI (match_operand:DF 1 "reg_or_0_operand")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1") ++ ++(define_insn "*fixuns_truncdfsi2" ++ [(set (match_operand:SI 0 "reg_no_subreg_operand" "=&r,&r") ++ (unsigned_fix:SI ++ (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-wu%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++(define_expand "fixuns_truncdfsi2" ++ [(set (match_operand:SI 0 "reg_no_subreg_operand") ++ (unsigned_fix:SI (match_operand:DF 1 "reg_or_0_operand")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1") ++ ++(define_insn "*wdfsi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (fix:SI ++ (unspec:DF [(match_operand:DF 1 "register_operand" "fG")] ++ FRINT)))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-w %1, %0" ++ [(set_attr "type" "frint")]) ++ ++(define_insn "*wudfsi2" ++ [(set (match_operand:SI 0 "register_operand" "=&r,&r") ++ (unsigned_fix:SI ++ (unspec:DF [(match_operand:DF 1 "register_operand" "fG,fG")] ++ FRINT)))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-wu %1, %0" ++ [(set_attr "type" "frint")]) ++ ++(define_insn "ldfdi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (fix:DI ++ (unspec:DF [(match_operand:DF 1 "register_operand" "fG")] ++ FRINT)))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-l %1, %0" ++ [(set_attr "type" "frint")]) ++ ++(define_insn "ludfdi2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unsigned_fix:DI ++ (unspec:DF [(match_operand:DF 1 "register_operand" "fG")] ++ FRINT)))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-lu %1, %0" ++ [(set_attr "type" "frint")]) ++ ++(define_insn "fix_truncdfdi2_8a" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&r,&r") ++ (fix:DI ++ (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-l%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "fixuns_truncdfdi2_internal" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&r,&r") ++ (unsigned_fix:DI ++ (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmov%-lu%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn_and_split "*fix_truncdfsi_internal" ++ [(set (match_operand:SI 0 "memory_operand" "=m") ++ (subreg:SI ++ (match_operator:DI 4 "fix_operator" ++ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0)) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)])) ++ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) ++ (set (match_dup 5) (match_dup 3))] ++{ ++ //operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2])); ++ operands[5] = adjust_address (operands[0], SFmode, 0); ++} ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes")]) ++ ++(define_insn "*fix_truncdfdi2" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f,&f") ++ (match_operator:DI 2 "fix_operator" ++ [(match_operand:DF 1 "reg_or_0_operand" "fG,fG")]))] ++ "TARGET_FP && ((flag_sw_sdsame == 0 && flag_sw_cmov == 0) || TARGET_SW6B)" ++ "fcvt%-l%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*fix_truncdfdi2_same" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f,f") ++ (match_operator:DI 2 "fix_operator" ++ [(match_operand:DF 1 "reg_or_0_operand" "fG,fG")]))] ++ "TARGET_FP && ((flag_sw_sdsame == 1 && flag_sw_cmov == 0) || TARGET_SW6B)" ++ "fcvt%-l%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "fix_truncdfdi2" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand") ++ (fix:DI (match_operand:DF 1 "reg_or_0_operand")))] ++ "TARGET_FP") ++ ++(define_expand "fixuns_truncdfdi2" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand") ++ (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand")))] ++ "TARGET_FP" ++{ ++ if ((TARGET_SW8A == 1 && flag_sw_cmov != 1) || TARGET_SW6B) ++ { ++ rtx reg1 = gen_reg_rtx (DFmode); ++ rtx reg2 = gen_reg_rtx (DFmode); ++ rtx reg3 = gen_reg_rtx (DImode); ++ rtx_code_label *label1 = gen_label_rtx (); ++ rtx_code_label *label2 = gen_label_rtx (); ++ rtx test; ++ REAL_VALUE_TYPE offset; ++ ++ real_2expN (&offset, 63, DFmode); ++ ++ emit_move_insn (reg1, const_double_from_real_value (offset, DFmode)); ++ do_pending_stack_adjust (); ++ ++ test = gen_rtx_GE (VOIDmode, operands[1], reg1); ++ emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1)); ++ ++ emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1])); ++ emit_jump_insn (gen_rtx_SET (pc_rtx, gen_rtx_LABEL_REF (VOIDmode, label2))); ++ emit_barrier (); ++ ++ emit_label (label1); ++ emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); ++ emit_move_insn (reg3, GEN_INT (BITMASK_HIGH)); ++ emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); ++ ++ emit_insn (gen_fix_truncdfdi2 (operands[0], reg2)); ++ emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); ++ ++ emit_label (label2); ++ ++ /* Allow REG_NOTES to be set on last insn (labels don't have enough ++ fields, and can't be used for REG_NOTES anyway). */ ++ emit_use (stack_pointer_rtx); ++ DONE; ++ } ++ else ++ { ++ emit_insn (gen_fixuns_truncdfdi2_internal (operands[0], operands[1])); ++ DONE; ++ } ++}) ++ ++ ++;; Likewise between SFmode and SImode. ++ ++(define_insn_and_split "*fix_truncsfsi_ieee" ++ [(set (match_operand:SI 0 "memory_operand" "=m") ++ (subreg:SI ++ (match_operator:DI 4 "fix_operator" ++ [(float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0)) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && ((sw_64_fptm >= SW_64_FPTM_SU && flag_sw_cmov == 0) || TARGET_SW6B)" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))])) ++ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) ++ (set (match_dup 5) (match_dup 3))] ++ "operands[5] = adjust_address (operands[0], SFmode, 0);" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes")]) ++ ++(define_insn_and_split "*fix_truncsfsi_internal" ++ [(set (match_operand:SI 0 "memory_operand" "=m") ++ (subreg:SI ++ (match_operator:DI 4 "fix_operator" ++ [(float_extend:DF ++ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0)) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && ((sw_64_fptm < SW_64_FPTM_SU && flag_sw_cmov == 0) || TARGET_SW6B)" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))])) ++ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) ++ (set (match_dup 5) (match_dup 3))] ++{ ++ // operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2])); ++ operands[5] = adjust_address (operands[0], SFmode, 0); ++} ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes")]) ++ ++(define_insn "*fix_truncsfdi2" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f,&f") ++ (match_operator:DI 2 "fix_operator" ++ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,fG"))]))] ++ "TARGET_FP && ((flag_sw_sdsame == 0 && flag_sw_cmov == 0) || TARGET_SW6B)" ++ "fcvt%-l%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*fix_truncsfdi2_same" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f,f") ++ (match_operator:DI 2 "fix_operator" ++ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,fG"))]))] ++ "TARGET_FP && ((flag_sw_sdsame == 1 && flag_sw_cmov == 0) || TARGET_SW6B)" ++ "fcvt%-l%T2 %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "c") ++ (set_attr "trap_suffix" "v_sv_svi") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "fix_truncsfdi2" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand") ++ (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))] ++ "TARGET_FP && flag_sw_cmov == 0") ++ ++(define_expand "fixuns_truncsfdi2" ++ [(set (match_operand:DI 0 "reg_no_subreg_operand") ++ (unsigned_fix:DI ++ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))] ++ "TARGET_FP" ++{ ++ if ((TARGET_SW8A == 1 && flag_sw_cmov != 1) || TARGET_SW6B) ++ { ++ rtx reg1 = gen_reg_rtx (SFmode); ++ rtx reg2 = gen_reg_rtx (DFmode); ++ rtx reg3 = gen_reg_rtx (DImode); ++ rtx reg4 = gen_reg_rtx (DFmode); ++ rtx reg5 = gen_reg_rtx (DFmode); ++ rtx_code_label *label1 = gen_label_rtx (); ++ rtx_code_label *label2 = gen_label_rtx (); ++ rtx test; ++ REAL_VALUE_TYPE offset; ++ ++ real_2expN (&offset, 63, SFmode); ++ ++ emit_move_insn (reg1, const_double_from_real_value (offset, SFmode)); ++ do_pending_stack_adjust (); ++ ++ test = gen_rtx_GE (SFmode, operands[1], reg1); ++ emit_insn (gen_extendsfdf2 (reg4, reg1)); ++ emit_insn (gen_extendsfdf2 (reg2, operands[1])); ++ emit_jump_insn (gen_cbranchdf4 (test, reg2, reg4, label1)); ++ ++ emit_insn (gen_fix_truncdfdi2 (operands[0], reg2)); ++ emit_jump_insn (gen_rtx_SET (pc_rtx, gen_rtx_LABEL_REF (VOIDmode, label2))); ++ emit_barrier (); ++ ++ emit_label (label1); ++ emit_move_insn (reg5, gen_rtx_MINUS (DFmode, reg2, reg4)); ++ emit_move_insn (reg3, GEN_INT (BITMASK_HIGH)); ++ emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); ++ ++ emit_insn (gen_fix_truncdfdi2 (operands[0], reg5)); ++ emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); ++ ++ emit_label (label2); ++ ++ /* Allow REG_NOTES to be set on last insn (labels don't have enough ++ fields, and can't be used for REG_NOTES anyway). */ ++ emit_use (stack_pointer_rtx); ++ DONE; ++ } ++ else ++ { ++ rtx reg2 = gen_reg_rtx (DFmode); ++ emit_insn (gen_extendsfdf2 (reg2, operands[1])); ++ emit_insn (gen_fixuns_truncdfdi2_internal (operands[0], reg2)); ++ DONE; ++ } ++}) ++ ++ ++ ++(define_expand "fix_trunctfdi2" ++ [(use (match_operand:DI 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_cvt (FIX, operands); DONE;") ++ ++(define_expand "fixuns_trunctfdi2" ++ [(use (match_operand:DI 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;") ++ ++(define_insn "floatdisf2_8a" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovl%,%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*floatdisf2" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f,f")))] ++ "(flag_sw_cmov == 0 && flag_sw_sdsame == 0) || TARGET_SW6B" ++ "fcvtl%,%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*floatdisf2_same" ++ [(set (match_operand:SF 0 "register_operand" "=f,f") ++ (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f,f")))] ++ "(flag_sw_sdsame == 1 && flag_sw_cmov == 0) || TARGET_SW6B" ++ "fcvtl%,%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "floatdisf2" ++ [(set (match_operand:SF 0 "register_operand" "=f,f") ++ (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f,f")))] ++ "TARGET_FP" ++ "" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn_and_split "*floatsisf2_ieee" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (float:SF (match_operand:SI 1 "memory_operand" "m"))) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && sw_64_fptm >= SW_64_FPTM_SU && flag_sw_cmov == 0" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 3) (match_dup 1)) ++ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) ++ (set (match_dup 0) (float:SF (match_dup 2)))] ++ "operands[1] = adjust_address (operands[1], SFmode, 0);") ++ ++ (define_insn "floatsisf2" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (float:SF (match_operand:SI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovws %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn_and_split "*floatsisf2" ++ [(set (match_operand:SF 0 "register_operand" "=&f") ++ (float:SF (match_operand:SI 1 "memory_operand" "m"))) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && flag_sw_cmov == 0" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 3) (match_dup 1)) ++ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) ++ (set (match_dup 0) (float:SF (match_dup 2)))] ++{ ++ operands[1] = adjust_address (operands[1], SFmode, 0); ++ //operands[2] = gen_rtx_REG (DImode, REGNO (operands[0])); ++}) ++ ++(define_insn "floatdidf2_8a" ++ [(set (match_operand:DF 0 "register_operand" "=&f,&f") ++ (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovl%-%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*floatdidf2" ++ [(set (match_operand:DF 0 "register_operand" "=&f,&f") ++ (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f,f")))] ++ "flag_sw_sdsame == 0" ++ "fcvtl%-%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*floatdidf2_same" ++ [(set (match_operand:DF 0 "register_operand" "=f,f") ++ (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f,f")))] ++ "flag_sw_sdsame == 1" ++ "fcvtl%-%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "floatdidf2" ++ [(set (match_operand:DF 0 "register_operand" "=f,f") ++ (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f,f")))] ++ "TARGET_FP" ++ "" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++ (define_insn "floatsidf2" ++ [(set (match_operand:DF 0 "register_operand" "=&f,&f") ++ (float:DF (match_operand:SI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovwd %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++(define_insn_and_split "*floatsidf2_ieee" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (float:DF (match_operand:SI 1 "memory_operand" "m"))) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && sw_64_fptm >= SW_64_FPTM_SU && flag_sw_cmov == 0" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 3) (match_dup 1)) ++ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) ++ (set (match_dup 0) (float:DF (match_dup 2)))] ++ "operands[1] = adjust_address (operands[1], SFmode, 0);") ++ ++(define_insn_and_split "*floatsidf2" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (float:DF (match_operand:SI 1 "memory_operand" "m"))) ++ (clobber (match_scratch:DI 2 "=&f")) ++ (clobber (match_scratch:SF 3 "=&f"))] ++ "TARGET_FP && flag_sw_cmov == 0" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 3) (match_dup 1)) ++ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) ++ (set (match_dup 0) (float:DF (match_dup 2)))] ++{ ++ operands[1] = adjust_address (operands[1], SFmode, 0); ++// operands[2] = gen_rtx_REG (DImode, REGNO (operands[0])); ++ // operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0])); ++}) ++ ++(define_expand "floatditf2" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:DI 1 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_cvt (FLOAT, operands); DONE;") ++ ++(define_insn "floatunsdisf2" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (unsigned_float:SF (match_operand:DI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovul%,%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "floatunsdidf2" ++ [(set (match_operand:DF 0 "register_operand" "=&f,&f") ++ (unsigned_float:DF (match_operand:DI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_FP && TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovul%-%/ %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "floatunssidf2" ++ [(set (match_operand:DF 0 "register_operand" "=&f,&f") ++ (unsigned_float:DF (match_operand:SI 1 "register_operand" "r,r")))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovuwd %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ (define_insn "floatunssisf2" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (unsigned_float:SF (match_operand:SI 1 "reg_no_subreg_operand" "r,r")))] ++ "TARGET_SW8A && flag_sw_cmov == 1" ++ "cmovuws %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_expand "floatunsditf2" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:DI 1 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;") ++ ++(define_expand "extendsfdf2" ++ [(set (match_operand:DF 0 "register_operand") ++ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand")))] ++ "TARGET_FP" ++{ ++ if (sw_64_fptm >= SW_64_FPTM_SU) ++ operands[1] = force_reg (SFmode, operands[1]); ++}) ++ ++;; The Unicos/Mk assembler doesn't support cvtst, but we've already ++;; asserted that sw_64_fptm == SW_64_FPTM_N. ++ ++(define_insn "*cmpsf_internal" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (match_operator:SF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:SF 2 "reg_or_0_operand" "fG,fG") ++ (match_operand:SF 3 "reg_or_0_operand" "fG,fG")]))] ++ "TARGET_FP && flag_sw_sdsame == 0 && flag_sw_sf_cmpsel" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++(define_insn "*cmpsf_internal_same" ++ [(set (match_operand:SF 0 "register_operand" "=f,f") ++ (match_operator:SF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:SF 2 "reg_or_0_operand" "fG,fG") ++ (match_operand:SF 3 "reg_or_0_operand" "fG,fG")]))] ++ "TARGET_FP && flag_sw_sdsame == 1 && flag_sw_sf_cmpsel" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*extendsfdf2_ieee" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] ++ "TARGET_FP && sw_64_fptm >= SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fcvtsd %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes")]) ++(define_insn "*extendsfdf2_ieee_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] ++ "TARGET_FP && sw_64_fptm >= SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fcvtsd %1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes")]) ++ ++(define_insn "*extendsfdf2_internal_1" ++ [(set (match_operand:DF 0 "register_operand" "=&f,f,m") ++ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_nofcpys == 1" ++ "@ ++ fcvtsd %1,%0 ++ fld%,%U1 %0,%1 ++ fst%-%U0 %1,%0" ++ [(set_attr "type" "fcpys,fld,fst")]) ++ ++(define_insn "*extendsfdf2_internal_2" ++ [(set (match_operand:DF 0 "register_operand" "=&f,f,m") ++ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_nofcpys == 0" ++ "@ ++ fcvtsd %1,%0 \;fcpys %0,%0,%0 ++ fld%, %0,%1 ++ fst%- %1,%0" ++ [(set_attr "type" "fcpys,fld,fst")]) ++ ++;; Use register_operand for operand 1 to prevent compress_float_constant ++;; from doing something silly. When optimizing we'll put things back ++;; together anyway. ++(define_expand "extendsftf2" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:SF 1 "register_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++{ ++ rtx tmp = gen_reg_rtx (DFmode); ++ emit_insn (gen_extendsfdf2 (tmp, operands[1])); ++ emit_insn (gen_extenddftf2 (operands[0], tmp)); ++ DONE; ++}) ++ ++(define_expand "extenddftf2" ++ [(use (match_operand:TF 0 "register_operand")) ++ (use (match_operand:DF 1 "register_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;") ++ ++(define_insn "*truncdfsf2" ++ [(set (match_operand:SF 0 "register_operand" "=&f,&f") ++ (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 0" ++ "fcvt%-%,%/ %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*truncdfsf2_same" ++ [(set (match_operand:SF 0 "register_operand" "=f,f") ++ (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "flag_sw_sdsame == 1" ++ "fcvt%-%,%/ %R1,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++(define_expand "truncdfsf2" ++ [(set (match_operand:SF 0 "register_operand" "=f,f") ++ (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG,fG")))] ++ "TARGET_FP" ++ "" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "round_suffix" "normal") ++ (set_attr "trap_suffix" "u_su_sui") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++ ++(define_expand "trunctfdf2" ++ [(use (match_operand:DF 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;") ++ ++(define_expand "trunctfsf2" ++ [(use (match_operand:SF 0 "register_operand")) ++ (use (match_operand:TF 1 "general_operand"))] ++ "TARGET_FP && TARGET_HAS_XFLOATING_LIBS" ++{ ++ rtx tmpf, sticky, arg, lo, hi; ++ ++ tmpf = gen_reg_rtx (DFmode); ++ sticky = gen_reg_rtx (DImode); ++ arg = copy_to_mode_reg (TFmode, operands[1]); ++ lo = gen_lowpart (DImode, arg); ++ hi = gen_highpart (DImode, arg); ++ ++ /* Convert the low word of the TFmode value into a sticky rounding bit, ++ then or it into the low bit of the high word. This leaves the sticky ++ bit at bit 48 of the fraction, which is representable in DFmode, ++ which prevents rounding error in the final conversion to SFmode. */ ++ ++ emit_insn (gen_rtx_SET (sticky, gen_rtx_NE (DImode, lo, const0_rtx))); ++ emit_insn (gen_iordi3 (hi, hi, sticky)); ++ emit_insn (gen_trunctfdf2 (tmpf, arg)); ++ emit_insn (gen_truncdfsf2 (operands[0], tmpf)); ++ DONE; ++}) ++ ++;; Next are all the integer comparisons, and conditional moves and branches ++;; and some of the related define_expand's and define_split's. ++ ++(define_insn "*setcc_internal" ++ [(set (match_operand 0 "register_operand" "=r") ++ (match_operator 1 "sw_64_comparison_operator" ++ [(match_operand:DI 2 "register_operand" "r") ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))] ++ "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT ++ && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8 ++ && GET_MODE (operands[0]) == GET_MODE (operands[1])" ++ "cmp%C1 %2,%3,%0" ++ [(set_attr "type" "icmp")]) ++ ++;; Yes, we can technically support reg_or_8bit_operand in operand 2, ++;; but that's non-canonical rtl and allowing that causes inefficiencies ++;; from cse on. ++(define_insn "*setcc_swapped_internal" ++ [(set (match_operand 0 "register_operand" "=r") ++ (match_operator 1 "sw_64_swapped_comparison_operator" ++ [(match_operand:DI 2 "register_operand" "r") ++ (match_operand:DI 3 "reg_or_0_operand" "rJ")]))] ++ "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT ++ && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8 ++ && GET_MODE (operands[0]) == GET_MODE (operands[1])" ++ "cmp%c1 %r3,%2,%0" ++ [(set_attr "type" "icmp")]) ++ ++;; Use match_operator rather than ne directly so that we can match ++;; multiple integer modes. ++(define_insn "*setne_internal" ++ [(set (match_operand 0 "register_operand" "=r") ++ (match_operator 1 "signed_comparison_operator" ++ [(match_operand:DI 2 "register_operand" "r") ++ (const_int 0)]))] ++ "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT ++ && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8 ++ && GET_CODE (operands[1]) == NE ++ && GET_MODE (operands[0]) == GET_MODE (operands[1])" ++ "cmpult $31,%2,%0" ++ [(set_attr "type" "icmp")]) ++ ++;; The mode folding trick can't be used with const_int operands, since ++;; reload needs to know the proper mode. ++;; ++;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand ++;; in order to create more pairs of constants. As long as we're allowing ++;; two constants at the same time, and will have to reload one of them... ++ ++(define_insn "*movcc_internal" ++ [(set (match_operand:IMODE 0 "register_operand" "=r,r,r,r") ++ (if_then_else:IMODE ++ (match_operator 2 "signed_comparison_operator" ++ [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") ++ (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) ++ (match_operand:IMODE 1 "add_operand" "rI,0,rI,0") ++ (match_operand:IMODE 5 "add_operand" "0,rI,0,rI")))] ++ "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" ++ "@ ++ sel%C2 %r3,%1,%0,%0 ++ sel%D2 %r3,%5,%0,%0 ++ sel%c2 %r4,%1,%0,%0 ++ sel%d2 %r4,%5,%0,%0" ++ [(set_attr "type" "icmov")]) ++ ++(define_insn "*movcc_lbc" ++ [(set (match_operand:IMODE 0 "register_operand" "=r,r") ++ (if_then_else:IMODE ++ (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") ++ (const_int 1) ++ (const_int 0)) ++ (const_int 0)) ++ (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0") ++ (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))] ++ "" ++ "@ ++ sellbc %r2,%1,%0,%0 ++ sellbs %r2,%3,%0,%0" ++ [(set_attr "type" "icmov")]) ++ ++(define_insn "*movcc_lbs" ++ [(set (match_operand:IMODE 0 "register_operand" "=r,r") ++ (if_then_else:IMODE ++ (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") ++ (const_int 1) ++ (const_int 0)) ++ (const_int 0)) ++ (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0") ++ (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))] ++ "" ++ "@ ++ sellbs %r2,%1,%0,%0 ++ sellbc %r2,%3,%0,%0" ++ [(set_attr "type" "icmov")]) ++ ++;; For ABS, we have two choices, depending on whether the input and output ++;; registers are the same or not. ++(define_expand "absdi2" ++ [(set (match_operand:DI 0 "register_operand") ++ (abs:DI (match_operand:DI 1 "register_operand")))] ++ "" ++{ ++ if (rtx_equal_p (operands[0], operands[1])) ++ emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode))); ++ else ++ emit_insn (gen_absdi2_diff (operands[0], operands[1])); ++ DONE; ++}) ++ ++(define_expand "absdi2_same" ++ [(set (match_operand:DI 1 "register_operand") ++ (neg:DI (match_operand:DI 0 "register_operand"))) ++ (set (match_dup 0) ++ (if_then_else:DI (ge (match_dup 0) (const_int 0)) ++ (match_dup 0) ++ (match_dup 1)))]) ++ ++(define_expand "absdi2_diff" ++ [(set (match_operand:DI 0 "register_operand") ++ (neg:DI (match_operand:DI 1 "register_operand"))) ++ (set (match_dup 0) ++ (if_then_else:DI (lt (match_dup 1) (const_int 0)) ++ (match_dup 0) ++ (match_dup 1)))]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (abs:DI (match_dup 0))) ++ (clobber (match_operand:DI 1 "register_operand"))] ++ "" ++ [(set (match_dup 1) (neg:DI (match_dup 0))) ++ (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0)) ++ (match_dup 0) (match_dup 1)))]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (abs:DI (match_operand:DI 1 "register_operand")))] ++ "! rtx_equal_p (operands[0], operands[1])" ++ [(set (match_dup 0) (neg:DI (match_dup 1))) ++ (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0)) ++ (match_dup 0) (match_dup 1)))]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (neg:DI (abs:DI (match_dup 0)))) ++ (clobber (match_operand:DI 1 "register_operand"))] ++ "" ++ [(set (match_dup 1) (neg:DI (match_dup 0))) ++ (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0)) ++ (match_dup 0) (match_dup 1)))]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (neg:DI (abs:DI (match_operand:DI 1 "register_operand"))))] ++ "! rtx_equal_p (operands[0], operands[1])" ++ [(set (match_dup 0) (neg:DI (match_dup 1))) ++ (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0)) ++ (match_dup 0) (match_dup 1)))]) ++ ++(define_insn "3" ++ [(set (match_operand:I12MODE 0 "register_operand" "=r") ++ (any_maxmin:I12MODE ++ (match_operand:I12MODE 1 "reg_or_0_operand" "%rJ") ++ (match_operand:I12MODE 2 "reg_or_8bit_operand" "rI")))] ++ "TARGET_MAX" ++ " %r1,%2,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_expand "smaxdi3" ++ [(set (match_dup 3) ++ (le:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI (eq (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))] ++ "" ++ "operands[3] = gen_reg_rtx (DImode);") ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (smax:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (clobber (match_operand:DI 3 "register_operand"))] ++ "operands[2] != const0_rtx" ++ [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2))) ++ (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))]) ++ ++(define_insn "*smax_const0" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (smax:DI (match_operand:DI 1 "register_operand" "0") ++ (const_int 0)))] ++ "" ++ "sellt %0,0,%0,%0" ++ [(set_attr "type" "icmov")]) ++ ++(define_expand "smindi3" ++ [(set (match_dup 3) ++ (lt:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI (ne (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))] ++ "" ++ "operands[3] = gen_reg_rtx (DImode);") ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (smin:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (clobber (match_operand:DI 3 "register_operand"))] ++ "operands[2] != const0_rtx" ++ [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2))) ++ (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))]) ++ ++(define_insn "*smin_const0" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (smin:DI (match_operand:DI 1 "register_operand" "0") ++ (const_int 0)))] ++ "" ++ "selgt %0,0,%0,%0" ++ [(set_attr "type" "icmov")]) ++ ++(define_expand "umaxdi3" ++ [(set (match_dup 3) ++ (leu:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI (eq (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))] ++ "" ++ "operands[3] = gen_reg_rtx (DImode);") ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (umax:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (clobber (match_operand:DI 3 "register_operand"))] ++ "operands[2] != const0_rtx" ++ [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2))) ++ (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))]) ++ ++(define_expand "umindi3" ++ [(set (match_dup 3) ++ (ltu:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI (ne (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))] ++ "" ++ "operands[3] = gen_reg_rtx (DImode);") ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (umin:DI (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand"))) ++ (clobber (match_operand:DI 3 "register_operand"))] ++ "operands[2] != const0_rtx" ++ [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2))) ++ (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) ++ (match_dup 1) (match_dup 2)))]) ++ ++(define_insn "*bcc_normal" ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "signed_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (label_ref (match_operand 0)) ++ (pc)))] ++ "" ++ "b%C1 %r2,%0" ++ [(set_attr "type" "ibr")]) ++ ++(define_insn "*bcc_reverse" ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "signed_comparison_operator" ++ [(match_operand:DI 2 "register_operand" "r") ++ (const_int 0)]) ++ ++ (pc) ++ (label_ref (match_operand 0))))] ++ "" ++ "b%c1 %2,%0" ++ [(set_attr "type" "ibr")]) ++ ++(define_insn_and_split "*branchcombine" ++ [(set (pc) ++ (if_then_else (match_operator 1 "sw_64_branch_combination" ++ [(match_operand:DI 2 "register_operand") ++ (match_operand:DI 3 "reg_or_8bit_operand")]) ++ (label_ref (match_operand 0)) ++ (pc)))] ++"flag_sw_branch_combination==1 ++ && (can_create_pseudo_p ()) && operands[3]!=CONST0_RTX (DImode)" ++"#" ++"&& 1" ++ [(parallel ++ [(set (pc) ++ (if_then_else ++ (match_op_dup 1 ++ [(match_dup 2) ++ (match_dup 3)]) ++ (label_ref (match_dup 0)) ++ (pc))) ++ (clobber (match_dup 4))])] ++{ ++ operands[4]=gen_reg_rtx (DImode); ++}) ++ ++(define_insn "bcc_ne" ++ [(parallel ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "sw_64_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI")]) ++ (label_ref (match_operand 0)) ++ (pc))) ++ (clobber (match_operand:DI 4 "register_operand" "=r"))])] ++ "flag_sw_branch_combination==1" ++ "cmp%C1 %r2,%3,%r4 ++ bne %r4,%0" ++ [(set_attr "type" "ibr")]) ++ ++(define_insn "bcc_eq" ++ [(parallel ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "sw_64_swapped_branch_combination" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI")]) ++ (label_ref (match_operand 0)) ++ (pc))) ++ (clobber (match_operand:DI 4 "register_operand" "=r"))])] ++ "flag_sw_branch_combination==1" ++ "cmp%D1 %r2,%3,%r4 ++ beq %r4,%0" ++ [(set_attr "type" "ibr")]) ++ ++(define_insn "*blbs_normal" ++ [(set (pc) ++ (if_then_else ++ (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (const_int 1) ++ (const_int 0)) ++ (const_int 0)) ++ (label_ref (match_operand 0)) ++ (pc)))] ++ "" ++ "blbs %r1,%0" ++ [(set_attr "type" "ibr")]) ++ ++(define_insn "*blbc_normal" ++ [(set (pc) ++ (if_then_else ++ (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (const_int 1) ++ (const_int 0)) ++ (const_int 0)) ++ (label_ref (match_operand 0)) ++ (pc)))] ++ "" ++ "blbc %r1,%0" ++ [(set_attr "type" "ibr")]) ++ ++(define_split ++ [(parallel ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "comparison_operator" ++ [(zero_extract:DI (match_operand:DI 2 "register_operand") ++ (const_int 1) ++ (match_operand:DI 3 "const_int_operand")) ++ (const_int 0)]) ++ (label_ref (match_operand 0)) ++ (pc))) ++ (clobber (match_operand:DI 4 "register_operand"))])] ++ "INTVAL (operands[3]) != 0" ++ [(set (match_dup 4) ++ (lshiftrt:DI (match_dup 2) (match_dup 3))) ++ (set (pc) ++ (if_then_else (match_op_dup 1 ++ [(zero_extract:DI (match_dup 4) ++ (const_int 1) ++ (const_int 0)) ++ (const_int 0)]) ++ (label_ref (match_dup 0)) ++ (pc)))] ++) ++ ++;; The following are the corresponding floating-point insns. Recall ++;; we need to have variants that expand the arguments from SFmode ++;; to DFmode. ++ ++(define_insn "*cmpdf_internal" ++ [(set (match_operand:DF 0 "register_operand" "=&f,&f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "reg_or_0_operand" "fG,fG") ++ (match_operand:DF 3 "reg_or_0_operand" "fG,fG")]))] ++ "TARGET_FP && flag_sw_sdsame == 0" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*cmpdf_internal_same" ++ [(set (match_operand:DF 0 "register_operand" "=f,f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "reg_or_0_operand" "fG,fG") ++ (match_operand:DF 3 "reg_or_0_operand" "fG,fG")]))] ++ "TARGET_FP && flag_sw_sdsame == 1" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su") ++ (set (attr "enabled") ++ (cond [(eq_attr "alternative" "0") ++ (symbol_ref "sw_64_fptm < SW_64_FPTM_SU") ++ ] ++ (symbol_ref "true")))]) ++ ++(define_insn "*cmpdf_ext1" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG")) ++ (match_operand:DF 3 "reg_or_0_operand" "fG")]))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su")]) ++(define_insn "*cmpdf_ext1_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG")) ++ (match_operand:DF 3 "reg_or_0_operand" "fG")]))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su")]) ++ ++(define_insn "*cmpdf_ext2" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "reg_or_0_operand" "fG") ++ (float_extend:DF ++ (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su")]) ++(define_insn "*cmpdf_ext2_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(match_operand:DF 2 "reg_or_0_operand" "fG") ++ (float_extend:DF ++ (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su")]) ++ ++(define_insn "*cmpdf_ext3" ++ [(set (match_operand:DF 0 "register_operand" "=&f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG")) ++ (float_extend:DF ++ (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 0" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su")]) ++(define_insn "*cmpdf_ext3_same" ++ [(set (match_operand:DF 0 "register_operand" "=f") ++ (match_operator:DF 1 "sw_64_fp_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG")) ++ (float_extend:DF ++ (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU && flag_sw_sdsame == 1" ++ "fcmp%C1%/ %R2,%R3,%0" ++ [(set_attr "type" "fadd") ++ (set_attr "trap" "yes") ++ (set_attr "trap_suffix" "su")]) ++ ++ ++(define_insn "*movcc_internal" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (if_then_else:FMODE ++ (match_operator 3 "signed_comparison_operator" ++ [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") ++ (match_operand:DF 2 "const0_operand" "G,G")]) ++ (match_operand:FMODE 1 "reg_or_0_operand" "fG,0") ++ (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))] ++ "TARGET_FP" ++ "@ ++ fsel%C3 %R4,%R1,%0,%0 ++ fsel%D3 %R4,%R5,%0,%0" ++ [(set_attr "type" "fcmov")]) ++ ++(define_insn "*movdfcc_ext1" ++ [(set (match_operand:DF 0 "register_operand" "=f,f") ++ (if_then_else:DF ++ (match_operator 3 "signed_comparison_operator" ++ [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") ++ (match_operand:DF 2 "const0_operand" "G,G")]) ++ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0")) ++ (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++ "@ ++ fsel%C3 %R4,%R1,%0,%0 ++ fsel%D3 %R4,%R5,%0,%0" ++ [(set_attr "type" "fcmov")]) ++ ++(define_insn "*movdfcc_ext2" ++ [(set (match_operand:DF 0 "register_operand" "=f,f") ++ (if_then_else:DF ++ (match_operator 3 "signed_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) ++ (match_operand:DF 2 "const0_operand" "G,G")]) ++ (match_operand:DF 1 "reg_or_0_operand" "fG,0") ++ (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++ "@ ++ fsel%C3 %R4,%R1,%0,%0 ++ fsel%D3 %R4,%R5,%0,%0" ++ [(set_attr "type" "fcmov")]) ++ ++(define_insn "*movdfcc_ext3" ++ [(set (match_operand:SF 0 "register_operand" "=f,f") ++ (if_then_else:SF ++ (match_operator 3 "signed_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) ++ (match_operand:DF 2 "const0_operand" "G,G")]) ++ (match_operand:SF 1 "reg_or_0_operand" "fG,0") ++ (match_operand:SF 5 "reg_or_0_operand" "0,fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++ "@ ++ fsel%C3 %R4,%R1,%0,%0 ++ fsel%D3 %R4,%R5,%0,%0" ++ [(set_attr "type" "fcmov")]) ++ ++(define_insn "*movdfcc_ext4" ++ [(set (match_operand:DF 0 "register_operand" "=f,f") ++ (if_then_else:DF ++ (match_operator 3 "signed_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) ++ (match_operand:DF 2 "const0_operand" "G,G")]) ++ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0")) ++ (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++ "@ ++ fsel%C3 %R4,%R1,%0,%0 ++ fsel%D3 %R4,%R5,%0,%0" ++ [(set_attr "type" "fcmov")]) ++ ++(define_expand "smaxdf3" ++ [(set (match_dup 3) ++ (le:DF (match_operand:DF 1 "reg_or_0_operand") ++ (match_operand:DF 2 "reg_or_0_operand"))) ++ (set (match_operand:DF 0 "register_operand") ++ (if_then_else:DF (eq (match_dup 3) (match_dup 4)) ++ (match_dup 1) (match_dup 2)))] ++ "TARGET_FP" ++{ ++ operands[3] = gen_reg_rtx (DFmode); ++ operands[4] = CONST0_RTX (DFmode); ++}) ++ ++(define_expand "smindf3" ++ [(set (match_dup 3) ++ (lt:DF (match_operand:DF 1 "reg_or_0_operand") ++ (match_operand:DF 2 "reg_or_0_operand"))) ++ (set (match_operand:DF 0 "register_operand") ++ (if_then_else:DF (ne (match_dup 3) (match_dup 4)) ++ (match_dup 1) (match_dup 2)))] ++ "TARGET_FP" ++{ ++ operands[3] = gen_reg_rtx (DFmode); ++ operands[4] = CONST0_RTX (DFmode); ++}) ++ ++(define_expand "smaxsf3" ++ [(set (match_dup 3) ++ (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand")) ++ (float_extend:DF (match_operand:SF 2 "reg_or_0_operand")))) ++ (set (match_operand:SF 0 "register_operand") ++ (if_then_else:SF (eq (match_dup 3) (match_dup 4)) ++ (match_dup 1) (match_dup 2)))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++{ ++ operands[3] = gen_reg_rtx (DFmode); ++ operands[4] = CONST0_RTX (DFmode); ++}) ++ ++(define_expand "sminsf3" ++ [(set (match_dup 3) ++ (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand")) ++ (float_extend:DF (match_operand:SF 2 "reg_or_0_operand")))) ++ (set (match_operand:SF 0 "register_operand") ++ (if_then_else:SF (ne (match_dup 3) (match_dup 4)) ++ (match_dup 1) (match_dup 2)))] ++ "TARGET_FP && sw_64_fptm < SW_64_FPTM_SU" ++{ ++ operands[3] = gen_reg_rtx (DFmode); ++ operands[4] = CONST0_RTX (DFmode); ++}) ++ ++(define_insn "*fbcc_normal" ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "signed_comparison_operator" ++ [(match_operand:DF 2 "reg_or_0_operand" "fG") ++ (match_operand:DF 3 "const0_operand" "G")]) ++ (label_ref (match_operand 0)) ++ (pc)))] ++ "TARGET_FP" ++ "fb%C1 %R2,%0" ++ [(set_attr "type" "fbr")]) ++ ++(define_insn "*fbcc_ext_normal" ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "signed_comparison_operator" ++ [(float_extend:DF ++ (match_operand:SF 2 "reg_or_0_operand" "fG")) ++ (match_operand:DF 3 "const0_operand" "G")]) ++ (label_ref (match_operand 0)) ++ (pc)))] ++ "TARGET_FP" ++ "fb%C1 %R2,%0" ++ [(set_attr "type" "fbr")]) ++ ++;; These are the main define_expand's used to make conditional branches ++;; and compares. ++ ++(define_expand "cbranchsf4" ++ [(use (match_operator 0 "sw_64_cbranch_operator" ++ [(match_operand:SF 1 "reg_or_0_operand") ++ (match_operand:SF 2 "reg_or_0_operand")])) ++ (use (match_operand 3))] ++ "TARGET_FP && flag_sw_sf_cmpsel" ++ "sw_64_emit_conditional_branch (operands, SFmode); DONE;") ++ ++(define_insn "*sfbcc_normal" ++ [(set (pc) ++ (if_then_else ++ (match_operator 1 "signed_comparison_operator" ++ [(match_operand:SF 2 "reg_or_0_operand" "fG") ++ (match_operand:SF 3 "const0_operand" "G")]) ++ (label_ref (match_operand 0)) ++ (pc)))] ++ "TARGET_FP && flag_sw_sf_cmpsel" ++ "fb%C1 %R2,%0" ++ [(set_attr "type" "fbr")]) ++ ++(define_insn "*movsfcc_internal" ++ [(set (match_operand:FMODE 0 "register_operand" "=f,f") ++ (if_then_else:FMODE ++ (match_operator 3 "signed_comparison_operator" ++ [(match_operand:SF 4 "reg_or_0_operand" "fG,fG") ++ (match_operand:SF 2 "const0_operand" "G,G")]) ++ (match_operand:FMODE 1 "reg_or_0_operand" "fG,0") ++ (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))] ++ "TARGET_FP && flag_sw_sf_cmpsel" ++ "@ ++ fsel%C3 %R4,%R1,%0,%0 ++ fsel%D3 %R4,%R5,%0,%0" ++ [(set_attr "type" "fcmov")]) ++ ++ ++(define_expand "cbranchdf4" ++ [(use (match_operator 0 "sw_64_cbranch_operator" ++ [(match_operand:DF 1 "reg_or_0_operand") ++ (match_operand:DF 2 "reg_or_0_operand")])) ++ (use (match_operand 3))] ++ "TARGET_FP" ++ "sw_64_emit_conditional_branch (operands, DFmode); DONE;") ++ ++(define_expand "cbranchtf4" ++ [(use (match_operator 0 "sw_64_cbranch_operator" ++ [(match_operand:TF 1 "general_operand") ++ (match_operand:TF 2 "general_operand")])) ++ (use (match_operand 3))] ++ "TARGET_HAS_XFLOATING_LIBS" ++ "sw_64_emit_conditional_branch (operands, TFmode); DONE;") ++ ++(define_expand "cbranchdi4" ++ [(use (match_operator 0 "sw_64_cbranch_operator" ++ [(match_operand:DI 1 "general_operand") ++ (match_operand:DI 2 "general_operand")])) ++ (use (match_operand 3))] ++ "" ++ "sw_64_emit_conditional_branch (operands, DImode); DONE;") ++ ++(define_expand "cstoredf4" ++ [(use (match_operator:DI 1 "sw_64_cbranch_operator" ++ [(match_operand:DF 2 "reg_or_0_operand") ++ (match_operand:DF 3 "reg_or_0_operand")])) ++ (clobber (match_operand:DI 0 "register_operand"))] ++ "TARGET_FP" ++{ ++ if (sw_64_emit_setcc (operands, DFmode)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++(define_expand "cstoretf4" ++ [(use (match_operator:DI 1 "sw_64_cbranch_operator" ++ [(match_operand:TF 2 "general_operand") ++ (match_operand:TF 3 "general_operand")])) ++ (clobber (match_operand:DI 0 "register_operand"))] ++ "TARGET_HAS_XFLOATING_LIBS" ++{ ++ if (sw_64_emit_setcc (operands, TFmode)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++(define_expand "cstoredi4" ++ [(use (match_operator:DI 1 "sw_64_cbranch_operator" ++ [(match_operand:DI 2 "general_operand") ++ (match_operand:DI 3 "general_operand")])) ++ (clobber (match_operand:DI 0 "register_operand"))] ++ "" ++{ ++ if (sw_64_emit_setcc (operands, DImode)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++;; These are the main define_expand's used to make conditional moves. ++ ++(define_expand "movcc" ++ [(set (match_operand:I48MODE 0 "register_operand") ++ (if_then_else:I48MODE ++ (match_operand 1 "comparison_operator") ++ (match_operand:I48MODE 2 "reg_or_8bit_operand") ++ (match_operand:I48MODE 3 "reg_or_8bit_operand")))] ++ "" ++{ ++ operands[1] = sw_64_emit_conditional_move (operands[1], mode); ++ if (operands[1] == 0) ++ FAIL; ++}) ++ ++(define_expand "movcc" ++ [(set (match_operand:FMODE 0 "register_operand") ++ (if_then_else:FMODE ++ (match_operand 1 "comparison_operator") ++ (match_operand:FMODE 2 "reg_or_8bit_operand") ++ (match_operand:FMODE 3 "reg_or_8bit_operand")))] ++ "" ++{ ++ operands[1] = sw_64_emit_conditional_move (operands[1], mode); ++ if (operands[1] == 0) ++ FAIL; ++}) ++ ++;; These define_split definitions are used in cases when comparisons have ++;; not be stated in the correct way and we need to reverse the second ++;; comparison. For example, x >= 7 has to be done as x < 6 with the ++;; comparison that tests the result being reversed. We have one define_split ++;; for each use of a comparison. They do not match valid insns and need ++;; not generate valid insns. ++;; ++;; We can also handle equality comparisons (and inequality comparisons in ++;; cases where the resulting add cannot overflow) by doing an add followed by ++;; a comparison with zero. This is faster since the addition takes one ++;; less cycle than a compare when feeding into a conditional move. ++;; For this case, we also have an SImode pattern since we can merge the add ++;; and sign extend and the order doesn't matter. ++;; ++;; We do not do this for floating-point, since it isn't clear how the "wrong" ++;; operation could have been generated. ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI ++ (match_operator 1 "comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand") ++ (match_operand:DI 3 "reg_or_cint_operand")]) ++ (match_operand:DI 4 "reg_or_cint_operand") ++ (match_operand:DI 5 "reg_or_cint_operand"))) ++ (clobber (match_operand:DI 6 "register_operand"))] ++ "operands[3] != const0_rtx" ++ [(set (match_dup 6) (match_dup 7)) ++ (set (match_dup 0) ++ (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))] ++{ ++ enum rtx_code code = GET_CODE (operands[1]); ++ int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); ++ ++ /* If we are comparing for equality with a constant and that constant ++ appears in the arm when the register equals the constant, use the ++ register since that is more likely to match (and to produce better code ++ if both would). */ ++ ++ if (code == EQ && CONST_INT_P (operands[3]) ++ && rtx_equal_p (operands[4], operands[3])) ++ operands[4] = operands[2]; ++ ++ else if (code == NE && CONST_INT_P (operands[3]) ++ && rtx_equal_p (operands[5], operands[3])) ++ operands[5] = operands[2]; ++ ++ if (code == NE || code == EQ ++ || (extended_count (operands[2], DImode, unsignedp) >= 1 ++ && extended_count (operands[3], DImode, unsignedp) >= 1)) ++ { ++ if (CONST_INT_P (operands[3])) ++ operands[7] = gen_rtx_PLUS (DImode, operands[2], ++ GEN_INT (- INTVAL (operands[3]))); ++ else ++ operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]); ++ ++ operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx); ++ } ++ ++ else if (code == EQ || code == LE || code == LT ++ || code == LEU || code == LTU) ++ { ++ operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]); ++ operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx); ++ } ++ else ++ { ++ operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode, ++ operands[2], operands[3]); ++ operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx); ++ } ++}) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (if_then_else:DI ++ (match_operator 1 "comparison_operator" ++ [(match_operand:SI 2 "reg_or_0_operand") ++ (match_operand:SI 3 "reg_or_cint_operand")]) ++ (match_operand:DI 4 "reg_or_8bit_operand") ++ (match_operand:DI 5 "reg_or_8bit_operand"))) ++ (clobber (match_operand:DI 6 "register_operand"))] ++ "operands[3] != const0_rtx ++ && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" ++ [(set (match_dup 6) (match_dup 7)) ++ (set (match_dup 0) ++ (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))] ++{ ++ enum rtx_code code = GET_CODE (operands[1]); ++ int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); ++ rtx tem; ++ ++ if ((code != NE && code != EQ ++ && ! (extended_count (operands[2], DImode, unsignedp) >= 1 ++ && extended_count (operands[3], DImode, unsignedp) >= 1))) ++ FAIL; ++ ++ if (CONST_INT_P (operands[3])) ++ tem = gen_rtx_PLUS (SImode, operands[2], ++ GEN_INT (- INTVAL (operands[3]))); ++ else ++ tem = gen_rtx_MINUS (SImode, operands[2], operands[3]); ++ ++ operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem); ++ operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode, ++ operands[6], const0_rtx); ++}) ++ ++;; Prefer to use cmp and arithmetic when possible instead of a cmove. ++ ++(define_split ++ [(set (match_operand 0 "register_operand") ++ (if_then_else (match_operator 1 "signed_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand") ++ (const_int 0)]) ++ (match_operand 3 "const_int_operand") ++ (match_operand 4 "const_int_operand")))] ++ "" ++ [(const_int 0)] ++{ ++ if (sw_64_split_conditional_move (GET_CODE (operands[1]), operands[0], ++ operands[2], operands[3], operands[4])) ++ DONE; ++ else ++ FAIL; ++}) ++ ++;; ??? Why combine is allowed to create such non-canonical rtl, I don't know. ++;; Oh well, we match it in movcc, so it must be partially our fault. ++(define_split ++ [(set (match_operand 0 "register_operand") ++ (if_then_else (match_operator 1 "signed_comparison_operator" ++ [(const_int 0) ++ (match_operand:DI 2 "reg_or_0_operand")]) ++ (match_operand 3 "const_int_operand") ++ (match_operand 4 "const_int_operand")))] ++ "" ++ [(const_int 0)] ++{ ++ if (sw_64_split_conditional_move (swap_condition (GET_CODE (operands[1])), ++ operands[0], operands[2], operands[3], ++ operands[4])) ++ DONE; ++ else ++ FAIL; ++}) ++ ++(define_insn_and_split "*cmp_sadd_di" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (plus:DI (if_then_else:DI ++ (match_operator 1 "sw_64_zero_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (match_operand:DI 3 "const48_operand" "I") ++ (const_int 0)) ++ (match_operand:DI 4 "sext_add_operand" "rIO"))) ++ (clobber (match_scratch:DI 5 "=r"))] ++ "" ++ "#" ++ "" ++ [(set (match_dup 5) ++ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) ++ (set (match_dup 0) ++ (plus:DI (mult:DI (match_dup 5) (match_dup 3)) ++ (match_dup 4)))] ++{ ++ if (can_create_pseudo_p ()) ++ operands[5] = gen_reg_rtx (DImode); ++ else if (reg_overlap_mentioned_p (operands[5], operands[4])) ++ operands[5] = operands[0]; ++}) ++ ++(define_insn_and_split "*cmp_sadd_si" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (plus:SI (if_then_else:SI ++ (match_operator 1 "sw_64_zero_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (match_operand:SI 3 "const48_operand" "I") ++ (const_int 0)) ++ (match_operand:SI 4 "sext_add_operand" "rIO"))) ++ (clobber (match_scratch:DI 5 "=r"))] ++ "" ++ "#" ++ "" ++ [(set (match_dup 5) ++ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) ++ (set (match_dup 0) ++ (plus:SI (mult:SI (match_dup 6) (match_dup 3)) ++ (match_dup 4)))] ++{ ++ if (can_create_pseudo_p ()) ++ operands[5] = gen_reg_rtx (DImode); ++ else if (reg_overlap_mentioned_p (operands[5], operands[4])) ++ operands[5] = gen_lowpart (DImode, operands[0]); ++ ++ operands[6] = gen_lowpart (SImode, operands[5]); ++}) ++ ++(define_insn_and_split "*cmp_sadd_sidi" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (plus:SI (if_then_else:SI ++ (match_operator 1 "sw_64_zero_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (match_operand:SI 3 "const48_operand" "I") ++ (const_int 0)) ++ (match_operand:SI 4 "sext_add_operand" "rIO")))) ++ (clobber (match_scratch:DI 5 "=r"))] ++ "" ++ "#" ++ "" ++ [(set (match_dup 5) ++ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) ++ (set (match_dup 0) ++ (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3)) ++ (match_dup 4))))] ++{ ++ if (can_create_pseudo_p ()) ++ operands[5] = gen_reg_rtx (DImode); ++ else if (reg_overlap_mentioned_p (operands[5], operands[4])) ++ operands[5] = operands[0]; ++ ++ operands[6] = gen_lowpart (SImode, operands[5]); ++}) ++ ++(define_insn_and_split "*cmp_ssub_di" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (minus:DI (if_then_else:DI ++ (match_operator 1 "sw_64_zero_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (match_operand:DI 3 "const48_operand" "I") ++ (const_int 0)) ++ (match_operand:DI 4 "reg_or_8bit_operand" "rI"))) ++ (clobber (match_scratch:DI 5 "=r"))] ++ "" ++ "#" ++ "" ++ [(set (match_dup 5) ++ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) ++ (set (match_dup 0) ++ (minus:DI (mult:DI (match_dup 5) (match_dup 3)) ++ (match_dup 4)))] ++{ ++ if (can_create_pseudo_p ()) ++ operands[5] = gen_reg_rtx (DImode); ++ else if (reg_overlap_mentioned_p (operands[5], operands[4])) ++ operands[5] = operands[0]; ++}) ++ ++(define_insn_and_split "*cmp_ssub_si" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (minus:SI (if_then_else:SI ++ (match_operator 1 "sw_64_zero_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (match_operand:SI 3 "const48_operand" "I") ++ (const_int 0)) ++ (match_operand:SI 4 "reg_or_8bit_operand" "rI"))) ++ (clobber (match_scratch:DI 5 "=r"))] ++ "" ++ "#" ++ "" ++ [(set (match_dup 5) ++ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) ++ (set (match_dup 0) ++ (minus:SI (mult:SI (match_dup 6) (match_dup 3)) ++ (match_dup 4)))] ++{ ++ if (can_create_pseudo_p ()) ++ operands[5] = gen_reg_rtx (DImode); ++ else if (reg_overlap_mentioned_p (operands[5], operands[4])) ++ operands[5] = gen_lowpart (DImode, operands[0]); ++ ++ operands[6] = gen_lowpart (SImode, operands[5]); ++}) ++ ++(define_insn_and_split "*cmp_ssub_sidi" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (sign_extend:DI ++ (minus:SI (if_then_else:SI ++ (match_operator 1 "sw_64_zero_comparison_operator" ++ [(match_operand:DI 2 "reg_or_0_operand" "rJ") ++ (const_int 0)]) ++ (match_operand:SI 3 "const48_operand" "I") ++ (const_int 0)) ++ (match_operand:SI 4 "reg_or_8bit_operand" "rI")))) ++ (clobber (match_scratch:DI 5 "=r"))] ++ "" ++ "#" ++ "" ++ [(set (match_dup 5) ++ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) ++ (set (match_dup 0) ++ (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3)) ++ (match_dup 4))))] ++{ ++ if (can_create_pseudo_p ()) ++ operands[5] = gen_reg_rtx (DImode); ++ else if (reg_overlap_mentioned_p (operands[5], operands[4])) ++ operands[5] = operands[0]; ++ ++ operands[6] = gen_lowpart (SImode, operands[5]); ++}) ++ ++(define_expand "call" ++ [(use (match_operand:DI 0)) ++ (use (match_operand 1)) ++ (use (match_operand 2)) ++ (use (match_operand 3))] ++ "" ++{ ++ emit_call_insn (gen_call_osf (operands[0], operands[1])); ++ DONE; ++}) ++ ++(define_expand "sibcall" ++ [(parallel [(call (mem:DI (match_operand 0)) ++ (match_operand 1)) ++ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])] ++ "" ++{ ++ gcc_assert (MEM_P (operands[0])); ++ operands[0] = XEXP (operands[0], 0); ++}) ++ ++(define_expand "call_osf" ++ [(parallel [(call (mem:DI (match_operand 0)) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))])] ++ "" ++{ ++ gcc_assert (MEM_P (operands[0])); ++ ++ operands[0] = XEXP (operands[0], 0); ++ if (! call_operand (operands[0], Pmode)) ++ operands[0] = copy_to_mode_reg (Pmode, operands[0]); ++}) ++ ++ ++(define_expand "call_value" ++ [(use (match_operand 0)) ++ (use (match_operand:DI 1)) ++ (use (match_operand 2)) ++ (use (match_operand 3)) ++ (use (match_operand 4))] ++ "" ++{ ++ emit_call_insn (gen_call_value_osf (operands[0], operands[1], ++ operands[2])); ++ DONE; ++}) ++ ++(define_expand "sibcall_value" ++ [(parallel [(set (match_operand 0) ++ (call (mem:DI (match_operand 1)) ++ (match_operand 2))) ++ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])] ++ "" ++{ ++ gcc_assert (MEM_P (operands[1])); ++ operands[1] = XEXP (operands[1], 0); ++}) ++ ++(define_expand "call_value_osf" ++ [(parallel [(set (match_operand 0) ++ (call (mem:DI (match_operand 1)) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))])] ++ "" ++{ ++ gcc_assert (MEM_P (operands[1])); ++ ++ operands[1] = XEXP (operands[1], 0); ++ if (! call_operand (operands[1], Pmode)) ++ operands[1] = copy_to_mode_reg (Pmode, operands[1]); ++}) ++ ++ ++(define_insn "*call_osf_1_er_noreturn" ++ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS ++ && find_reg_note (insn, REG_NORETURN, NULL_RTX)" ++ "@ ++ call $26,($27),0 ++ bsr $26,%0\t\t!samegp ++ ldl $27,%0($29)\t\t!literal!%#\;call $26,($27),%0\t\t!lituse_jsr!%#" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,*,8")]) ++ ++(define_insn "*call_osf_1_er_setfpec0" ++ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 3" ++ "@ ++ call $26,(%0),0\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%* ++ bsr $26,%0\t\t!samegp ++ ldl $27,%0($29)\t\t!literal!%#\;call $26,($27),%0\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_osf_1_er_setfpec1" ++ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 1 " ++ "@ ++ call $26,(%0),0\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%* ++ bsr $26,%0\t\t!samegp ++ ldl $27,%0($29)\t\t!literal!%#\;call $26,($27),%0\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_osf_1_er" ++ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS" ++ "@ ++ call $26,(%0),0\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%* ++ bsr $26,%0\t\t!samegp ++ ldl $27,%0($29)\t\t!literal!%#\;call $26,($27),%0\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_osf_2_er_nogp" ++ [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (use (match_operand 2)) ++ (use (match_operand 3 "const_int_operand")) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS" ++ "call $26,(%0),%2%J3" ++ [(set_attr "type" "call")]) ++ ++ ++(define_insn "*call_osf_2_er_setfpec0" ++ [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) ++ (match_operand 1)) ++ (set (reg:DI 29) ++ (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")] ++ UNSPEC_LDGP1)) ++ (use (match_operand 2)) ++ (use (match_operand 3 "const_int_operand")) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 3 " ++ "call $26,(%0),%2%J3\;ldih $29,0($26)\t\t!gpdisp!%4" ++ [(set_attr "type" "call") ++ (set_attr "cannot_copy" "true") ++ (set_attr "length" "8")]) ++ ++(define_insn "*call_osf_2_er_setfpec1" ++ [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) ++ (match_operand 1)) ++ (set (reg:DI 29) ++ (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")] ++ UNSPEC_LDGP1)) ++ (use (match_operand 2)) ++ (use (match_operand 3 "const_int_operand")) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 1 " ++ "call $26,(%0),%2%J3\;ldih $29,0($26)\t\t!gpdisp!%4" ++ [(set_attr "type" "call") ++ (set_attr "cannot_copy" "true") ++ (set_attr "length" "8")]) ++ ++(define_insn "*call_osf_2_er" ++ [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) ++ (match_operand 1)) ++ (set (reg:DI 29) ++ (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")] ++ UNSPEC_LDGP1)) ++ (use (match_operand 2)) ++ (use (match_operand 3 "const_int_operand")) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS" ++ "call $26,(%0),%2%J3\;ldih $29,0($26)\t\t!gpdisp!%4" ++ [(set_attr "type" "call") ++ (set_attr "cannot_copy" "true") ++ (set_attr "length" "8")]) ++ ++(define_insn "*call_osf_1_noreturn" ++ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "! TARGET_EXPLICIT_RELOCS ++ && find_reg_note (insn, REG_NORETURN, NULL_RTX)" ++ "@ ++ call $26,($27),0 ++ bsr $26,$%0..ng ++ call $26,%0" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,*,8")]) ++ ++(define_insn "*call_osf_1" ++ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) ++ (match_operand 1)) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "! TARGET_EXPLICIT_RELOCS" ++ "@ ++ call $26,($27),0\;ldgp $29,0($26) ++ bsr $26,$%0..ng ++ call $26,%0\;ldgp $29,0($26)" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*sibcall_osf_1_er" ++ [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) ++ (match_operand 1)) ++ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] ++ "TARGET_EXPLICIT_RELOCS" ++ "@ ++ br $31,%0\t\t!samegp ++ ldl $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,8")]) ++ ++(define_insn "*sibcall_osf_1" ++ [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) ++ (match_operand 1)) ++ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] ++ "! TARGET_EXPLICIT_RELOCS" ++ "@ ++ br $31,$%0..ng ++ ldi $27,%0\;jmp $31,($27),%0" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,8")]) ++ ++(define_expand "rsqrtsf2" ++ [(match_operand:SF 0 "register_operand" "") ++ (match_operand:SF 1 "register_operand" "")] ++ "TARGET_FP && flag_reciprocal_math == 1 && flag_sw_rsqrt == 1" ++ { ++ sw_64_emit_rsqrt (operands[0], operands[1], 1); ++ DONE; ++ }) ++ ++(define_insn "*movsf2" ++ [(set (match_operand:SF 0 "nonimmediate_operand" "=r") ++ (unspec:SF [(match_operand:SF 1 "input_operand" "f")] ++ UNSPEC_FIMOVS))] ++ "TARGET_FP && flag_reciprocal_math == 1 && flag_sw_rsqrt == 1" ++ "fimovs %1,%0" ++ [(set_attr "type" "ldsym")]) ++ ++(define_expand "untyped_call" ++ [(parallel [(call (match_operand 0) ++ (const_int 0)) ++ (match_operand 1) ++ (match_operand 2)])] ++ "" ++{ ++ int i; ++ ++ emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); ++ ++ for (i = 0; i < XVECLEN (operands[2], 0); i++) ++ { ++ rtx set = XVECEXP (operands[2], 0, i); ++ emit_move_insn (SET_DEST (set), SET_SRC (set)); ++ } ++ ++ /* The optimizer does not know that the call sets the function value ++ registers we stored in the result block. We avoid problems by ++ claiming that all hard registers are used and clobbered at this ++ point. */ ++ emit_insn (gen_blockage ()); ++ ++ DONE; ++}) ++ ++;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ++;; all of memory. This blocks insns from being moved across this point. ++ ++(define_insn "blockage" ++ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] ++ "" ++ "" ++ [(set_attr "length" "0") ++ (set_attr "type" "none")]) ++ ++(define_insn "jump" ++ [(set (pc) ++ (label_ref (match_operand 0)))] ++ "" ++ "br $31,%l0" ++ [(set_attr "type" "ibr")]) ++ ++(define_expand "return" ++ [(return)] ++ "direct_return ()") ++ ++(define_insn "*return_internal" ++ [(return)] ++ "reload_completed" ++{ ++ return "ret $31,($26),1"; ++} ++ ++ [(set_attr "type" "ibr")]) ++ ++(define_insn "indirect_jump" ++ [(set (pc) (match_operand:DI 0 "register_operand" "r"))] ++ "" ++ "jmp $31,(%0),0" ++ [(set_attr "type" "ibr")]) ++ ++(define_expand "tablejump" ++ [(parallel [(set (pc) ++ (match_operand 0 "register_operand")) ++ (use (label_ref:DI (match_operand 1)))])] ++ "" ++{ ++ rtx dest = gen_reg_rtx (DImode); ++ emit_insn (gen_extendsidi2 (dest, operands[0])); ++ emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest)); ++ operands[0] = dest; ++}) ++ ++(define_insn "*tablejump_internal" ++ [(set (pc) ++ (match_operand:DI 0 "register_operand" "r")) ++ (use (label_ref (match_operand 1)))] ++ "" ++ "jmp $31,(%0),0" ++ [(set_attr "type" "ibr")]) ++ ++(define_insn "imb" ++ [(unspec_volatile [(const_int 0)] UNSPECV_IMB)] ++ "" ++ "sys_call 0x86" ++ [(set_attr "type" "callpal")]) ++ ++(define_expand "clear_cache" ++ [(match_operand:DI 0) ; region start ++ (match_operand:DI 1)] ; region end ++ "" ++{ ++ emit_insn (gen_imb ()); ++ DONE; ++}) ++ ++(define_insn "trap" ++ [(trap_if (const_int 1) (const_int 0)) ++ (use (reg:DI 29))] ++ "" ++ "sys_call 0x80" ++ [(set_attr "type" "callpal")]) ++ ++;; For userland, we load the thread pointer from the TCB. ++;; For the kernel, we load the per-cpu private value. ++ ++(define_insn "get_thread_pointerdi" ++ [(set (match_operand:DI 0 "register_operand" "=v") ++ (unspec:DI [(const_int 0)] UNSPEC_TP))] ++ "" ++{ ++ if (TARGET_TLS_KERNEL) ++ return "sys_call 0x32"; ++ else if (flag_sw_rtid == 1) ++ return "rtid %0"; ++ else ++ return "sys_call 0x9e"; ++} ++ [(set_attr "type" "callpal")]) ++ ++;; For completeness, and possibly a __builtin function, here's how to ++;; set the thread pointer. Since we don't describe enough of this ++;; quantity for CSE, we have to use a volatile unspec, and then there's ++;; not much point in creating an R16_REG register class. ++ ++(define_expand "set_thread_pointerdi" ++ [(set (reg:DI 16) (match_operand:DI 0 "input_operand")) ++ (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)] ++ "") ++ ++(define_insn "*set_tp" ++ [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)] ++ "" ++{ ++ if (TARGET_TLS_KERNEL) ++ return "sys_call 0x31"; ++ else ++ return "sys_call 0x9f"; ++} ++ [(set_attr "type" "callpal")]) ++ ++;; Finally, we have the basic data motion insns. The byte and word insns ++;; are done via define_expand. Start with the floating-point insns, since ++;; they are simpler. ++ ++(define_expand "movsf" ++ [(set (match_operand:SF 0 "nonimmediate_operand") ++ (match_operand:SF 1 "general_operand"))] ++ "" ++{ ++ if (MEM_P (operands[0]) ++ && ! reg_or_0_operand (operands[1], SFmode)) ++ operands[1] = force_reg (SFmode, operands[1]); ++}) ++ ++(define_insn "*movsf" ++ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r") ++ (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))] ++ "register_operand (operands[0], SFmode) ++ || reg_or_0_operand (operands[1], SFmode)" ++ "@ ++ fcpys %R1,%R1,%0 ++ fld%,%U1 %0,%1 ++ bis $31,%r1,%0 ++ ldw %0,%1 ++ fst%,%U0 %R1,%0 ++ stw %r1,%0 ++ ifmovs %1,%0 ++ fimovs %1,%0" ++ [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi") ++ (set_attr "isa" "*,*,*,*,*,*,fix,fix")]) ++ ++(define_expand "movdf" ++ [(set (match_operand:DF 0 "nonimmediate_operand") ++ (match_operand:DF 1 "general_operand"))] ++ "" ++{ ++ if (MEM_P (operands[0]) ++ && ! reg_or_0_operand (operands[1], DFmode)) ++ operands[1] = force_reg (DFmode, operands[1]); ++}) ++(define_insn "*movdf" ++ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r") ++ (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))] ++ "register_operand (operands[0], DFmode) ++ || reg_or_0_operand (operands[1], DFmode)" ++ "@ ++ fcpys %R1,%R1,%0 ++ fld%-%U1 %0,%1 ++ bis $31,%r1,%0 ++ ldl %0,%1 ++ fst%-%U0 %R1,%0 ++ stl %r1,%0 ++ ifmovd %1,%0 ++ fimovd %1,%0" ++ [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi") ++ (set_attr "isa" "*,*,*,*,*,*,fix,fix")]) ++ ++(define_expand "storentdf" ++ [(set (match_operand:DF 0 "nonimmediate_operand") ++ (unspec:DF [(match_operand:DF 1 "general_operand")] UNSPEC_NTDF))] ++ "flag_sw_non_temporal == 1" ++{ ++ if (MEM_P (operands[0]) ++ && ! reg_or_0_operand (operands[1], DFmode)) ++ operands[1] = force_reg (DFmode, operands[1]); ++}) ++ ++(define_insn "*storentdf" ++ [(set (match_operand:DF 0 "nonimmediate_operand" "=m") ++ (unspec:DF [(match_operand:DF 1 "input_operand" "fG")] UNSPEC_NTDF))] ++ "register_operand (operands[0], DFmode) ++ || reg_or_0_operand (operands[1], DFmode)" ++ "std_nc %R1,%0" ++ [(set_attr "type" "fst") ++ (set_attr "isa" "*")]) ++ ++;; Subregs suck for register allocation. Pretend we can move TFmode ++;; data between general registers until after reload. ++;; ??? Is this still true now that we have the lower-subreg pass? ++ ++(define_expand "movtf" ++ [(set (match_operand:TF 0 "nonimmediate_operand") ++ (match_operand:TF 1 "general_operand"))] ++ "" ++{ ++ if (MEM_P (operands[0]) ++ && ! reg_or_0_operand (operands[1], TFmode)) ++ operands[1] = force_reg (TFmode, operands[1]); ++}) ++ ++(define_insn_and_split "*movtf_internal" ++ [(set (match_operand:TF 0 "nonimmediate_operand" "=r,m") ++ (match_operand:TF 1 "input_operand" "rmG,rG"))] ++ "register_operand (operands[0], TFmode) ++ || reg_or_0_operand (operands[1], TFmode)" ++ "#" ++ "reload_completed" ++ [(set (match_dup 0) (match_dup 2)) ++ (set (match_dup 1) (match_dup 3))] ++ "sw_64_split_tmode_pair (operands, TFmode, true);") ++ ++(define_expand "movsi" ++ [(set (match_operand:SI 0 "nonimmediate_operand") ++ (match_operand:SI 1 "general_operand"))] ++ "" ++{ ++ if (sw_64_expand_mov (SImode, operands)) ++ DONE; ++}) ++ ++(define_insn "*movsi" ++ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r") ++ (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ,s"))] ++ "register_operand (operands[0], SImode) ++ || reg_or_0_operand (operands[1], SImode)" ++ "@ ++ bis $31,%r1,%0 ++ ldi %0,%1($31) ++ ldih %0,%h1($31) ++ # ++ ldw%U1 %0,%1 ++ stw%U0 %r1,%0 ++ ldi %0,%1" ++ [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist,ldsym") ++ (set_attr "isa" "*,*,*,*,*,*,vms")]) ++ ++(define_expand "storentsi" ++ [(set (match_operand:SI 0 "nonimmediate_operand") ++ (unspec:SI [(match_operand:SI 1 "input_operand")] UNSPEC_NTSI))] ++ "flag_sw_non_temporal == 1" ++{ ++ if (sw_64_expand_mov (SImode, operands)) ++ DONE; ++}) ++ ++(define_insn "*storentsi" ++ [(set (match_operand:SI 0 "nonimmediate_operand" "=m") ++ (unspec:SI [(match_operand:SI 1 "input_operand" "rJ")] UNSPEC_NTSI))] ++ "register_operand (operands[0], SImode) ++ || reg_or_0_operand (operands[1], SImode)" ++ "stw_nc %r1,%0" ++ [(set_attr "type" "ist") ++ (set_attr "isa" "*")]) ++ ++;; Split a load of a large constant into the appropriate two-insn ++;; sequence. ++ ++(define_split ++ [(set (match_operand:SI 0 "register_operand") ++ (match_operand:SI 1 "non_add_const_operand"))] ++ "" ++ [(const_int 0)] ++{ ++ if (sw_64_split_const_mov (SImode, operands)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++(define_insn "*movdi_er_low_l" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (lo_sum:DI (match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "local_symbolic_operand")))] ++ "TARGET_EXPLICIT_RELOCS" ++{ ++ if (true_regnum (operands[1]) == 29) ++ return "ldi %0,%2(%1)\t\t!gprel"; ++ else ++ return "ldi %0,%2(%1)\t\t!gprellow"; ++} ++ [(set_attr "usegp" "yes")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "small_symbolic_operand"))] ++ "TARGET_EXPLICIT_RELOCS && reload_completed" ++ [(set (match_dup 0) ++ (lo_sum:DI (match_dup 2) (match_dup 1)))] ++ "operands[2] = pic_offset_table_rtx;") ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "local_symbolic_operand"))] ++ "TARGET_EXPLICIT_RELOCS && reload_completed" ++ [(set (match_dup 0) ++ (plus:DI (match_dup 2) (high:DI (match_dup 1)))) ++ (set (match_dup 0) ++ (lo_sum:DI (match_dup 0) (match_dup 1)))] ++ "operands[2] = pic_offset_table_rtx;") ++ ++(define_split ++ [(match_operand 0 "some_small_symbolic_operand")] ++ "" ++ [(match_dup 0)] ++ "operands[0] = split_small_symbolic_operand (operands[0]);") ++ ++(define_insn "movdi_er_high_g" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand") ++ (match_operand 3 "const_int_operand")] ++ UNSPEC_LITERAL))] ++ "TARGET_EXPLICIT_RELOCS" ++{ ++ if (INTVAL (operands[3]) == 0) ++ return "ldl %0,%2(%1)\t\t!literal"; ++ else ++ return "ldl %0,%2(%1)\t\t!literal!%3"; ++} ++ [(set_attr "type" "ldsym")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "global_symbolic_operand"))] ++ "TARGET_EXPLICIT_RELOCS && reload_completed" ++ [(set (match_dup 0) ++ (unspec:DI [(match_dup 2) ++ (match_dup 1) ++ (const_int 0)] UNSPEC_LITERAL))] ++ "operands[2] = pic_offset_table_rtx;") ++ ++(define_insn "movdi_er_tlsgd" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand") ++ (match_operand 3 "const_int_operand")] ++ UNSPEC_TLSGD))] ++ "HAVE_AS_TLS" ++{ ++ if (INTVAL (operands[3]) == 0) ++ return "ldi %0,%2(%1)\t\t!tlsgd"; ++ else ++ return "ldi %0,%2(%1)\t\t!tlsgd!%3"; ++} ++[(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*movdi_er_tlsrelgot" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand") ++ (match_operand 3 "const_int_operand")] ++ UNSPEC_TLSRELGOT))] ++ "HAVE_AS_TLS" ++{ ++ if (INTVAL (operands[3]) == 0) ++ return "ldih %0,%2(%1)\t\t!tlsrel_got"; ++ else ++ return "ldih %0,%2(%1)\t\t!tlsrel_got!%3"; ++} ++[(set_attr "cannot_copy" "true")]) ++ ++(define_insn "movdi_er_tlsldm" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPEC_TLSLDM))] ++ "HAVE_AS_TLS" ++{ ++ if (INTVAL (operands[2]) == 0) ++ return "ldi %0,%&(%1)\t\t!tlsldm"; ++ else ++ return "ldi %0,%&(%1)\t\t!tlsldm!%2"; ++} ++[(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*movdi_er_gotdtprel" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand") ++ (match_operand 3 "const_int_operand")] ++ UNSPEC_GOTDTPREL))] ++ "HAVE_AS_TLS" ++{ ++ if (INTVAL (operands[3]) == 0) ++ return "ldl %0,%2(%1)\t\t!gotdtprel"; ++ else ++ return "ldl %0,%2(%1)\t\t!gotdtprel!%3"; ++} ++[(set_attr "type" "ild") ++ (set_attr "usegp" "yes")]) ++ ++(define_insn "*movdi_er_gotdtp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand")] ++ UNSPEC_DTPREL))] ++ "HAVE_AS_TLS" ++ "ldl %0,%2(%1)\t\t!gotdtprel" ++ [(set_attr "type" "ild") ++ (set_attr "usegp" "yes")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "gotdtp_symbolic_operand"))] ++ "HAVE_AS_TLS && reload_completed" ++ [(set (match_dup 0) ++ (unspec:DI [(match_dup 2) ++ (match_dup 1)] UNSPEC_DTPREL))] ++{ ++ operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0); ++ operands[2] = pic_offset_table_rtx; ++}) ++ ++(define_insn "*movdi_er_gottprel" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand") ++ (match_operand 3 "const_int_operand")] ++ UNSPEC_TPREL))] ++ "HAVE_AS_TLS" ++{ ++ if (INTVAL (operands[3]) == 0) ++ return "ldl %0,%2(%1)\t\t!gottprel"; ++ else ++ return "ldl %0,%2(%1)\t\t!gottprel!%3"; ++} ++[(set_attr "type" "ild") ++ (set_attr "usegp" "yes")]) ++ ++(define_insn "*movdi_er_gottp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand:DI 2 "symbolic_operand")] ++ UNSPEC_TPREL))] ++ "HAVE_AS_TLS" ++ "ldl %0,%2(%1)\t\t!gottprel" ++ [(set_attr "type" "ild") ++ (set_attr "usegp" "yes")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "gottp_symbolic_operand"))] ++ "HAVE_AS_TLS && reload_completed" ++ [(set (match_dup 0) ++ (unspec:DI [(match_dup 2) ++ (match_dup 1)] UNSPEC_TPREL))] ++{ ++ operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0); ++ operands[2] = pic_offset_table_rtx; ++}) ++ ++(define_insn "*movdi" ++ [(set (match_operand:DI 0 "nonimmediate_operand" ++ "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f") ++ (match_operand:DI 1 "input_operand" ++ "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))] ++ "register_operand (operands[0], DImode) ++ || reg_or_0_operand (operands[1], DImode)" ++ "@ ++ mov %r1,%0 ++ ldi %0,%1($31) ++ ldih %0,%h1($31) ++ # ++ # ++ # ++ ldi %0,%1 ++ ldl%A1%U1 %0,%1 ++ stl%A0%U0 %r1,%0 ++ fmov %R1,%0 ++ fldd%U1 %0,%1 ++ fstd%U0 %R1,%0 ++ fimovd %1,%0 ++ ifmovd %1,%0" ++ [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof") ++ (set_attr "isa" "*,*,*,er,er,*,ner,*,*,*,*,*,fix,fix") ++ (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*,*")]) ++ ++(define_expand "storentdi" ++ [(set (match_operand:DI 0 "nonimmediate_operand") ++ (unspec:DI [(match_operand:DI 1 "input_operand")] UNSPEC_NTDI))] ++ "flag_sw_non_temporal == 1" ++{ ++ if (sw_64_expand_mov (DImode, operands)) ++ DONE; ++}) ++ ++(define_insn "*storentdi" ++ [(set (match_operand:DI 0 "nonimmediate_operand" "=m") ++ (unspec:DI [(match_operand:DI 1 "input_operand" "rJ")] UNSPEC_NTDI))] ++ "register_operand (operands[0], DImode) ++ || reg_or_0_operand (operands[1], DImode)" ++ "stl_nc %r1,%0" ++ [(set_attr "type" "ist") ++ (set_attr "isa" "*") ++ (set_attr "usegp" "*")]) ++ ++(define_insn "force_movdi" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")] ++ UNSPECV_FORCE_MOV))] ++ "" ++ "mov %1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_expand "movdi" ++ [(set (match_operand:DI 0 "nonimmediate_operand") ++ (match_operand:DI 1 "general_operand"))] ++ "" ++{ ++ if (sw_64_expand_mov (DImode, operands)) ++ DONE; ++}) ++ ++;; Split a load of a large constant into the appropriate two-insn ++;; sequence. ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "non_add_const_operand"))] ++ "" ++ [(const_int 0)] ++{ ++ if (sw_64_split_const_mov (DImode, operands)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++;; We need to prevent reload from splitting TImode moves, because it ++;; might decide to overwrite a pointer with the value it points to. ++;; In that case we have to do the loads in the appropriate order so ++;; that the pointer is not destroyed too early. ++ ++(define_insn_and_split "*movti_internal" ++ [(set (match_operand:TI 0 "nonimmediate_operand" "=r,m") ++ (match_operand:TI 1 "input_operand" "rmJ,rJ"))] ++ "(register_operand (operands[0], TImode) ++ /* Prevent rematerialization of constants. */ ++ && ! CONSTANT_P (operands[1])) ++ || reg_or_0_operand (operands[1], TImode)" ++ "#" ++ "reload_completed" ++ [(set (match_dup 0) (match_dup 2)) ++ (set (match_dup 1) (match_dup 3))] ++ "sw_64_split_tmode_pair (operands, TImode, true);") ++ ++(define_expand "movti" ++ [(set (match_operand:TI 0 "nonimmediate_operand") ++ (match_operand:TI 1 "general_operand"))] ++ "" ++{ ++ if (MEM_P (operands[0]) ++ && ! reg_or_0_operand (operands[1], TImode)) ++ operands[1] = force_reg (TImode, operands[1]); ++ ++ if (operands[1] == const0_rtx) ++ ; ++ /* We must put 64-bit constants in memory. We could keep the ++ 32-bit constants in TImode and rely on the splitter, but ++ this doesn't seem to be worth the pain. */ ++ else if (CONST_SCALAR_INT_P (operands[1])) ++ { ++ rtx in[2], out[2], target; ++ ++ gcc_assert (can_create_pseudo_p ()); ++ ++ split_double (operands[1], &in[0], &in[1]); ++ ++ if (in[0] == const0_rtx) ++ out[0] = const0_rtx; ++ else ++ { ++ out[0] = gen_reg_rtx (DImode); ++ emit_insn (gen_movdi (out[0], in[0])); ++ } ++ ++ if (in[1] == const0_rtx) ++ out[1] = const0_rtx; ++ else ++ { ++ out[1] = gen_reg_rtx (DImode); ++ emit_insn (gen_movdi (out[1], in[1])); ++ } ++ ++ if (!REG_P (operands[0])) ++ target = gen_reg_rtx (TImode); ++ else ++ target = operands[0]; ++ ++ emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0])); ++ emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1])); ++ ++ if (target != operands[0]) ++ emit_insn (gen_rtx_SET (operands[0], target)); ++ ++ DONE; ++ } ++}) ++ ++;; These are the partial-word cases. ++;; ++;; First we have the code to load an aligned word. Operand 0 is the register ++;; in which to place the result. It's mode is QImode or HImode. Operand 1 ++;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the ++;; number of bits within the word that the value is. Operand 3 is an SImode ++;; scratch register. If operand 0 is a hard register, operand 3 may be the ++;; same register. It is allowed to conflict with operand 1 as well. ++ ++(define_expand "aligned_loadqi" ++ [(set (match_operand:SI 3 "register_operand") ++ (match_operand:SI 1 "memory_operand")) ++ (set (match_operand:DI 0 "register_operand") ++ (zero_extract:DI (subreg:DI (match_dup 3) 0) ++ (const_int 8) ++ (match_operand:DI 2 "const_int_operand")))]) ++ ++(define_expand "aligned_loadhi" ++ [(set (match_operand:SI 3 "register_operand") ++ (match_operand:SI 1 "memory_operand")) ++ (set (match_operand:DI 0 "register_operand") ++ (zero_extract:DI (subreg:DI (match_dup 3) 0) ++ (const_int 16) ++ (match_operand:DI 2 "const_int_operand")))]) ++ ++;; Similar for unaligned loads, where we use the sequence from the ++;; Sw_64 Architecture manual. We have to distinguish between little-endian ++;; and big-endian systems as the sequences are different. ++;; ++;; Operand 1 is the address. Operands 2 and 3 are temporaries, where ++;; operand 3 can overlap the input and output registers. ++ ++(define_expand "unaligned_loadqi" ++ [(set (match_operand:DI 2 "register_operand") ++ (mem:DI (and:DI (match_operand:DI 1 "address_operand") ++ (const_int -8)))) ++ (set (match_operand:DI 3 "register_operand") ++ (match_dup 1)) ++ (set (match_operand:DI 0 "register_operand") ++ (zero_extract:DI (match_dup 2) ++ (const_int 8) ++ (ashift:DI (match_dup 3) (const_int 3))))]) ++ ++(define_expand "unaligned_loadhi" ++ [(set (match_operand:DI 2 "register_operand") ++ (mem:DI (and:DI (match_operand:DI 1 "address_operand") ++ (const_int -8)))) ++ (set (match_operand:DI 3 "register_operand") ++ (match_dup 1)) ++ (set (match_operand:DI 0 "register_operand") ++ (zero_extract:DI (match_dup 2) ++ (const_int 16) ++ (ashift:DI (match_dup 3) (const_int 3))))]) ++ ++;; Storing an aligned byte or word requires two temporaries. Operand 0 is the ++;; aligned SImode MEM. Operand 1 is the register containing the ++;; byte or word to store. Operand 2 is the number of bits within the word that ++;; the value should be placed. Operands 3 and 4 are SImode temporaries. ++ ++(define_expand "aligned_store" ++ [(set (match_operand:SI 3 "register_operand") ++ (match_operand:SI 0 "memory_operand")) ++ (set (subreg:DI (match_dup 3) 0) ++ (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5))) ++ (set (subreg:DI (match_operand:SI 4 "register_operand") 0) ++ (ashift:DI (zero_extend:DI (match_operand 1 "register_operand")) ++ (match_operand:DI 2 "const_int_operand"))) ++ (set (subreg:DI (match_dup 4) 0) ++ (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0))) ++ (set (match_dup 0) (match_dup 4))] ++ "" ++{ ++ operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1])) ++ << INTVAL (operands[2]))); ++}) ++ ++;; For the unaligned byte and halfword cases, we use code similar to that ++;; in the ;; Architecture book, but reordered to lower the number of registers ++;; required. Operand 0 is the address. Operand 1 is the data to store. ++;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may ++;; be the same temporary, if desired. If the address is in a register, ++;; operand 2 can be that register. ++ ++(define_expand "@unaligned_store" ++ [(set (match_operand:DI 3 "register_operand") ++ (mem:DI (and:DI (match_operand:DI 0 "address_operand") ++ (const_int -8)))) ++ (set (match_operand:DI 2 "register_operand") ++ (match_dup 0)) ++ (set (match_dup 3) ++ (and:DI (not:DI (ashift:DI (match_dup 5) ++ (ashift:DI (match_dup 2) (const_int 3)))) ++ (match_dup 3))) ++ (set (match_operand:DI 4 "register_operand") ++ (ashift:DI (zero_extend:DI ++ (match_operand:I12MODE 1 "register_operand")) ++ (ashift:DI (match_dup 2) (const_int 3)))) ++ (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3))) ++ (set (mem:DI (and:DI (match_dup 0) (const_int -8))) ++ (match_dup 4))] ++ "" ++ "operands[5] = GEN_INT (GET_MODE_MASK (mode));") ++ ++;; Here are the define_expand's for QI and HI moves that use the above ++;; patterns. We have the normal sets, plus the ones that need scratch ++;; registers for reload. ++ ++(define_expand "mov" ++ [(set (match_operand:I12MODE 0 "nonimmediate_operand") ++ (match_operand:I12MODE 1 "general_operand"))] ++ "" ++{ ++ if (sw_64_expand_mov (mode, operands)) ++ DONE; ++}) ++ ++(define_insn "*movqi" ++ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m") ++ (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))] ++ "register_operand (operands[0], QImode) ++ || reg_or_0_operand (operands[1], QImode)" ++ "@ ++ bis $31,%r1,%0 ++ ldi %0,%L1($31) ++ ldbu%U1 %0,%1 ++ stb%U0 %r1,%0" ++ [(set_attr "type" "ilog,iadd,ild,ist") ++ (set_attr "isa" "*,*,bwx,bwx")]) ++ ++(define_insn "*movhi" ++ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") ++ (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))] ++ "register_operand (operands[0], HImode) ++ || reg_or_0_operand (operands[1], HImode)" ++ "@ ++ bis $31,%r1,%0 ++ ldi %0,%L1($31) ++ ldhu%U1 %0,%1 ++ sth%U0 %r1,%0" ++ [(set_attr "type" "ilog,iadd,ild,ist") ++ (set_attr "isa" "*,*,bwx,bwx")]) ++ ++;; Helpers for the above. The way reload is structured, we can't ++;; always get a proper address for a stack slot during reload_foo ++;; expansion, so we must delay our address manipulations until after. ++ ++(define_insn_and_split "@reload_in_aligned" ++ [(set (match_operand:I12MODE 0 "register_operand" "=r") ++ (match_operand:I12MODE 1 "memory_operand" "m"))] ++ "!TARGET_BWX && (reload_in_progress || reload_completed)" ++ "#" ++ "!TARGET_BWX && reload_completed" ++ [(const_int 0)] ++{ ++ rtx aligned_mem, bitnum; ++ get_aligned_mem (operands[1], &aligned_mem, &bitnum); ++ emit_insn (gen_aligned_load ++ (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum, ++ gen_rtx_REG (SImode, REGNO (operands[0])))); ++ DONE; ++}) ++ ++ ++(define_mode_iterator VEC [V8QI V4HI V2SI]) ++(define_mode_iterator VEC12 [V8QI V4HI]) ++ ++(define_expand "mov" ++ [(set (match_operand:VEC 0 "nonimmediate_operand") ++ (match_operand:VEC 1 "general_operand"))] ++ "" ++{ ++ if (sw_64_expand_mov (mode, operands)) ++ DONE; ++}) ++ ++(define_split ++ [(set (match_operand:VEC 0 "register_operand") ++ (match_operand:VEC 1 "non_zero_const_operand"))] ++ "" ++ [(const_int 0)] ++{ ++ if (sw_64_split_const_mov (mode, operands)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++(define_expand "movmisalign" ++ [(set (match_operand:VEC 0 "nonimmediate_operand") ++ (match_operand:VEC 1 "general_operand"))] ++ "flag_sw_unalign_byte != 1 || !TARGET_SW8A" ++{ ++ sw_64_expand_movmisalign (mode, operands); ++ DONE; ++}) ++ ++(define_insn "*mov_fix" ++ [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f") ++ (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))] ++ "register_operand (operands[0], mode) ++ || reg_or_0_operand (operands[1], mode)" ++ "@ ++ bis $31,%r1,%0 ++ # ++ ldl%A1%U1 %0,%1 ++ stl%A0%U0 %r1,%0 ++ fcpys %R1,%R1,%0 ++ fldd%U1 %0,%1 ++ fstd%U0 %R1,%0 ++ fimovd %1,%0 ++ ifmovd %1,%0" ++ [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof") ++ (set_attr "isa" "*,*,*,*,*,*,*,fix,fix")]) ++ ++(define_insn "3" ++ [(set (match_operand:VEC12 0 "register_operand" "=r") ++ (any_maxmin:VEC12 ++ (match_operand:VEC12 1 "reg_or_0_operand" "rW") ++ (match_operand:VEC12 2 "reg_or_0_operand" "rW")))] ++ "TARGET_MAX" ++ " %r1,%r2,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_insn "one_cmpl2" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (not:VEC (match_operand:VEC 1 "register_operand" "r")))] ++ "" ++ "ornot $31,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "and3" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (and:VEC (match_operand:VEC 1 "register_operand" "r") ++ (match_operand:VEC 2 "register_operand" "r")))] ++ "" ++ "and %1,%2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*andnot3" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r")) ++ (match_operand:VEC 2 "register_operand" "r")))] ++ "" ++ "bic %2,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "ior3" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (ior:VEC (match_operand:VEC 1 "register_operand" "r") ++ (match_operand:VEC 2 "register_operand" "r")))] ++ "" ++ "bis %1,%2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*iornot3" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r")) ++ (match_operand:VEC 2 "register_operand" "r")))] ++ "" ++ "ornot %2,%1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "xor3" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (xor:VEC (match_operand:VEC 1 "register_operand" "r") ++ (match_operand:VEC 2 "register_operand" "r")))] ++ "" ++ "xor %1,%2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "*xornot3" ++ [(set (match_operand:VEC 0 "register_operand" "=r") ++ (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r") ++ (match_operand:VEC 2 "register_operand" "r"))))] ++ "" ++ "eqv %1,%2,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_expand "vec_shl_" ++ [(set (match_operand:VEC 0 "register_operand") ++ (ashift:DI (match_operand:VEC 1 "register_operand") ++ (match_operand:DI 2 "reg_or_6bit_operand")))] ++ "" ++{ ++ operands[0] = gen_lowpart (DImode, operands[0]); ++ operands[1] = gen_lowpart (DImode, operands[1]); ++}) ++ ++(define_expand "vec_shr_" ++ [(set (match_operand:VEC 0 "register_operand") ++ (lshiftrt:DI (match_operand:VEC 1 "register_operand") ++ (match_operand:DI 2 "reg_or_6bit_operand")))] ++ "" ++{ ++ operands[0] = gen_lowpart (DImode, operands[0]); ++ operands[1] = gen_lowpart (DImode, operands[1]); ++}) ++ ++ ++(define_expand "extvmisaligndi" ++ [(set (match_operand:DI 0 "register_operand") ++ (sign_extract:DI (match_operand:BLK 1 "memory_operand") ++ (match_operand:DI 2 "const_int_operand") ++ (match_operand:DI 3 "const_int_operand")))] ++ "" ++{ ++ /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */ ++ if (INTVAL (operands[3]) % 8 != 0 ++ || (INTVAL (operands[2]) != 16 ++ && INTVAL (operands[2]) != 32 ++ && INTVAL (operands[2]) != 64)) ++ FAIL; ++ ++ sw_64_expand_unaligned_load (operands[0], operands[1], ++ INTVAL (operands[2]) / 8, ++ INTVAL (operands[3]) / 8, 1); ++ DONE; ++}) ++ ++(define_expand "extzvdi" ++ [(set (match_operand:DI 0 "register_operand") ++ (zero_extract:DI (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "const_int_operand") ++ (match_operand:DI 3 "const_int_operand")))] ++ "" ++{ ++ /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */ ++ if (INTVAL (operands[3]) % 8 != 0 ++ || (INTVAL (operands[2]) != 8 ++ && INTVAL (operands[2]) != 16 ++ && INTVAL (operands[2]) != 32 ++ && INTVAL (operands[2]) != 64)) ++ FAIL; ++}) ++ ++(define_expand "extzvmisaligndi" ++ [(set (match_operand:DI 0 "register_operand") ++ (zero_extract:DI (match_operand:BLK 1 "memory_operand") ++ (match_operand:DI 2 "const_int_operand") ++ (match_operand:DI 3 "const_int_operand")))] ++ "" ++{ ++ /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. ++ We fail 8-bit fields, falling back on a simple byte load. */ ++ if (INTVAL (operands[3]) % 8 != 0 ++ || (INTVAL (operands[2]) != 16 ++ && INTVAL (operands[2]) != 32 ++ && INTVAL (operands[2]) != 64)) ++ FAIL; ++ ++ sw_64_expand_unaligned_load (operands[0], operands[1], ++ INTVAL (operands[2]) / 8, ++ INTVAL (operands[3]) / 8, 0); ++ DONE; ++}) ++ ++(define_expand "insvmisaligndi" ++ [(set (zero_extract:DI (match_operand:BLK 0 "memory_operand") ++ (match_operand:DI 1 "const_int_operand") ++ (match_operand:DI 2 "const_int_operand")) ++ (match_operand:DI 3 "register_operand"))] ++ "" ++{ ++ /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */ ++ if (INTVAL (operands[2]) % 8 != 0 ++ || (INTVAL (operands[1]) != 16 ++ && INTVAL (operands[1]) != 32 ++ && INTVAL (operands[1]) != 64)) ++ FAIL; ++ ++ sw_64_expand_unaligned_store (operands[0], operands[3], ++ INTVAL (operands[1]) / 8, ++ INTVAL (operands[2]) / 8); ++ DONE; ++}) ++ ++;; Block move/clear, see sw_64.c for more details. ++;; Argument 0 is the destination ++;; Argument 1 is the source ++;; Argument 2 is the length ++;; Argument 3 is the alignment ++ ++(define_expand "cpymemqi" ++ [(parallel [(set (match_operand:BLK 0 "memory_operand") ++ (match_operand:BLK 1 "memory_operand")) ++ (use (match_operand:DI 2 "immediate_operand")) ++ (use (match_operand:DI 3 "immediate_operand"))])] ++ "flag_sw_unalign_byte != 1 || !TARGET_SW8A" ++{ ++ if (sw_64_expand_block_move (operands)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++(define_expand "setmemqi" ++ [(parallel [(set (match_operand:BLK 0 "memory_operand") ++ (match_operand 2 "const_int_operand")) ++ (use (match_operand:DI 1 "immediate_operand")) ++ (use (match_operand:DI 3 "immediate_operand"))])] ++ "" ++{ ++ /* If value to set is not zero, use the library routine. */ ++ if (operands[2] != const0_rtx) ++ FAIL; ++ ++ if (sw_64_expand_block_clear (operands)) ++ DONE; ++ else ++ FAIL; ++}) ++ ++;; Subroutine of stack space allocation. Perform a stack probe. ++(define_expand "stack_probe_internal" ++ [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))] ++ "" ++{ ++ operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx, ++ INTVAL (operands[0]))); ++ MEM_VOLATILE_P (operands[1]) = 1; ++ ++ operands[0] = const0_rtx; ++}) ++ ++;; This is how we allocate stack space. If we are allocating a ++;; constant amount of space and we know it is less than 4096 ++;; bytes, we need do nothing. ++;; ++;; If it is more than 4096 bytes, we need to probe the stack ++;; periodically. ++(define_expand "allocate_stack" ++ [(set (reg:DI 30) ++ (plus:DI (reg:DI 30) ++ (match_operand:DI 1 "reg_or_cint_operand"))) ++ (set (match_operand:DI 0 "register_operand" "=r") ++ (match_dup 2))] ++ "" ++{ ++ if (CONST_INT_P (operands[1]) ++ && INTVAL (operands[1]) < 32768) ++ { ++ if (INTVAL (operands[1]) >= 4096) ++ { ++ /* We do this the same way as in the prologue and generate explicit ++ probes. Then we update the stack by the constant. */ ++ ++ int probed = 4096; ++ ++ emit_insn (gen_stack_probe_internal (GEN_INT (- probed))); ++ while (probed + 8192 < INTVAL (operands[1])) ++ emit_insn (gen_stack_probe_internal ++ (GEN_INT (- (probed += 8192)))); ++ ++ if (probed + 4096 < INTVAL (operands[1])) ++ emit_insn (gen_stack_probe_internal ++ (GEN_INT (- INTVAL (operands[1])))); ++ } ++ ++ operands[1] = GEN_INT (- INTVAL (operands[1])); ++ operands[2] = virtual_stack_dynamic_rtx; ++ } ++ else ++ { ++ rtx_code_label *out_label = 0; ++ rtx_code_label *loop_label = gen_label_rtx (); ++ rtx want = gen_reg_rtx (Pmode); ++ rtx tmp = gen_reg_rtx (Pmode); ++ rtx memref, test; ++ ++ emit_insn (gen_subdi3 (want, stack_pointer_rtx, ++ force_reg (Pmode, operands[1]))); ++ ++ if (!CONST_INT_P (operands[1])) ++ { ++ rtx limit = GEN_INT (4096); ++ out_label = gen_label_rtx (); ++ test = gen_rtx_LTU (VOIDmode, operands[1], limit); ++ emit_jump_insn ++ (gen_cbranchdi4 (test, operands[1], limit, out_label)); ++ } ++ ++ emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096))); ++ emit_label (loop_label); ++ memref = gen_rtx_MEM (DImode, tmp); ++ MEM_VOLATILE_P (memref) = 1; ++ emit_move_insn (memref, const0_rtx); ++ emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (-8192))); ++ test = gen_rtx_GTU (VOIDmode, tmp, want); ++ emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label)); ++ ++ memref = gen_rtx_MEM (DImode, want); ++ MEM_VOLATILE_P (memref) = 1; ++ emit_move_insn (memref, const0_rtx); ++ ++ if (out_label) ++ emit_label (out_label); ++ ++ emit_move_insn (stack_pointer_rtx, want); ++ emit_move_insn (operands[0], virtual_stack_dynamic_rtx); ++ DONE; ++ } ++}) ++ ++;; This is used by sw_64_expand_prolog to do the same thing as above, ++;; except we cannot at that time generate new basic blocks, so we hide ++;; the loop in this one insn. ++ ++(define_insn "prologue_stack_probe_loop" ++ [(unspec_volatile [(match_operand:DI 0 "register_operand" "r") ++ (match_operand:DI 1 "register_operand" "r")] ++ UNSPECV_PSPL)] ++ "" ++{ ++ operands[2] = gen_label_rtx (); ++ (*targetm.asm_out.internal_label) (asm_out_file, "L", ++ CODE_LABEL_NUMBER (operands[2])); ++ ++ return "stl $31,-8192(%1)\;subl %0,1,%0\;ldi %1,-8192(%1)\;bne %0,%l2"; ++} ++ [(set_attr "length" "16") ++ (set_attr "type" "multi")]) ++ ++(define_expand "prologue" ++ [(const_int 0)] ++ "" ++{ ++ sw_64_expand_prologue (); ++ DONE; ++}) ++ ++;; These take care of emitting the ldgp insn in the prologue. This will be ++;; an ldi/ldih pair and we want to align them properly. So we have two ++;; unspec_volatile insns, the first of which emits the ldgp assembler macro ++;; and the second of which emits nothing. However, both are marked as type ++;; IADD (the default) so the alignment code in sw_64.c does the right thing ++;; with them. ++ ++(define_expand "prologue_ldgp" ++ [(set (match_dup 0) ++ (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1)) ++ (set (match_dup 0) ++ (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))] ++ "" ++{ ++ operands[0] = pic_offset_table_rtx; ++ operands[1] = gen_rtx_REG (Pmode, 27); ++ operands[2] = (TARGET_EXPLICIT_RELOCS ++ ? GEN_INT (sw_64_next_sequence_number++) ++ : const0_rtx); ++}) ++ ++(define_insn "*ldgp_er_1" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPECV_LDGP1))] ++ "TARGET_EXPLICIT_RELOCS" ++ "ldih %0,0(%1)\t\t!gpdisp!%2" ++ [(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*ldgp_er_2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPEC_LDGP2))] ++ "TARGET_EXPLICIT_RELOCS" ++ "ldi %0,0(%1)\t\t!gpdisp!%2" ++ [(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*exc_ldgp_er_2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPECV_LDGP2))] ++ "TARGET_EXPLICIT_RELOCS" ++ "ldi %0,0(%1)\t\t!gpdisp!%2" ++ [(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*prologue_ldgp_er_2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPECV_PLDGP2))] ++ "TARGET_EXPLICIT_RELOCS" ++{ ++ return "ldi %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"; ++} ++ [(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*prologue_ldgp_1" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPECV_LDGP1))] ++ "" ++{ ++ return "ldgp %0,0(%1)\n$%~..ng:"; ++} ++ [(set_attr "cannot_copy" "true")]) ++ ++(define_insn "*prologue_ldgp_2" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") ++ (match_operand 2 "const_int_operand")] ++ UNSPECV_PLDGP2))] ++ "" ++) ++ ++(define_insn "hardware_prefetch_use_syscall" ++[(unspec_volatile [ ++(match_operand:DI 0 "register_operand" "=r") ++(match_operand:DI 1 "register_operand" "=r") ++] UNSPECV_HARDWARE_PREFETCH_CNT)] ++"" ++{ ++ return "ldi $16,109($31)\;ldi $18,1($31)\;ldi $19,120($30)\;\ ++stl %0,120($30)\;\ ++ldl $27,syscall($29)\t\t!literal!%#\;call $26,($27),syscall\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*\;" ++ ; ++} ++[(set_attr "type" "multi") ++ (set_attr "length" "8")]) ++;; The _mcount profiling hook has special calling conventions, and ++;; does not clobber all the registers that a normal call would. So ++;; hide the fact this is a call at all. ++ ++(define_insn "prologue_mcount" ++ [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)] ++ "" ++{ ++ if (TARGET_EXPLICIT_RELOCS) ++ /* Note that we cannot use a lituse_jsr reloc, since _mcount ++ cannot be called via the PLT. */ ++ return "ldl $28,_mcount($29)\t\t!literal\;call $28,($28),_mcount"; ++ else ++ return "ldi $28,_mcount\;call $28,($28),_mcount"; ++} ++ [(set_attr "type" "multi") ++ (set_attr "length" "8")]) ++ ++(define_insn "init_fp" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (match_operand:DI 1 "register_operand" "r")) ++ (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))] ++ "" ++ "bis $31,%1,%0") ++ ++(define_expand "epilogue" ++ [(return)] ++ "" ++ "sw_64_expand_epilogue ();") ++ ++(define_expand "sibcall_epilogue" ++ [(return)] ++ "" ++{ ++ sw_64_expand_epilogue (); ++ DONE; ++}) ++ ++(define_expand "builtin_longjmp" ++ [(use (match_operand:DI 0 "register_operand" "r"))] ++ "" ++{ ++ /* The elements of the buffer are, in order: */ ++ rtx fp = gen_rtx_MEM (Pmode, operands[0]); ++ rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 8)); ++ rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 16)); ++ rtx pv = gen_rtx_REG (Pmode, 27); ++ ++ /* This bit is the same as expand_builtin_longjmp. */ ++ emit_move_insn (pv, lab); ++ emit_stack_restore (SAVE_NONLOCAL, stack); ++ emit_use (hard_frame_pointer_rtx); ++ emit_use (stack_pointer_rtx); ++ ++ emit_move_insn (hard_frame_pointer_rtx, fp); ++ /* Load the label we are jumping through into $27 so that we know ++ where to look for it when we get back to setjmp's function for ++ restoring the gp. */ ++ emit_jump_insn (gen_builtin_longjmp_internal (pv)); ++ emit_barrier (); ++ DONE; ++}) ++ ++;; This is effectively a copy of indirect_jump, but constrained such ++;; that register renaming cannot foil our cunning plan with $27. ++(define_insn "builtin_longjmp_internal" ++ [(set (pc) ++ (unspec_volatile [(match_operand:DI 0 "register_operand" "c")] ++ UNSPECV_LONGJMP))] ++ "" ++ "jmp $31,(%0),0" ++ [(set_attr "type" "ibr")]) ++ ++(define_expand "builtin_setjmp_receiver" ++ [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)] ++ "") ++ ++(define_insn_and_split "*builtin_setjmp_receiver_1" ++ [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)] ++ "" ++{ ++ if (TARGET_EXPLICIT_RELOCS) ++ return "#"; ++ else ++ return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"; ++} ++ "&& TARGET_EXPLICIT_RELOCS && reload_completed" ++ [(set (match_dup 1) ++ (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1)) ++ (set (match_dup 1) ++ (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))] ++{ ++ if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0)) ++ emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]), ++ UNSPECV_SETJMPR_ER)); ++ operands[1] = pic_offset_table_rtx; ++ operands[2] = gen_rtx_REG (Pmode, 27); ++ operands[3] = GEN_INT (sw_64_next_sequence_number++); ++} ++ [(set_attr "length" "12") ++ (set_attr "type" "multi")]) ++ ++(define_insn "*builtin_setjmp_receiver_er_sl_1" ++ [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)] ++ "TARGET_EXPLICIT_RELOCS" ++ "ldi $27,$LSJ%=-%l0($27)\n$LSJ%=:") ++ ++;; When flag_reorder_blocks_and_partition is in effect, compiler puts ++;; exception landing pads in a cold section. To prevent inter-section offset ++;; calculation, a jump to original landing pad is emitted in the place of the ++;; original landing pad. Since landing pad is moved, RA-relative GP ++;; calculation in the prologue of landing pad breaks. To solve this problem, ++;; we use alternative GP load approach. ++ ++(define_expand "exception_receiver" ++ [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)] ++ "" ++{ ++ if (flag_reorder_blocks_and_partition) ++ operands[0] = copy_rtx (sw_64_gp_save_rtx ()); ++ else ++ operands[0] = const0_rtx; ++}) ++ ++(define_insn "*exception_receiver_2" ++ [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)] ++ "flag_reorder_blocks_and_partition" ++ "ldl $29,%0" ++ [(set_attr "type" "ild")]) ++ ++(define_insn_and_split "*exception_receiver_1" ++ [(unspec_volatile [(const_int 0)] UNSPECV_EHR)] ++ "" ++{ ++ if (TARGET_EXPLICIT_RELOCS) ++ return "#"; ++ else ++ return "ldgp $29,0($26)"; ++} ++ "&& TARGET_EXPLICIT_RELOCS && reload_completed" ++ [(set (match_dup 0) ++ (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1)) ++ (set (match_dup 0) ++ (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))] ++{ ++ operands[0] = pic_offset_table_rtx; ++ operands[1] = gen_rtx_REG (Pmode, 26); ++ operands[2] = GEN_INT (sw_64_next_sequence_number++); ++} ++ [(set_attr "length" "8") ++ (set_attr "type" "multi")]) ++ ++;; Prefetch data. ++;; On SW6, these become official prefetch instructions. ++ ++(define_insn "prefetch" ++ [(prefetch (match_operand:DI 0 "address_operand" "p") ++ (match_operand:DI 1 "const_int_operand" "n") ++ (match_operand:DI 2 "const_int_operand" "n"))] ++ "sw_64_cpu == PROCESSOR_SW6 || sw_64_cpu == PROCESSOR_SW8" ++{ ++ /* Interpret "no temporal locality" as this data should be evicted once ++ it is used. The "evict next" alternatives load the data into the cache ++ and leave the LRU eviction counter pointing to that block. */ ++ static const char * alt[2][2] ; ++ if (flag_sw_prefetch_l1) ++ { ++ alt[0][0] = "fillcs_e %a0" ; /* read, evict next */ ++ alt[0][1] = "fillcs %a0" ; /* read, evict next */ ++ alt[1][0] = "fillde_e %a0" ; /* write, evict next */ ++ alt[1][1] = "fillde %a0" ; /* write, evict next */ ++ ++ } ++ else ++ { ++ alt[0][0] = "s_fillde %a0" ; /* read, evict next */ ++ alt[0][1] = "s_fillcs %a0" ; /* read, evict next */ ++ alt[1][0] = "fillde_e %a0" ; /* write, evict next */ ++ alt[1][1] = "fillde %a0" ; /* write, evict next */ ++ } ++ ++ bool write = INTVAL (operands[1]) != 0; ++ bool lru = INTVAL (operands[2]) != 0; ++ ++ return alt[write][lru]; ++} ++ [(set_attr "type" "ild")]) ++ ++(define_expand "prefetch_sc" ++ [(prefetch (match_operand:DI 0 "address_operand") ++ (match_operand:DI 1 "const_int_operand") ++ (unspec: DI [(match_operand:DI 2 "const_int_operand")] UNSPEC_PFSC))] ++ "sw_64_cpu == PROCESSOR_SW6 || sw_64_cpu == PROCESSOR_SW8") ++ ++(define_insn "prefetch_sc_internal" ++ [(prefetch (match_operand:DI 0 "address_operand" "p") ++ (match_operand:DI 1 "const_int_operand" "n") ++ (unspec: DI [(match_operand:DI 2 "const_int_operand" "n")] UNSPEC_PFSC))] ++ "sw_64_cpu == PROCESSOR_SW6 || sw_64_cpu == PROCESSOR_SW8" ++{ ++ static const char * alt[2]; ++ ++ alt[0] = "s_fillcs %a0"; /* L2 read */ ++ alt[1] = "s_fillde %a0"; /* L2 write */ ++ ++ bool write = INTVAL (operands[1]) != 0; ++ ++ return alt[write]; ++} ++ [(set_attr "type" "ild")]) ++ ++(define_expand "prefetch_tc" ++ [(prefetch (match_operand:DI 0 "address_operand") ++ (match_operand:DI 1 "const_int_operand") ++ (unspec: DI [(match_operand:DI 2 "const_int_operand")] UNSPEC_PFTC))] ++ "sw_64_cpu == PROCESSOR_SW6 || sw_64_cpu == PROCESSOR_SW8") ++ ++(define_insn "prefetch_tc_internal" ++ [(prefetch (match_operand:DI 0 "address_operand" "p") ++ (match_operand:DI 1 "const_int_operand" "n") ++ (unspec: DI [(match_operand:DI 2 "const_int_operand" "n")] UNSPEC_PFTC))] ++ "sw_64_cpu == PROCESSOR_SW6 || sw_64_cpu == PROCESSOR_SW8" ++{ ++ static const char * alt[2]; ++ ++ alt[0] = "e_fillcs %a0"; /* L3 read */ ++ alt[1] = "e_fillde %a0"; /* L3 write */ ++ ++ bool write = INTVAL (operands[1]) != 0; ++ ++ return alt[write]; ++} ++ [(set_attr "type" "ild")]) ++ ++(define_insn "trapb" ++ [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)] ++ "" ++ "memb" ++ [(set_attr "type" "misc")]) ++ ++(define_insn "nop" ++ [(const_int 0)] ++ "" ++ "nop" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "fnop" ++ [(const_int 1)] ++ "TARGET_FP" ++ "fcpys $f31,$f31,$f31" ++ [(set_attr "type" "fcpys")]) ++ ++(define_insn "unop" ++ [(const_int 2)] ++ "" ++{ ++ return "ldl_u $31,0($30)"; ++} ++) ++ ++(define_insn "realign" ++ [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] ++ UNSPECV_REALIGN)] ++ "" ++ ".align %0 #realign") ++ ++(define_insn "builtin_cmpbge" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ") ++ (match_operand:DI 2 "reg_or_8bit_operand" "rI")] ++ UNSPEC_CMPBGE))] ++ "" ++ "cmpgeb %r1,%2,%0" ++ [(set_attr "type" "icmp")]) ++ ++(define_expand "extbl" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2])); ++ DONE; ++}) ++ ++(define_expand "extwl" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2])); ++ DONE; ++}) ++ ++(define_expand "extll" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2])); ++ DONE; ++}) ++ ++(define_expand "extql" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2])); ++ DONE; ++}) ++ ++(define_expand "builtin_insbl" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ operands[1] = gen_lowpart (QImode, operands[1]); ++ emit_insn (gen_insbl (operands[0], operands[1], operands[2])); ++ DONE; ++}) ++ ++(define_expand "builtin_inswl" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ operands[1] = gen_lowpart (HImode, operands[1]); ++ emit_insn (gen_inswl (operands[0], operands[1], operands[2])); ++ DONE; ++}) ++ ++(define_expand "builtin_insll" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ operands[1] = gen_lowpart (SImode, operands[1]); ++ emit_insn (gen_insll (operands[0], operands[1], operands[2])); ++ DONE; ++}) ++ ++(define_expand "inswh" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2])); ++ DONE; ++}) ++ ++(define_expand "inslh" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2])); ++ DONE; ++}) ++ ++(define_expand "insqh" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2])); ++ DONE; ++}) ++ ++(define_expand "mskbl" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ rtx mask = GEN_INT (0xff); ++ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2])); ++ DONE; ++}) ++ ++(define_expand "mskwl" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ rtx mask = GEN_INT (0xffff); ++ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2])); ++ DONE; ++}) ++ ++(define_expand "mskll" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ rtx mask = gen_int_mode (0xffffffff, DImode); ++ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2])); ++ DONE; ++}) ++ ++(define_expand "mskql" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ rtx mask = constm1_rtx; ++ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2])); ++ DONE; ++}) ++ ++(define_expand "mskwh" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2])); ++ DONE; ++}) ++ ++(define_expand "msklh" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2])); ++ DONE; ++}) ++ ++(define_expand "mskqh" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "register_operand") ++ (match_operand:DI 2 "reg_or_8bit_operand")] ++ "" ++{ ++ emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2])); ++ DONE; ++}) ++ ++(define_expand "builtin_zap" ++ [(set (match_operand:DI 0 "register_operand") ++ (and:DI (unspec:DI ++ [(match_operand:DI 2 "reg_or_cint_operand")] ++ UNSPEC_ZAP) ++ (match_operand:DI 1 "reg_or_cint_operand")))] ++ "" ++{ ++ if (CONST_INT_P (operands[2])) ++ { ++ rtx mask = sw_64_expand_zap_mask (INTVAL (operands[2])); ++ ++ if (mask == const0_rtx) ++ { ++ emit_move_insn (operands[0], const0_rtx); ++ DONE; ++ } ++ if (mask == constm1_rtx) ++ { ++ emit_move_insn (operands[0], operands[1]); ++ DONE; ++ } ++ ++ operands[1] = force_reg (DImode, operands[1]); ++ emit_insn (gen_anddi3 (operands[0], operands[1], mask)); ++ DONE; ++ } ++ ++ operands[1] = force_reg (DImode, operands[1]); ++ operands[2] = gen_lowpart (QImode, operands[2]); ++}) ++ ++(define_insn "*builtin_zap_1" ++ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") ++ (and:DI (unspec:DI ++ [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")] ++ UNSPEC_ZAP) ++ (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))] ++ "" ++ "@ ++ # ++ # ++ bis $31,$31,%0 ++ zap %r1,%2,%0" ++ [(set_attr "type" "shift,shift,ilog,shift")]) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (and:DI (unspec:DI ++ [(match_operand:QI 2 "const_int_operand")] ++ UNSPEC_ZAP) ++ (match_operand:DI 1 "const_int_operand")))] ++ "" ++ [(const_int 0)] ++{ ++ rtx mask = sw_64_expand_zap_mask (INTVAL (operands[2])); ++ ++ operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode); ++ emit_move_insn (operands[0], operands[1]); ++ DONE; ++}) ++ ++(define_split ++ [(set (match_operand:DI 0 "register_operand") ++ (and:DI (unspec:DI ++ [(match_operand:QI 2 "const_int_operand")] ++ UNSPEC_ZAP) ++ (match_operand:DI 1 "register_operand")))] ++ "" ++ [(set (match_dup 0) ++ (and:DI (match_dup 1) (match_dup 2)))] ++{ ++ operands[2] = sw_64_expand_zap_mask (INTVAL (operands[2])); ++ if (operands[2] == const0_rtx) ++ { ++ emit_move_insn (operands[0], const0_rtx); ++ DONE; ++ } ++ if (operands[2] == constm1_rtx) ++ { ++ emit_move_insn (operands[0], operands[1]); ++ DONE; ++ } ++}) ++ ++(define_expand "builtin_zapnot" ++ [(set (match_operand:DI 0 "register_operand") ++ (and:DI (unspec:DI ++ [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))] ++ UNSPEC_ZAP) ++ (match_operand:DI 1 "reg_or_cint_operand")))] ++ "" ++{ ++ if (CONST_INT_P (operands[2])) ++ { ++ rtx mask = sw_64_expand_zap_mask (~ INTVAL (operands[2])); ++ ++ if (mask == const0_rtx) ++ { ++ emit_move_insn (operands[0], const0_rtx); ++ DONE; ++ } ++ if (mask == constm1_rtx) ++ { ++ emit_move_insn (operands[0], operands[1]); ++ DONE; ++ } ++ ++ operands[1] = force_reg (DImode, operands[1]); ++ emit_insn (gen_anddi3 (operands[0], operands[1], mask)); ++ DONE; ++ } ++ ++ operands[1] = force_reg (DImode, operands[1]); ++ operands[2] = gen_lowpart (QImode, operands[2]); ++}) ++ ++(define_insn "*builtin_zapnot_1" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (and:DI (unspec:DI ++ [(not:QI (match_operand:QI 2 "register_operand" "r"))] ++ UNSPEC_ZAP) ++ (match_operand:DI 1 "reg_or_0_operand" "rJ")))] ++ "" ++ "zapnot %r1,%2,%0" ++ [(set_attr "type" "shift")]) ++ ++(define_insn "builtin_amask" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")] ++ UNSPEC_AMASK))] ++ "" ++ "amask %1,%0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "builtin_implver" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))] ++ "" ++ "implver %0" ++ [(set_attr "type" "ilog")]) ++ ++(define_insn "builtin_rpcc" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))] ++ "" ++ "rtc %0" ++ [(set_attr "type" "ilog")]) ++ ++(define_expand "builtin_minub8" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_minsb8" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_minuw4" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_minsw4" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_maxub8" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_maxsb8" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_maxuw4" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_expand "builtin_maxsw4" ++ [(match_operand:DI 0 "register_operand") ++ (match_operand:DI 1 "reg_or_0_operand") ++ (match_operand:DI 2 "reg_or_0_operand")] ++ "TARGET_MAX" ++{ ++ sw_64_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0], ++ operands[1], operands[2]); ++ DONE; ++}) ++ ++(define_insn "builtin_perr" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ") ++ (match_operand:DI 2 "reg_or_8bit_operand" "rJ")] ++ UNSPEC_PERR))] ++ "TARGET_MAX" ++ "perr %r1,%r2,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_expand "builtin_pklb" ++ [(set (match_operand:DI 0 "register_operand") ++ (vec_concat:V8QI ++ (vec_concat:V4QI ++ (truncate:V2QI (match_operand:DI 1 "register_operand")) ++ (match_dup 2)) ++ (match_dup 3)))] ++ "TARGET_MAX" ++{ ++ operands[0] = gen_lowpart (V8QImode, operands[0]); ++ operands[1] = gen_lowpart (V2SImode, operands[1]); ++ operands[2] = CONST0_RTX (V2QImode); ++ operands[3] = CONST0_RTX (V4QImode); ++}) ++ ++(define_insn "*pklb" ++ [(set (match_operand:V8QI 0 "register_operand" "=r") ++ (vec_concat:V8QI ++ (vec_concat:V4QI ++ (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r")) ++ (match_operand:V2QI 2 "const0_operand")) ++ (match_operand:V4QI 3 "const0_operand")))] ++ "TARGET_MAX" ++ "pklb %r1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_expand "builtin_pkwb" ++ [(set (match_operand:DI 0 "register_operand") ++ (vec_concat:V8QI ++ (truncate:V4QI (match_operand:DI 1 "register_operand")) ++ (match_dup 2)))] ++ "TARGET_MAX" ++{ ++ operands[0] = gen_lowpart (V8QImode, operands[0]); ++ operands[1] = gen_lowpart (V4HImode, operands[1]); ++ operands[2] = CONST0_RTX (V4QImode); ++}) ++ ++(define_insn "*pkwb" ++ [(set (match_operand:V8QI 0 "register_operand" "=r") ++ (vec_concat:V8QI ++ (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r")) ++ (match_operand:V4QI 2 "const0_operand")))] ++ "TARGET_MAX" ++ "pkwb %r1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_expand "builtin_unpkbl" ++ [(set (match_operand:DI 0 "register_operand") ++ (zero_extend:V2SI ++ (vec_select:V2QI (match_operand:DI 1 "register_operand") ++ (parallel [(const_int 0) (const_int 1)]))))] ++ "TARGET_MAX" ++{ ++ operands[0] = gen_lowpart (V2SImode, operands[0]); ++ operands[1] = gen_lowpart (V8QImode, operands[1]); ++}) ++ ++(define_insn "*unpkbl" ++ [(set (match_operand:V2SI 0 "register_operand" "=r") ++ (zero_extend:V2SI ++ (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") ++ (parallel [(const_int 0) (const_int 1)]))))] ++ "TARGET_MAX" ++ "unpkbl %r1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(define_expand "builtin_unpkbw" ++ [(set (match_operand:DI 0 "register_operand") ++ (zero_extend:V4HI ++ (vec_select:V4QI (match_operand:DI 1 "register_operand") ++ (parallel [(const_int 0) ++ (const_int 1) ++ (const_int 2) ++ (const_int 3)]))))] ++ "TARGET_MAX" ++{ ++ operands[0] = gen_lowpart (V4HImode, operands[0]); ++ operands[1] = gen_lowpart (V8QImode, operands[1]); ++}) ++ ++(define_insn "*unpkbw" ++ [(set (match_operand:V4HI 0 "register_operand" "=r") ++ (zero_extend:V4HI ++ (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") ++ (parallel [(const_int 0) ++ (const_int 1) ++ (const_int 2) ++ (const_int 3)]))))] ++ "TARGET_MAX" ++ "unpkbw %r1,%0" ++ [(set_attr "type" "mvi")]) ++ ++(include "sync.md") ++ ++;; The call patterns are at the end of the file because their ++;; wildcard operand0 interferes with nice recognition. ++ ++(define_insn "*call_value_osf_1_er_noreturn" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS ++ && find_reg_note (insn, REG_NORETURN, NULL_RTX)" ++ "@ ++ call $26,($27),0 ++ bsr $26,%1\t\t!samegp ++ ldl $27,%1($29)\t\t!literal!%#\;call $26,($27),%1\t\t!lituse_jsr!%#" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,*,8")]) ++ ++(define_insn "*call_value_osf_1_er_setfpec0" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 3 " ++ "@ ++ call $26,(%1),0\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%* ++ bsr $26,%1\t\t!samegp ++ ldl $27,%1($29)\t\t!literal!%#\;call $26,($27),0\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_value_osf_1_er_setfpec1" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 1" ++ "@ ++ call $26,(%1),0\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%* ++ bsr $26,%1\t\t!samegp ++ ldl $27,%1($29)\t\t!literal!%#\;call $26,($27),0\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_value_osf_1_er" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS" ++ "@ ++ call $26,(%1),0\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%* ++ bsr $26,%1\t\t!samegp ++ ldl $27,%1($29)\t\t!literal!%#\;call $26,($27),0\t\t!lituse_jsr!%#\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++;; We must use peep2 instead of a split because we need accurate life ++;; information for $gp. Consider the case of { bar(); while (1); }. ++(define_peephole2 ++ [(parallel [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))])] ++ "TARGET_EXPLICIT_RELOCS && reload_completed ++ && ! samegp_function_operand (operands[1], Pmode) ++ && (peep2_regno_dead_p (1, 29) ++ || find_reg_note (insn, REG_NORETURN, NULL_RTX))" ++ [(parallel [(set (match_dup 0) ++ (call (mem:DI (match_dup 3)) ++ (match_dup 2))) ++ (use (reg:DI 29)) ++ (use (match_dup 1)) ++ (use (match_dup 4)) ++ (clobber (reg:DI 26))])] ++{ ++ if (CONSTANT_P (operands[1])) ++ { ++ operands[3] = gen_rtx_REG (Pmode, 27); ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, ++ operands[1], operands[4])); ++ } ++ else ++ { ++ operands[3] = operands[1]; ++ operands[1] = const0_rtx; ++ operands[4] = const0_rtx; ++ } ++}) ++(define_peephole2 ++ [(parallel [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))])] ++ "TARGET_EXPLICIT_RELOCS && reload_completed ++ && ! samegp_function_operand (operands[1], Pmode) ++ && ! (peep2_regno_dead_p (1, 29) ++ || find_reg_note (insn, REG_NORETURN, NULL_RTX)) ++ && !enable_asan_check_stack ()" ++ [(parallel [(set (match_dup 0) ++ (call (mem:DI (match_dup 3)) ++ (match_dup 2))) ++ (set (match_dup 6) ++ (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1)) ++ (use (match_dup 1)) ++ (use (match_dup 5)) ++ (clobber (reg:DI 26))]) ++ (set (match_dup 6) ++ (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))] ++{ ++ if (CONSTANT_P (operands[1])) ++ { ++ operands[3] = gen_rtx_REG (Pmode, 27); ++ operands[5] = GEN_INT (sw_64_next_sequence_number++); ++ emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, ++ operands[1], operands[5])); ++ } ++ else ++ { ++ operands[3] = operands[1]; ++ operands[1] = const0_rtx; ++ operands[5] = const0_rtx; ++ } ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ operands[6] = pic_offset_table_rtx; ++}) ++ ++(define_insn "*call_value_osf_2_er_nogp" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "register_operand" "c")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (use (match_operand 3)) ++ (use (match_operand 4)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS" ++ "call $26,(%1),%3%J4" ++ [(set_attr "type" "call")]) ++ ++(define_insn "*call_value_osf_2_er" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "register_operand" "c")) ++ (match_operand 2))) ++ (set (reg:DI 29) ++ (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")] ++ UNSPEC_LDGP1)) ++ (use (match_operand 3)) ++ (use (match_operand 4)) ++ (clobber (reg:DI 26))] ++ "TARGET_EXPLICIT_RELOCS" ++ { ++ return "call $26,(%1),%3%J4\;ldih $29,0($26)\t\t!gpdisp!%5"; ++ } ++ [(set_attr "type" "call") ++ (set_attr "cannot_copy" "true") ++ (set_attr "length" "8")]) ++ ++(define_insn "*call_value_osf_1_noreturn" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "! TARGET_EXPLICIT_RELOCS ++ && find_reg_note (insn, REG_NORETURN, NULL_RTX)" ++ "@ ++ call $26,($27),0 ++ bsr $26,$%1..ng ++ call $26,%1" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,*,8")]) ++ ++(define_int_iterator TLS_CALL ++ [UNSPEC_TLSGD_CALL ++ UNSPEC_TLSLDM_CALL]) ++ ++(define_int_attr tls ++ [(UNSPEC_TLSGD_CALL "tlsgd") ++ (UNSPEC_TLSLDM_CALL "tlsldm")]) ++ ++(define_insn "call_value_osf_" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "symbolic_operand")) ++ (const_int 0))) ++ (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "HAVE_AS_TLS" ++ "ldl $27,%1($29)\t\t!literal!%2\;call $26,($27),%1\t\t!lituse_!%2\;ldih $29,0($26)\t\t!gpdisp!%*\;ldi $29,0($29)\t\t!gpdisp!%*" ++ [(set_attr "type" "call") ++ (set_attr "cannot_copy" "true") ++ (set_attr "length" "16")]) ++ ++;; We must use peep2 instead of a split because we need accurate life ++;; information for $gp. ++(define_peephole2 ++ [(parallel ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "symbolic_operand")) ++ (const_int 0))) ++ (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))])] ++ "HAVE_AS_TLS && reload_completed ++ && peep2_regno_dead_p (1, 29)" ++ [(set (match_dup 3) ++ (unspec:DI [(match_dup 5) ++ (match_dup 1) ++ (match_dup 2)] UNSPEC_LITERAL)) ++ (parallel [(set (match_dup 0) ++ (call (mem:DI (match_dup 3)) ++ (const_int 0))) ++ (use (match_dup 5)) ++ (use (match_dup 1)) ++ (use (unspec [(match_dup 2)] TLS_CALL)) ++ (clobber (reg:DI 26))]) ++ (set (match_dup 5) ++ (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] ++{ ++ operands[3] = gen_rtx_REG (Pmode, 27); ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ operands[5] = pic_offset_table_rtx; ++}) ++ ++(define_peephole2 ++ [(parallel ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "symbolic_operand")) ++ (const_int 0))) ++ (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))])] ++ "HAVE_AS_TLS && reload_completed ++ && !peep2_regno_dead_p (1, 29) ++ && !find_reg_note (insn, REG_EH_REGION, NULL_RTX)" ++ [(set (match_dup 3) ++ (unspec:DI [(match_dup 5) ++ (match_dup 1) ++ (match_dup 2)] UNSPEC_LITERAL)) ++ (parallel [(set (match_dup 0) ++ (call (mem:DI (match_dup 3)) ++ (const_int 0))) ++ (set (match_dup 5) ++ (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) ++ (use (match_dup 1)) ++ (use (unspec [(match_dup 2)] TLS_CALL)) ++ (clobber (reg:DI 26))]) ++ (set (match_dup 5) ++ (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] ++{ ++ operands[3] = gen_rtx_REG (Pmode, 27); ++ operands[4] = GEN_INT (sw_64_next_sequence_number++); ++ operands[5] = pic_offset_table_rtx; ++}) ++ ++ ++(define_insn "*call_value_osf_1_setfpec0" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "! TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 3" ++ "@ ++ call $26,($27),0\;ldgp $29,0($26) ++ bsr $26,$%1..ng ++ call $26,%1\;ldgp $29,0($26)" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_value_osf_1_setfpec1" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "! TARGET_EXPLICIT_RELOCS && flag_fpcr_set == 1" ++ "@ ++ call $26,($27),0\;ldgp $29,0($26) ++ bsr $26,$%1..ng ++ call $26,%1\;ldgp $29,0($26)" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*call_value_osf_1" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) ++ (match_operand 2))) ++ (use (reg:DI 29)) ++ (clobber (reg:DI 26))] ++ "! TARGET_EXPLICIT_RELOCS" ++ "@ ++ call $26,($27),0\;ldgp $29,0($26) ++ bsr $26,$%1..ng ++ call $26,%1\;ldgp $29,0($26)" ++ [(set_attr "type" "call") ++ (set_attr "length" "12,*,16")]) ++ ++(define_insn "*sibcall_value_osf_1_er" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s")) ++ (match_operand 2))) ++ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] ++ "TARGET_EXPLICIT_RELOCS" ++ "@ ++ br $31,%1\t\t!samegp ++ ldl $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,8")]) ++ ++(define_insn "*sibcall_value_osf_1" ++ [(set (match_operand 0) ++ (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s")) ++ (match_operand 2))) ++ (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] ++ "! TARGET_EXPLICIT_RELOCS" ++ "@ ++ br $31,$%1..ng ++ ldi $27,%1\;jmp $31,($27),%1" ++ [(set_attr "type" "call") ++ (set_attr "length" "*,8")]) ++ ++(define_insn "speculation_barrier" ++ [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)] ++"" ++"imemb" ++[(set_attr "type" "misc")]) ++ ++(define_insn "bswaphi2" ++ [(set (match_operand:HI 0 "register_operand" "=r") ++ (bswap:HI (match_operand:HI 1 "register_operand" "r")))] ++ "TARGET_SW8A && flag_sw_rev == 1" ++ "revbh %1,%0" ++ [(set_attr "isa" "sw8a")]) ++ ++(define_insn "stack_tie" ++ [(set (mem:BLK (scratch)) ++ (unspec:BLK [(match_operand:DI 0 "register_operand" "r") ++ (match_operand:DI 1 "register_operand" "r")] ++ UNSPEC_TIE))] ++ "" ++ "" ++ [(set_attr "length" "0")] ++) +diff --git a/gcc/config/sw_64/sw_64.opt b/gcc/config/sw_64/sw_64.opt +new file mode 100644 +index 000000000..c818dff40 +--- /dev/null ++++ b/gcc/config/sw_64/sw_64.opt +@@ -0,0 +1,326 @@ ++; Options for the Sw64 port of the compiler ++; ++; Copyright (C) 2005-2022 Free Software Foundation, Inc. ++; ++; This file is part of GCC. ++; ++; GCC is free software; you can redistribute it and/or modify it under ++; the terms of the GNU General Public License as published by the Free ++; Software Foundation; either version 3, or (at your option) any later ++; version. ++; ++; GCC is distributed in the hope that it will be useful, but WITHOUT ++; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ++; License for more details. ++; ++; You should have received a copy of the GNU General Public License ++; along with GCC; see the file COPYING3. If not see ++; . ++msw-use-32align ++C C++ Fortran LTO Driver Target Mask(SW_32ALIGN) Save ++Use or not use 32align. ++ ++fsw-sf-cmpsel ++Target Var(flag_sw_sf_cmpsel) Init(0) ++use or not use SF cmp/br/selcet instructions. ++ ++fsw-hardware-prefetch ++Target Var(flag_sw_hardware_prefetch) Init(0) ++set hardware_prefetch registers:PFH_CTL,PFH_CNT. ++ ++fsw-hardware-prefetch-exit ++Target Var(flag_sw_hardware_prefetch_exit) Init(0) ++set hardware_prefetch default value in the function exit. ++ ++fsw-hardware-prefetch-clt= ++Common Joined RejectNegative UInteger Var(flag_hardware_prefetch_clt) Init(5) Optimization ++ ++fsw-hardware-prefetch-cnt-l1= ++Common Joined RejectNegative UInteger Var(flag_hardware_prefetch_cnt_l1) Init(0) Optimization ++ ++fsw-hardware-prefetch-cnt-l2= ++Common Joined RejectNegative UInteger Var(flag_hardware_prefetch_cnt_l2) Init(0) Optimization ++ ++fsw-hardware-prefetch-cnt-l3= ++Common Joined RejectNegative UInteger Var(flag_hardware_prefetch_cnt_l3) Init(5) Optimization ++ ++ ++fsw-branch-fusion ++Target Var(flag_sw_branch_fusion) Init(1) ++fuse the cbranch instructions. ++ ++fsw-branch-combination ++Target Var(flag_sw_branch_combination) Init(0) ++combine the cbranch instructions. ++ ++fsw-fselect ++Target Var(flag_sw_fselect) Init(0) ++Use or not use less instructions for sel/fsel. ++ ++fsw-prefetch-unroll ++Target Var(flag_sw_prefetch_unroll) Init(0) ++Optimize loop unroll in the prefetch pass. ++ ++fsw-delmemb ++Target Var(flag_sw_delmemb) Init(1) ++Use or not use memb. ++ ++fsw-non-temporal ++Target Var(flag_sw_non_temporal) Init(0) ++Use or not use stw_nc/stl_nc/std_nc. ++ ++fsw-prefetch-tc ++Target Var(flag_sw_prefetch_tc) Init(0) ++Generate L3 level prefetch instruction with multi-level method. ++ ++fsw-prefetch-sc ++Target Var(flag_sw_prefetch_sc) Init(0) ++Generate L2 level prefetch instruction with multi-level method. ++ ++fsw-rsqrt ++Target Var(flag_sw_rsqrt) Init(0) ++Fast calculation of 1/sqrt(x). ++ ++fsw-int-divmod ++Target Var(flag_sw_int_divmod) Init(1) ++Use or not use int div/mod instructions. ++;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++fsw-unalign-byte ++Target Var(flag_sw_unalign_byte) Init(0) ++Not use or use ldl_u/stl_u instructions. ++ ++fsw-auto-inc-dec ++Target Var(flag_sw_auto_inc_dec) Init(0) ++Use or not use int auto-inc-dec load/store instructions. ++ ++fsw-nofcpys ++Target Var(flag_sw_nofcpys) Init(1) ++delete fcpys after fcvtsd instruction. ++ ++fsw-sdsame ++Target Var(flag_sw_sdsame) Init(0) ++For des and src same. ++ ++fsw-fast-math ++Target Var(flag_sw_fast_math) Init(0) ++For 628 fast-math. ++ ++fsw-fma ++Target Var(flag_sw_fma) Init(1) ++Add fma option. ++ ++fsw-prefetch-dc ++Target Var(flag_sw_prefetch_dc) Init(1) ++Generate L1 level prefetch instruction with multi-level method. ++ ++fsw-rtx-cost ++Target Var(flag_sw_rtx_cost) Init(1) ++Adjust the rtx-cost. ++ ++fsw-delnop ++Target Var(flag_sw_delnop) Init(1) ++Delete the nop instruction. ++ ++fsw-sxaddl ++Target Var(flag_sw_sxaddl) Init(1) ++ ++fsw-use-cas ++Target Var(flag_sw_use_cas) Init(0) ++Use or no use compare and swap instruction. ++ ++fsw-fprnd ++Target Var(flag_sw_fprnd) Init(0) ++Use fp rounding instructions. ++ ++fsw-recip ++Target Var(flag_sw_recip) Init(0) ++Use ISA fp reciprocal instructions. ++ ++fsw-recip-precision ++Target Var(flag_sw_recip_precision) Init(0) ++Use ISA fp reciprocal instructions to provide more accuracy. ++ ++fsw-rtid ++Target Var(flag_sw_rtid) Init(1) ++Use rtid instead of syscall 0x9e. ++ ++fsw-int-div-opt ++Target Var(flag_sw_int_div_opt) Init(0) ++SW div opt. ++ ++fsw-prefetch-l1 ++Target Var(flag_sw_prefetch_l1) Init(1) ++Use l1 load prefetch instead of L2. ++ ++fsw-prefetch-add ++Target Var(flag_sw_prefetch_add) Init(1) ++generate prefetch for cases like stream add. ++ ++msoft-float ++Target Mask(SOFT_FP) ++Do not use hardware fp. ++ ++mfp-regs ++Target Mask(FPREGS) ++Use fp registers. ++ ++mgas ++Target Ignore ++Does nothing. Preserved for backward compatibility. ++ ++mieee-conformant ++Target RejectNegative Mask(IEEE_CONFORMANT) ++Request IEEE-conformant math library routines (SYSV). ++ ++mieee ++Target RejectNegative Mask(IEEE) ++Emit IEEE-conformant code, without inexact exceptions. ++ ++mieee-main ++Target RejectNegative Mask(IEEE_MAIN) ++Emit IEEE-conformant code, without inexact exceptions. ++ ++mieee-with-inexact ++Target RejectNegative Mask(IEEE_WITH_INEXACT) ++ ++mbuild-constants ++Target Mask(BUILD_CONSTANTS) ++Do not emit complex integer constants to read-only memory. ++ ++mfloat-vax ++Target RejectNegative Mask(FLOAT_VAX) ++Use VAX fp. ++ ++mfloat-ieee ++Target RejectNegative InverseMask(FLOAT_VAX) ++Do not use VAX fp. ++ ++mbwx ++Target Mask(BWX) ++Emit code for the byte/word ISA extension. ++ ++mmax ++Target Mask(MAX) ++Emit code for the motion video ISA extension. ++ ++mfix ++Target Mask(FIX) ++Emit code for the fp move and sqrt ISA extension. ++ ++mcix ++Target Mask(CIX) ++Emit code for the counting ISA extension. ++ ++msw6a ++Target Mask(SW6A) ++Emit code for the SW6A ISA extension. ++ ++msw6b ++Target Mask(SW6B) ++Emit code for the SW6B ISA extension. ++ ++msw4d ++Target Mask(SW4D) ++Emit code for the SW4D ISA extension. ++ ++msw8a ++Target Mask(SW8A) ++Emit code for the SW8A ISA extension. ++ ++mexplicit-relocs ++Target Mask(EXPLICIT_RELOCS) ++Emit code using explicit relocation directives. ++ ++msmall-data ++Target RejectNegative Mask(SMALL_DATA) ++Emit 16-bit relocations to the small data areas. ++ ++mlarge-data ++Target RejectNegative InverseMask(SMALL_DATA) ++Emit 32-bit relocations to the small data areas. ++ ++msmall-text ++Target RejectNegative Mask(SMALL_TEXT) ++Emit direct branches to local functions. ++ ++mlarge-text ++Target RejectNegative InverseMask(SMALL_TEXT) ++Emit indirect branches to local functions. ++ ++mtls-kernel ++Target Mask(TLS_KERNEL) ++Emit rdval for thread pointer. ++ ++mlong-double-128 ++Target RejectNegative Mask(LONG_DOUBLE_128) ++Use 128-bit long double. ++ ++mlong-double-64 ++Target RejectNegative InverseMask(LONG_DOUBLE_128) ++Use 64-bit long double. ++ ++mcpu= ++Target RejectNegative Joined Var(sw_64_cpu_string) ++Use features of and schedule given CPU. ++ ++mtune= ++Target RejectNegative Joined Var(sw_64_tune_string) ++Schedule given CPU. ++ ++mfp-rounding-mode= ++Target RejectNegative Joined Var(sw_64_fprm_string) ++Control the generated fp rounding mode. ++ ++mfp-trap-mode= ++Target RejectNegative Joined Var(sw_64_fptm_string) ++Control the IEEE trap mode. ++ ++mtrap-precision= ++Target RejectNegative Joined Var(sw_64_tp_string) ++Control the precision given to fp exceptions. ++ ++mmemory-latency= ++Target RejectNegative Joined Var(sw_64_mlat_string) ++Tune expected memory latency. ++ ++mtls-size= ++Target RejectNegative Joined UInteger Var(sw_64_tls_size) Init(32) ++Specify bit size of immediate TLS offsets. ++ ++msimd ++C C++ Fortran Driver Target Mask(SW_SIMD) Save ++Support SW SIMD built-in functions and code generation. ++ ++fsw-cmov ++Target Var(flag_sw_cmov) Init(1) ++Use added floating-point integer conversion instruction. ++ ++fsw-shift-word ++Target Var(flag_sw_shift_word) Init(1) ++Control: Rotate Left 64/32, Logical Shift Left/Right 64/32, Algorithmetic Shift Right 64/32. ++ ++fsw-rev ++Target Var(flag_sw_rev) Init(1) ++Control: Reverse 16/32/64. ++ ++mgprel-size= ++Target RejectNegative Joined UInteger Var(sw_64_gprel_size) Init(32) ++Specify bit size of gprel relocation offsets. ++ ++mtls-tlsgd= ++Target RejectNegative Joined UInteger Var(sw_64_tls_gd) Init(16) ++Specify the bitsize of tlsgd relocation offset relative GP. ++ ++mtls-tlsldm= ++Target RejectNegative Joined UInteger Var(sw_64_tls_ldm) Init(16) ++Specify the bitsize of tlsldm relocation offset relative GP. ++ ++mtls-gotdtprel= ++Target RejectNegative Joined UInteger Var(sw_64_tls_gotdtprel) Init(16) ++Specify the bitsize of gotdtprel relocation offset relative GP. ++ ++mtls-gottprel= ++Target RejectNegative Joined UInteger Var(sw_64_tls_gottprel) Init(16) ++Specify the bitsize of gottprel relocation offset relative GP. +diff --git a/gcc/config/sw_64/sync.md b/gcc/config/sw_64/sync.md +new file mode 100644 +index 000000000..3297bda25 +--- /dev/null ++++ b/gcc/config/sw_64/sync.md +@@ -0,0 +1,495 @@ ++;; GCC machine description for Sw64 synchronization instructions. ++;; Copyright (C) 2005-2022 Free Software Foundation, Inc. ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++;; GNU General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++(define_code_iterator FETCHOP [plus minus ior xor and]) ++(define_code_attr fetchop_name ++ [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")]) ++(define_code_attr fetchop_pred ++ [(plus "add_operand") (minus "reg_or_8bit_operand") ++ (ior "or_operand") (xor "or_operand") (and "and_operand")]) ++(define_code_attr fetchop_constr ++ [(plus "rKL") (minus "rI") (ior "rIN") (xor "rIN") (and "rINM")]) ++ ++ ++(define_expand "memory_barrier" ++ [(set (match_dup 0) ++ (unspec:BLK [(match_dup 0)] UNSPEC_MB))] ++ "" ++{ ++ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[0]) = 1; ++}) ++ ++;; mb-> memb ++(define_insn "*memory_barrier" ++ [(set (match_operand:BLK 0) ++ (unspec:BLK [(match_dup 0)] UNSPEC_MB))] ++ "" ++ "memb" ++ [(set_attr "type" "mb")]) ++ ++;; "ld_l %0,%1" ++(define_insn "@load_locked_" ++ [(set (match_operand:I48MODE 0 "register_operand" "=r") ++ (unspec_volatile:I48MODE ++ [(match_operand:I48MODE 1 "memory_operand" "m")] ++ UNSPECV_LL))] ++ "" ++ { ++ switch ('') ++ { ++ case 'w': ++ return "ldi %0,%1\;lldw %0,0(%0)"; ++ case 'l': ++ return "ldi %0,%1\;lldl %0,0(%0)"; ++ default: ++ return "ld_l %0,%1"; ++ } ++ } ++ [(set_attr "type" "ld_l")]) ++ ++;; "st_c %0,%1" ++(define_insn "@store_conditional_" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_SC)) ++ (set (match_operand:I48MODE 1 "memory_operand" "=m") ++ (match_operand:I48MODE 2 "reg_or_0_operand" "0")) ++ (clobber (reg:DI 28))] ++ "" ++ { ++ switch ('') ++ { ++ case 'w': ++ return "ldi $28,%1\;lstw %0,0($28)"; ++ case 'l': ++ return "ldi $28,%1\;lstl %0,0($28)"; ++ default: ++ return "st_c %0,%1"; ++ } ++ } ++ [(set_attr "type" "st_c")]) ++ ++ (define_insn "builtin_rd_f" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_SC))] ++ "" ++ "rd_f %0" ++ [(set_attr "type" "st_c")]) ++ ++ (define_insn "builtin_wr_f" ++ [(match_operand:DI 0 "register_operand" "r") ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_LL)] ++ "" ++ "wr_f %0" ++ [(set_attr "type" "ld_l")]) ++ ++;; The Sw_64 Architecture Handbook says that it is UNPREDICTABLE whether ++;; the lock is cleared by a normal load or store. This means we cannot ++;; expand a ll/sc sequence before reload, lest a register spill is ++;; inserted inside the sequence. It is also UNPREDICTABLE whether the ++;; lock is cleared by a TAKEN branch. This means that we can not expand ++;; a ll/sc sequence containing a branch (i.e. compare-and-swap) until after ++;; the final basic-block reordering pass. ++ ++(define_expand "atomic_compare_and_swap" ++ [(parallel ++ [(set (match_operand:DI 0 "register_operand") ;; bool out ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:I48MODE 1 "register_operand") ;; val out ++ (unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:I48MODE 2 "memory_operand") ;; memory ++ (unspec_volatile:I48MODE ++ [(match_dup 2) ++ (match_operand:I48MODE 3 "reg_or_8bit_operand") ;; expected ++ (match_operand:I48MODE 4 "add_operand") ;; desired ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; succ model ++ (match_operand:SI 7 "const_int_operand") ;; fail model ++ (match_operand:DI 8 "register_operand")] ++ UNSPECV_CMPXCHG)) ++ (clobber (reg:DI 28))])] ++ "" ++{ ++ if (mode == SImode) ++ { ++ operands[3] = convert_modes (DImode, SImode, operands[3], 0); ++ operands[4] = convert_modes (DImode, SImode, operands[4], 0); ++ } ++ if (TARGET_SW8A) ++ { ++ if (flag_sw_use_cas) ++ { ++ if (CONST_INT_P (operands[3])) ++ operands[3] = force_reg (DImode, operands[3]); ++ ++ if (CONST_INT_P (operands[4])) ++ operands[4] = force_reg (DImode, operands[4]); ++ ++ emit_insn (gen_atomic_compare_and_swap_target_sw8a (operands[0], ++ operands[1], ++ operands[2], ++ operands[3], ++ operands[4], ++ operands[5], ++ operands[6], ++ operands[7])); ++ DONE; ++ } ++ } ++}) ++ ++(define_insn_and_split "*atomic_compare_and_swap" ++ [(set (match_operand:DI 0 "register_operand" "=&r") ;; bool out ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:I48MODE 1 "register_operand" "=&r") ;; val out ++ (unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:I48MODE 2 "memory_operand" "+m") ;; memory ++ (unspec_volatile:I48MODE ++ [(match_dup 2) ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected ++ (match_operand:DI 4 "add_operand" "rKL") ;; desired ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; succ model ++ (match_operand:SI 7 "const_int_operand") ;; fail model ++ (match_operand:DI 8 "register_operand" "r")] ++ UNSPECV_CMPXCHG)) ++ (clobber (reg:DI 28))] ++ ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_compare_and_swap (operands); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_expand "atomic_compare_and_swap" ++ [(match_operand:DI 0 "register_operand") ;; bool out ++ (match_operand:I12MODE 1 "register_operand") ;; val out ++ (match_operand:I12MODE 2 "mem_noofs_operand") ;; memory ++ (match_operand:I12MODE 3 "register_operand") ;; expected ++ (match_operand:I12MODE 4 "add_operand") ;; desired ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; succ model ++ (match_operand:SI 7 "const_int_operand") ;; fail model ++ (match_operand:DI 8 "register_operand")] ++ "" ++{ ++ if ( (TARGET_SW8A) && flag_sw_use_cas) ++ { ++ if (CONST_INT_P (operands[3])) ++ operands[3] = force_reg (mode, operands[3]); ++ ++ if (CONST_INT_P (operands[4])) ++ operands[4] = force_reg (mode, operands[4]); ++ } ++ sw_64_expand_compare_and_swap_12 (operands); ++ DONE; ++}) ++ ++(define_insn_and_split "@atomic_compare_and_swap_1" ++ [(set (match_operand:DI 0 "register_operand" "=&r") ;; bool out ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:DI 1 "register_operand" "=&r") ;; val out ++ (zero_extend:DI ++ (unspec_volatile:I12MODE [(const_int 0)] UNSPECV_CMPXCHG))) ++ (set (match_operand:I12MODE 2 "mem_noofs_operand" "+w") ;; memory ++ (unspec_volatile:I12MODE ++ [(match_dup 2) ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected ++ (match_operand:DI 4 "reg_or_0_operand" "rJ") ;; desired ++ (match_operand:DI 5 "register_operand" "r") ;; align ++ (match_operand:SI 6 "const_int_operand") ;; is_weak ++ (match_operand:SI 7 "const_int_operand") ;; succ model ++ (match_operand:SI 8 "const_int_operand") ;; fail model ++ (match_operand:DI 9 "register_operand" "r")] ++ UNSPECV_CMPXCHG)) ++ (clobber (match_scratch:DI 10 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_compare_and_swap_12 (operands); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic_compare_and_swap_target_sw8a" ++ [(set (match_operand:DI 0 "register_operand" "=&r") ;; bool out ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:I48MODE 1 "register_operand" "=&r") ;; val out ++ (unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:I48MODE 2 "memory_operand" "+m") ;; memory ++ (unspec_volatile:I48MODE ++ [(match_dup 2) ++ (match_operand:DI 3 "reg_or_8bit_operand" "r") ;; expected ++ (match_operand:DI 4 "add_operand" "r") ;; desired ++ (match_operand:SI 5 "const_int_operand") ;; is_weak ++ (match_operand:SI 6 "const_int_operand") ;; succ model ++ (match_operand:SI 7 "const_int_operand")] ;; fail model ++ UNSPECV_CMPXCHG)) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ if ( TARGET_SW8A && flag_sw_use_cas) ++ sw_64_split_atomic_cas (operands); ++ else ++ sw_64_split_compare_and_swap (operands); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "@atomic_compare_and_swap_1_target_sw8a" ++ [(set (match_operand:DI 0 "register_operand" "=&r") ;; bool out ++ (unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG)) ++ (set (match_operand:DI 1 "register_operand" "=&r") ;; val out ++ (zero_extend:DI ++ (unspec_volatile:I12MODE [(const_int 0)] UNSPECV_CMPXCHG))) ++ (set (match_operand:I12MODE 2 "mem_noofs_operand" "+w") ;; memory ++ (unspec_volatile:I12MODE ++ [(match_dup 2) ++ (match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected ++ (match_operand:DI 4 "register_operand" "r") ;; desired ++ (match_operand:DI 5 "register_operand" "r") ;; align ++ (match_operand:SI 6 "const_int_operand") ;; is_weak ++ (match_operand:SI 7 "const_int_operand") ;; succ model ++ (match_operand:SI 8 "const_int_operand")] ;; fail model ++ UNSPECV_CMPXCHG)) ++ (clobber (match_scratch:DI 9 "=&r")) ++ (clobber (match_scratch:DI 10 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_compare_and_swap_12 (operands); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn "sw_64_atomic_cas" ++ [(set (match_operand:I48MODE 0 "register_operand" "") ;; out ++ (match_operand:I48MODE 1 "memory_operand" "")) ;; memory. ++ (set (match_dup 1) ++ (unspec_volatile:I48MODE ++ [(match_dup 0) ++ (match_operand:I48MODE 2 "register_operand" "")] ;; value. ++ UNSPECV_CMPXCHG)) ++ (clobber (reg:DI 28))] ++ "TARGET_SW8A && flag_sw_use_cas" ++ "ldi $28,%1\;cas %0,$28,%2") ++;; endif ++ ++(define_insn_and_split "atomic_exchange" ++ [(set (match_operand:I48MODE 0 "register_operand" "=&r") ;; output ++ (match_operand:I48MODE 1 "memory_operand" "+m")) ;; memory ++ (set (match_dup 1) ++ (unspec:I48MODE ++ [(match_operand:I48MODE 2 "add_operand" "rKL") ;; input ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ UNSPEC_XCHG)) ++ (clobber (match_scratch:I48MODE 4 "=&r"))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_exchange (operands); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_expand "atomic_exchange" ++ [(match_operand:I12MODE 0 "register_operand") ;; output ++ (match_operand:I12MODE 1 "mem_noofs_operand") ;; memory ++ (match_operand:I12MODE 2 "reg_or_0_operand") ;; input ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ "" ++{ ++ sw_64_expand_atomic_exchange_12 (operands); ++ DONE; ++}) ++ ++(define_insn_and_split "@atomic_exchange_1" ++ [(set (match_operand:DI 0 "register_operand" "=&r") ;; output ++ (zero_extend:DI ++ (match_operand:I12MODE 1 "mem_noofs_operand" "+w"))) ;; memory ++ (set (match_dup 1) ++ (unspec:I12MODE ++ [(match_operand:DI 2 "reg_or_8bit_operand" "rI") ;; input ++ (match_operand:DI 3 "register_operand" "r") ;; align ++ (match_operand:SI 4 "const_int_operand")] ;; model ++ UNSPEC_XCHG)) ++ (clobber (match_scratch:DI 5 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_exchange_12 (operands); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic_" ++ [(set (match_operand:I48MODE 0 "memory_operand" "+m") ++ (unspec:I48MODE ++ [(FETCHOP:I48MODE (match_dup 0) ++ (match_operand:I48MODE 1 "" "")) ++ (match_operand:SI 2 "const_int_operand")] ++ UNSPEC_ATOMIC)) ++ (clobber (match_scratch:I48MODE 3 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_op (, operands[0], operands[1], ++ NULL, NULL, operands[3], ++ (enum memmodel) INTVAL (operands[2])); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic_nand" ++ [(set (match_operand:I48MODE 0 "memory_operand" "+m") ++ (unspec:I48MODE ++ [(not:I48MODE ++ (and:I48MODE (match_dup 0) ++ (match_operand:I48MODE 1 "register_operand" "r"))) ++ (match_operand:SI 2 "const_int_operand")] ++ UNSPEC_ATOMIC)) ++ (clobber (match_scratch:I48MODE 3 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_op (NOT, operands[0], operands[1], ++ NULL, NULL, operands[3], ++ (enum memmodel) INTVAL (operands[2])); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic_fetch_" ++ [(set (match_operand:I48MODE 0 "register_operand" "=&r") ++ (match_operand:I48MODE 1 "memory_operand" "+m")) ++ (set (match_dup 1) ++ (unspec:I48MODE ++ [(FETCHOP:I48MODE (match_dup 1) ++ (match_operand:I48MODE 2 "" "")) ++ (match_operand:SI 3 "const_int_operand")] ++ UNSPEC_ATOMIC)) ++ (clobber (match_scratch:I48MODE 4 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_op (, operands[1], operands[2], ++ operands[0], NULL, operands[4], ++ (enum memmodel) INTVAL (operands[3])); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic_fetch_nand" ++ [(set (match_operand:I48MODE 0 "register_operand" "=&r") ++ (match_operand:I48MODE 1 "memory_operand" "+m")) ++ (set (match_dup 1) ++ (unspec:I48MODE ++ [(not:I48MODE ++ (and:I48MODE (match_dup 1) ++ (match_operand:I48MODE 2 "register_operand" "r"))) ++ (match_operand:SI 3 "const_int_operand")] ++ UNSPEC_ATOMIC)) ++ (clobber (match_scratch:I48MODE 4 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_op (NOT, operands[1], operands[2], ++ operands[0], NULL, operands[4], ++ (enum memmodel) INTVAL (operands[3])); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic__fetch" ++ [(set (match_operand:I48MODE 0 "register_operand" "=&r") ++ (FETCHOP:I48MODE ++ (match_operand:I48MODE 1 "memory_operand" "+m") ++ (match_operand:I48MODE 2 "" ""))) ++ (set (match_dup 1) ++ (unspec:I48MODE ++ [(FETCHOP:I48MODE (match_dup 1) (match_dup 2)) ++ (match_operand:SI 3 "const_int_operand")] ++ UNSPEC_ATOMIC)) ++ (clobber (match_scratch:I48MODE 4 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_op (, operands[1], operands[2], ++ NULL, operands[0], operands[4], ++ (enum memmodel) INTVAL (operands[3])); ++ DONE; ++} ++ [(set_attr "type" "multi")]) ++ ++(define_insn_and_split "atomic_nand_fetch" ++ [(set (match_operand:I48MODE 0 "register_operand" "=&r") ++ (not:I48MODE ++ (and:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m") ++ (match_operand:I48MODE 2 "register_operand" "r")))) ++ (set (match_dup 1) ++ (unspec:I48MODE ++ [(not:I48MODE (and:I48MODE (match_dup 1) (match_dup 2))) ++ (match_operand:SI 3 "const_int_operand")] ++ UNSPEC_ATOMIC)) ++ (clobber (match_scratch:I48MODE 4 "=&r")) ++ (clobber (reg:DI 28))] ++ "" ++ "#" ++ "epilogue_completed" ++ [(const_int 0)] ++{ ++ sw_64_split_atomic_op (NOT, operands[1], operands[2], ++ NULL, operands[0], operands[4], ++ (enum memmodel) INTVAL (operands[3])); ++ DONE; ++} ++ [(set_attr "type" "multi")]) +diff --git a/gcc/config/sw_64/t-linux b/gcc/config/sw_64/t-linux +new file mode 100644 +index 000000000..d78ef47df +--- /dev/null ++++ b/gcc/config/sw_64/t-linux +@@ -0,0 +1 @@ ++MULTIARCH_DIRNAME = $(call if_multiarch,sw_64-linux-gnu) +diff --git a/gcc/config/sw_64/t-sw_64 b/gcc/config/sw_64/t-sw_64 +new file mode 100644 +index 000000000..c9b4b6267 +--- /dev/null ++++ b/gcc/config/sw_64/t-sw_64 +@@ -0,0 +1,19 @@ ++# Copyright (C) 2016-2022 Free Software Foundation, Inc. ++# ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . ++ ++PASSES_EXTRA += $(srcdir)/config/sw_64/sw_64-passes.def +diff --git a/gcc/config/sw_64/x-sw_64 b/gcc/config/sw_64/x-sw_64 +new file mode 100644 +index 000000000..ab615cd1b +--- /dev/null ++++ b/gcc/config/sw_64/x-sw_64 +@@ -0,0 +1,3 @@ ++driver-sw_64.o: $(srcdir)/config/sw_64/driver-sw_64.cc ++ $(COMPILE) $< ++ $(POSTCOMPILE) +diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc +index 2df5ff414..e500b583a 100644 +--- a/gcc/emit-rtl.cc ++++ b/gcc/emit-rtl.cc +@@ -2409,6 +2409,41 @@ adjust_address_1 (rtx memref, machine_mode mode, poly_int64 offset, + addr = gen_rtx_ZERO_EXTEND (address_mode, + plus_constant (pointer_mode, + XEXP (addr, 0), offset)); ++#endif ++#ifdef FLAG_SW64_INC_DEC ++ else if (GET_CODE (addr) == POST_INC) ++ ; ++ else if (GET_CODE (addr) == POST_DEC) ++ { ++ rtx term; ++ rtx reg = XEXP (addr, 0); ++ if (known_eq (offset, 0)) ++ term = GEN_INT (8); ++ else ++ term = GEN_INT (-24); ++ addr ++ = gen_rtx_POST_MODIFY (mode, reg, gen_rtx_PLUS (mode, reg, term)); ++ } ++ else if (GET_CODE (addr) == POST_MODIFY) ++ { ++ if (GET_CODE (XEXP (addr, 1)) == PLUS) ++ { ++ if (CONSTANT_P (XEXP (XEXP (addr, 1), 1))) ++ { ++ rtx term; ++ rtx reg = XEXP (XEXP (addr, 1), 0); ++ if (known_eq (offset, 0)) ++ term = GEN_INT (8); ++ else ++ term = plus_constant (mode, XEXP (XEXP (addr, 1), 1), -8); ++ if (term == const0_rtx) ++ XEXP (addr, 1) = XEXP (XEXP (addr, 1), 0); ++ else ++ addr = gen_rtx_POST_MODIFY (mode, reg, ++ gen_rtx_PLUS (mode, reg, term)); ++ } ++ } ++ } + #endif + else + addr = plus_constant (address_mode, addr, offset); +diff --git a/gcc/explow.cc b/gcc/explow.cc +index 124e8f49e..c7a3570b3 100644 +--- a/gcc/explow.cc ++++ b/gcc/explow.cc +@@ -1275,7 +1275,11 @@ get_dynamic_stack_size (rtx *psize, unsigned size_align, + in SIZE for the hole that might result from the alignment operation. */ + + unsigned known_align = REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM); ++#ifndef FLAG_SW64_90139 ++ // it change from 710 extra = (required_align - BITS_PER_UNIT) ++ // / BITS_PER_UNIT; see the test pr20210303 + if (known_align == 0) ++#endif + known_align = BITS_PER_UNIT; + if (required_align > known_align) + { +diff --git a/gcc/final.cc b/gcc/final.cc +index e4bfceabc..3b3f3d415 100644 +--- a/gcc/final.cc ++++ b/gcc/final.cc +@@ -1830,7 +1830,12 @@ profile_function (FILE *file ATTRIBUTE_UNUSED) + { + int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE); + switch_to_section (data_section); ++#ifdef FLAG_SW64_DELNOP ++ if (flag_sw_delnop == 0) ++ ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); ++#else + ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); ++#endif + targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no); + assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1); + } +@@ -2414,6 +2419,8 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, + #ifdef ASM_OUTPUT_ALIGN_WITH_NOP + ASM_OUTPUT_ALIGN_WITH_NOP (file, alignment.levels[0].log); + #else ++ if (flag_sw_delnop == 0) ++ ASM_OUTPUT_ALIGN (file, alignment.levels[0].log); + ASM_OUTPUT_ALIGN (file, alignment.levels[0].log); + #endif + #endif +@@ -2450,7 +2457,12 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, + #else + log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); + #endif ++#ifdef FLAG_SW64_DELNOP ++ if (flag_sw_delnop == 0) ++ ASM_OUTPUT_ALIGN (file, log_align); ++#else + ASM_OUTPUT_ALIGN (file, log_align); ++#endif + } + else + switch_to_section (current_function_section ()); +diff --git a/gcc/flags.h b/gcc/flags.h +index 212e357a0..7d025346b 100644 +--- a/gcc/flags.h ++++ b/gcc/flags.h +@@ -76,6 +76,10 @@ extern bool fast_math_flags_struct_set_p (struct cl_optimization *); + /* True if printing into -fdump-final-insns= dump. */ + + extern bool final_insns_dump_p; ++#ifdef SW64_TARGET_SUPPORT_FPCR ++extern int flag_fpcr_set; ++extern int stfp3_flag; ++#endif + + + /* Other basic status info about current function. */ +diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc +index 874acb914..26ab11a39 100644 +--- a/gcc/fortran/interface.cc ++++ b/gcc/fortran/interface.cc +@@ -3355,10 +3355,19 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, + "at %L", f->sym->name, actual_size, + formal_size, &a->expr->where); + else +- gfc_error_now ("Actual argument contains too few " ++#ifdef FLAG_SW64_90139 // close this for it will cause speccpu 416 build err ++ gfc_warning (OPT_Wargument_mismatch, ++ "Actual argument contains too few " ++ "elements for dummy argument %qs (%lu/%lu) " ++ "at %L.Please add -std=legacy options", ++ f->sym->name, actual_size, formal_size, ++ &a->expr->where); ++#else ++ gfc_error_now ("Actual argument contains too few " + "elements for dummy argument %qs (%lu/%lu) " + "at %L", f->sym->name, actual_size, + formal_size, &a->expr->where); ++#endif + } + ok = false; + goto match; +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index b37b50be2..01889f0d4 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -1953,6 +1953,12 @@ init_spec (void) + } + #endif + ++/* --no-relax for sw_64 */ ++#ifdef ENABLE_LD_NORELAX ++#define LINK_NORELAX_SPEC "%{!r:--no-relax} " ++ obstack_grow (&obstack, LINK_NORELAX_SPEC, sizeof (LINK_NORELAX_SPEC) - 1); ++#endif ++ + #if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \ + defined LINKER_HASH_STYLE + # ifdef LINK_BUILDID_SPEC +diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc +index 1c74d3808..ec97284dd 100644 +--- a/gcc/gimple-match-head.cc ++++ b/gcc/gimple-match-head.cc +@@ -1243,6 +1243,11 @@ optimize_pow_to_exp (tree arg0, tree arg1) + case PLUS_EXPR: + case MINUS_EXPR: + break; ++#ifdef FLAG_SW64_FM ++ case PAREN_EXPR: ++ if (flag_sw_fast_math == 1) ++ return false; ++#endif + default: + return true; + } +diff --git a/gcc/optabs.cc b/gcc/optabs.cc +index b441137de..72b7c1513 100644 +--- a/gcc/optabs.cc ++++ b/gcc/optabs.cc +@@ -6988,7 +6988,12 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval, + enum memmodel fail_model) + { + machine_mode mode = GET_MODE (mem); ++#ifdef FLAG_SW64_ATOMIC ++ class expand_operand ops[9]; ++ rtx imust = gen_reg_rtx (DImode); ++#else + class expand_operand ops[8]; ++#endif + enum insn_code icode; + rtx target_oval, target_bool = NULL_RTX; + rtx libfunc; +@@ -7037,7 +7042,12 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval, + create_integer_operand (&ops[5], is_weak); + create_integer_operand (&ops[6], succ_model); + create_integer_operand (&ops[7], fail_model); ++#ifdef FLAG_SW64_ATOMIC ++ create_fixed_operand (&ops[8], imust); ++ if (maybe_expand_insn (icode, 9, ops)) ++#else + if (maybe_expand_insn (icode, 8, ops)) ++#endif + { + /* Return success/failure. */ + target_bool = ops[0].value; +diff --git a/include/longlong.h b/include/longlong.h +index 64a7b10f9..9f65d6eca 100644 +--- a/include/longlong.h ++++ b/include/longlong.h +@@ -1458,6 +1458,65 @@ extern UDItype __umulsidi3 (USItype, USItype); + #define UDIV_TIME 230 + #endif /* sparc64 */ + ++#if defined(__sw_64) && W_TYPE_SIZE == 64 ++/* There is a bug in g++ before version 5 that ++ errors on __builtin_sw_64_umulh. */ ++#if !defined(__cplusplus) || __GNUC__ >= 5 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do \ ++ { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ (ph) = __builtin_sw_64_umulh (__m0, __m1); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 46 ++#endif /* !c++ */ ++#ifndef LONGLONG_STANDALONE ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do \ ++ { \ ++ UDItype __r; \ ++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ ++ (r) = __r; \ ++ } while (0) ++extern UDItype ++__udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); ++#define UDIV_TIME 220 ++#endif /* LONGLONG_STANDALONE */ ++#ifdef __sw_64_cix__ ++#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clzl (X)) ++#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctzl (X)) ++#define COUNT_LEADING_ZEROS_0 64 ++#else ++#define count_leading_zeros(COUNT, X) \ ++ do \ ++ { \ ++ UDItype __xr = (X), __t, __a; \ ++ __t = __builtin_sw_64_cmpbge (0, __xr); \ ++ __a = __clz_tab[__t ^ 0xff] - 1; \ ++ __t = __builtin_sw_64_extbl (__xr, __a); \ ++ (COUNT) = 64 - (__clz_tab[__t] + __a * 8); \ ++ } while (0) ++#define count_trailing_zeros(COUNT, X) \ ++ do \ ++ { \ ++ UDItype __xr = (X), __t, __a; \ ++ __t = __builtin_sw_64_cmpbge (0, __xr); \ ++ __t = ~__t & -~__t; \ ++ __a = ((__t & 0xCC) != 0) * 2; \ ++ __a += ((__t & 0xF0) != 0) * 4; \ ++ __a += ((__t & 0xAA) != 0); \ ++ __t = __builtin_sw_64_extbl (__xr, __a); \ ++ __a <<= 3; \ ++ __t &= -__t; \ ++ __a += ((__t & 0xCC) != 0) * 2; \ ++ __a += ((__t & 0xF0) != 0) * 4; \ ++ __a += ((__t & 0xAA) != 0); \ ++ (COUNT) = __a; \ ++ } while (0) ++#endif /* __sw_64_cix__ */ ++#endif /* __sw_64 */ ++ + #if defined (__vax__) && W_TYPE_SIZE == 32 + #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ +-- +2.25.1 + diff --git a/0003-Sw64-Port-add-multi-prefetch-support-for-sw64.patch b/0003-Sw64-Port-add-multi-prefetch-support-for-sw64.patch new file mode 100644 index 0000000000000000000000000000000000000000..33bf800101a837556452c5e9db39ac8552942d9e --- /dev/null +++ b/0003-Sw64-Port-add-multi-prefetch-support-for-sw64.patch @@ -0,0 +1,528 @@ +From bfa51c2eda3e40fdfd64601f5e7df19049a006cd Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:33:10 +0800 +Subject: [PATCH 03/16] Sw64 Port: add multi-prefetch support for sw64 + +--- + gcc/builtins.cc | 161 +++++++++++++++++++++++++++++++++- + gcc/builtins.def | 2 + + gcc/ipa-pure-const.cc | 2 + + gcc/opt-functions.awk | 4 +- + gcc/params.opt | 12 +++ + gcc/target-insns.def | 3 + + gcc/tree-ssa-loop-prefetch.cc | 155 +++++++++++++++++++++++++++++++- + 7 files changed, 336 insertions(+), 3 deletions(-) + +diff --git a/gcc/builtins.cc b/gcc/builtins.cc +index 57929a42b..c2589f316 100644 +--- a/gcc/builtins.cc ++++ b/gcc/builtins.cc +@@ -109,6 +109,8 @@ static int apply_args_size (void); + static int apply_result_size (void); + static rtx result_vector (int, rtx); + static void expand_builtin_prefetch (tree); ++static void expand_builtin_prefetch_sc (tree); ++static void expand_builtin_prefetch_tc (tree); + static rtx expand_builtin_apply_args (void); + static rtx expand_builtin_apply_args_1 (void); + static rtx expand_builtin_apply (rtx, rtx, rtx); +@@ -1352,6 +1354,156 @@ expand_builtin_prefetch (tree exp) + emit_insn (op0); + } + ++static void ++expand_builtin_prefetch_sc (tree exp) ++{ ++ tree arg0, arg1, arg2; ++ int nargs; ++ rtx op0, op1, op2; ++ ++ if (!validate_arglist (exp, POINTER_TYPE, 0)) ++ return; ++ ++ arg0 = CALL_EXPR_ARG (exp, 0); ++ ++ /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to ++ * zero (read) and argument 2 (locality) defaults to 3 (high degree of ++ * locality). */ ++ nargs = call_expr_nargs (exp); ++ if (nargs > 1) ++ arg1 = CALL_EXPR_ARG (exp, 1); ++ else ++ arg1 = integer_zero_node; ++ if (nargs > 2) ++ arg2 = CALL_EXPR_ARG (exp, 2); ++ else ++ arg2 = integer_three_node; ++ ++ /* Argument 0 is an address. */ ++ op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); ++ ++ /* Argument 1 (read/write flag) must be a compile-time constant int. */ ++ if (TREE_CODE (arg1) != INTEGER_CST) ++ { ++ error ("second argument to %<__builtin_prefetch_sc%> must be a constant"); ++ arg1 = integer_zero_node; ++ } ++ op1 = expand_normal (arg1); ++ /* Argument 1 must be either zero or one. */ ++ if (INTVAL (op1) != 0 && INTVAL (op1) != 1) ++ { ++ warning (0, "invalid second argument to %<__builtin_prefetch_sc%>;" ++ " using zero"); ++ op1 = const0_rtx; ++ } ++ ++ /* Argument 2 (locality) must be a compile-time constant int. */ ++ if (TREE_CODE (arg2) != INTEGER_CST) ++ { ++ error ("third argument to %<__builtin_prefetch_sc%> must be a constant"); ++ arg2 = integer_zero_node; ++ } ++ op2 = expand_normal (arg2); ++ /* Argument 2 must be 0, 1, 2, or 3. */ ++ if (INTVAL (op2) < 0 || INTVAL (op2) > 3) ++ { ++ warning ( ++ 0, "invalid third argument to %<__builtin_prefetch_sc%>; using zero"); ++ op2 = const0_rtx; ++ } ++ ++ if (targetm.have_prefetch ()) ++ { ++ class expand_operand ops[3]; ++ ++ create_address_operand (&ops[0], op0); ++ create_integer_operand (&ops[1], INTVAL (op1)); ++ create_integer_operand (&ops[2], INTVAL (op2)); ++ if (maybe_expand_insn (targetm.code_for_prefetch_sc, 3, ops)) ++ return; ++ } ++ ++ /* Don't do anything with direct references to volatile memory, but ++ * generate code to handle other side effects. */ ++ if (!MEM_P (op0) && side_effects_p (op0)) ++ emit_insn (op0); ++} ++ ++static void ++expand_builtin_prefetch_tc (tree exp) ++{ ++ tree arg0, arg1, arg2; ++ int nargs; ++ rtx op0, op1, op2; ++ ++ if (!validate_arglist (exp, POINTER_TYPE, 0)) ++ return; ++ ++ arg0 = CALL_EXPR_ARG (exp, 0); ++ ++ /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to ++ * zero (read) and argument 2 (locality) defaults to 3 (high degree of ++ * locality). */ ++ nargs = call_expr_nargs (exp); ++ if (nargs > 1) ++ arg1 = CALL_EXPR_ARG (exp, 1); ++ else ++ arg1 = integer_zero_node; ++ if (nargs > 2) ++ arg2 = CALL_EXPR_ARG (exp, 2); ++ else ++ arg2 = integer_three_node; ++ ++ /* Argument 0 is an address. */ ++ op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); ++ ++ /* Argument 1 (read/write flag) must be a compile-time constant int. */ ++ if (TREE_CODE (arg1) != INTEGER_CST) ++ { ++ error ("second argument to %<__builtin_prefetch%> must be a constant"); ++ arg1 = integer_zero_node; ++ } ++ op1 = expand_normal (arg1); ++ /* Argument 1 must be either zero or one. */ ++ if (INTVAL (op1) != 0 && INTVAL (op1) != 1) ++ { ++ warning (0, "invalid second argument to %<__builtin_prefetch%>;" ++ " using zero"); ++ op1 = const0_rtx; ++ } ++ ++ /* Argument 2 (locality) must be a compile-time constant int. */ ++ if (TREE_CODE (arg2) != INTEGER_CST) ++ { ++ error ("third argument to %<__builtin_prefetch%> must be a constant"); ++ arg2 = integer_zero_node; ++ } ++ op2 = expand_normal (arg2); ++ /* Argument 2 must be 0, 1, 2, or 3. */ ++ if (INTVAL (op2) < 0 || INTVAL (op2) > 3) ++ { ++ warning (0, ++ "invalid third argument to %<__builtin_prefetch%>; using zero"); ++ op2 = const0_rtx; ++ } ++ ++ if (targetm.have_prefetch ()) ++ { ++ class expand_operand ops[3]; ++ ++ create_address_operand (&ops[0], op0); ++ create_integer_operand (&ops[1], INTVAL (op1)); ++ create_integer_operand (&ops[2], INTVAL (op2)); ++ if (maybe_expand_insn (targetm.code_for_prefetch_tc, 3, ops)) ++ return; ++ } ++ ++ /* Don't do anything with direct references to volatile memory, but ++ * generate code to handle other side effects. */ ++ if (!MEM_P (op0) && side_effects_p (op0)) ++ emit_insn (op0); ++} ++ + /* Get a MEM rtx for expression EXP which is the address of an operand + to be used in a string instruction (cmpstrsi, cpymemsi, ..). LEN is + the maximum length of the block of memory that might be accessed or +@@ -7598,7 +7750,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, + case BUILT_IN_PREFETCH: + expand_builtin_prefetch (exp); + return const0_rtx; +- ++ case BUILT_IN_PREFETCH_SC: ++ expand_builtin_prefetch_sc (exp); ++ return const0_rtx; ++ case BUILT_IN_PREFETCH_TC: ++ expand_builtin_prefetch_tc (exp); ++ return const0_rtx; + case BUILT_IN_INIT_TRAMPOLINE: + return expand_builtin_init_trampoline (exp, true); + case BUILT_IN_INIT_HEAP_TRAMPOLINE: +@@ -10989,6 +11146,8 @@ is_inexpensive_builtin (tree decl) + case BUILT_IN_LABS: + case BUILT_IN_LLABS: + case BUILT_IN_PREFETCH: ++ case BUILT_IN_PREFETCH_SC: ++ case BUILT_IN_PREFETCH_TC: + case BUILT_IN_ACC_ON_DEVICE: + return true; + +diff --git a/gcc/builtins.def b/gcc/builtins.def +index 005976f34..983de293e 100644 +--- a/gcc/builtins.def ++++ b/gcc/builtins.def +@@ -924,6 +924,8 @@ DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_C + DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) + DEF_EXT_LIB_BUILTIN (BUILT_IN_POSIX_MEMALIGN, "posix_memalign", BT_FN_INT_PTRPTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) + DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST) ++DEF_GCC_BUILTIN (BUILT_IN_PREFETCH_SC, "prefetch_sc", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST) ++DEF_GCC_BUILTIN (BUILT_IN_PREFETCH_TC, "prefetch_tc", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST) + DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LEAF_LIST) + DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST) + DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST) +diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc +index 2642df91e..89a950966 100644 +--- a/gcc/ipa-pure-const.cc ++++ b/gcc/ipa-pure-const.cc +@@ -534,6 +534,8 @@ builtin_safe_for_const_function_p (bool *looping, tree callee) + *looping = false; + return true; + case BUILT_IN_PREFETCH: ++ case BUILT_IN_PREFETCH_SC: ++ case BUILT_IN_PREFETCH_TC: + *looping = true; + return true; + default: +diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk +index 2aee0b9f1..0dabde89d 100644 +--- a/gcc/opt-functions.awk ++++ b/gcc/opt-functions.awk +@@ -247,6 +247,8 @@ function var_type(flags) + return "HOST_WIDE_INT " + else if (flag_set_p("UInteger", flags)) + return "int " ++ else if (flag_set_p("UInteger", flags)) ++ return "int " + else + return "const char *" + } +@@ -256,7 +258,7 @@ function var_type(flags) + # type instead of int to save space. + function var_type_struct(flags) + { +- if (flag_set_p("UInteger", flags)) { ++ if (flag_set_p("UInteger", flags)) { + if (host_wide_int[var_name(flags)] == "yes") + return "HOST_WIDE_INT "; + if (flag_set_p("ByteSize", flags)) +diff --git a/gcc/params.opt b/gcc/params.opt +index 3ddfaf5b2..5abc8ce82 100644 +--- a/gcc/params.opt ++++ b/gcc/params.opt +@@ -385,6 +385,18 @@ The size of L1 cache. + Common Joined UInteger Var(param_l2_cache_size) Init(512) Param Optimization + The size of L2 cache. + ++-param=pf1= ++Common Joined UInteger Var(PF1) Init(0) IntegerRange(0,200) Param Optimization ++The number of Cache lines add to L1 prefetch delta. ++ ++-param=pf2= ++Common Joined UInteger Var(PF2) Init(0) IntegerRange(0,200) Param Optimization ++The number of Cache lines add to L2 prefetch delta. ++ ++-param=pf3= ++Common Joined UInteger Var(PF3) Init(0) IntegerRange(0,200) Param Optimization ++The number of Cache lines add to L3 prefetch delta. ++ + -param=large-function-growth= + Common Joined UInteger Var(param_large_function_growth) Optimization Init(100) Param + Maximal growth due to inlining of large function (in percent). +diff --git a/gcc/target-insns.def b/gcc/target-insns.def +index de8c0092f..8b4da8bc4 100644 +--- a/gcc/target-insns.def ++++ b/gcc/target-insns.def +@@ -77,6 +77,9 @@ DEF_TARGET_INSN (omp_simt_vote_any, (rtx x0, rtx x1)) + DEF_TARGET_INSN (omp_simt_xchg_bfly, (rtx x0, rtx x1, rtx x2)) + DEF_TARGET_INSN (omp_simt_xchg_idx, (rtx x0, rtx x1, rtx x2)) + DEF_TARGET_INSN (prefetch, (rtx x0, rtx x1, rtx x2)) ++DEF_TARGET_INSN (prefetch_sc, (rtx x0, rtx x1, rtx x2)) ++DEF_TARGET_INSN (prefetch_tc, (rtx x0, rtx x1, rtx x2)) ++/*********************/ + DEF_TARGET_INSN (probe_stack, (rtx x0)) + DEF_TARGET_INSN (probe_stack_address, (rtx x0)) + DEF_TARGET_INSN (prologue, (void)) +diff --git a/gcc/tree-ssa-loop-prefetch.cc b/gcc/tree-ssa-loop-prefetch.cc +index aebd7c920..6aa242260 100644 +--- a/gcc/tree-ssa-loop-prefetch.cc ++++ b/gcc/tree-ssa-loop-prefetch.cc +@@ -193,6 +193,9 @@ along with GCC; see the file COPYING3. If not see + #define L1_CACHE_SIZE_BYTES ((unsigned) (param_l1_cache_size * 1024)) + #define L2_CACHE_SIZE_BYTES ((unsigned) (param_l2_cache_size * 1024)) + ++#ifdef FLAG_SW64_PREFETCH ++#define L1_CACHE_LINE_SIZE ((unsigned) (param_l1_cache_line_size)) ++#endif + /* We consider a memory access nontemporal if it is not reused sooner than + after L2_CACHE_SIZE_BYTES of memory are accessed. However, we ignore + accesses closer than L1_CACHE_SIZE_BYTES / NONTEMPORAL_FRACTION, +@@ -1057,7 +1060,11 @@ schedule_prefetches (struct mem_ref_group *groups, unsigned unroll_factor, + + /* At most param_simultaneous_prefetches should be running + at the same time. */ ++#ifdef FLAG_SW64_PREFETCH ++ remaining_prefetch_slots = param_simultaneous_prefetches * 5; ++#else + remaining_prefetch_slots = param_simultaneous_prefetches; ++#endif + + /* The prefetch will run for AHEAD iterations of the original loop, i.e., + AHEAD / UNROLL_FACTOR iterations of the unrolled loop. In each iteration, +@@ -1081,8 +1088,10 @@ schedule_prefetches (struct mem_ref_group *groups, unsigned unroll_factor, + /* The loop is far from being sufficiently unrolled for this + prefetch. Do not generate prefetch to avoid many redudant + prefetches. */ +- if (ref->prefetch_mod / unroll_factor > PREFETCH_MOD_TO_UNROLL_FACTOR_RATIO) ++#ifndef FLAG_SW64_PREFETCH ++ if (ref->prefetch_mod / unroll_factor > PREFETCH_MOD_TO_UNROLL_FACTOR_RATIO) + continue; ++#endif + + /* If we need to prefetch the reference each PREFETCH_MOD iterations, + and we unroll the loop UNROLL_FACTOR times, we need to insert +@@ -1153,6 +1162,19 @@ estimate_prefetch_count (struct mem_ref_group *groups, unsigned unroll_factor) + return prefetch_count; + } + ++#ifdef FLAG_SW64_PREFETCH ++/*Due to the need for SW to dynamically adjust the value of PF during ++ * prefetching,PF needs to handle negative values.However ,since Common Joined ++ * UInteger Var(PFX) is used, the function needs to convert unsigned (0-200) to ++ * (-100,100)*/ ++int ++convert_default_to_sw (unsigned int pf_value) ++{ ++ if (pf_value > 100) ++ return 100 - (int) pf_value; ++ return pf_value; ++} ++#endif + /* Issue prefetches for the reference REF into loop as decided before. + HEAD is the number of iterations to prefetch ahead. UNROLL_FACTOR + is the factor by which LOOP was unrolled. */ +@@ -1184,11 +1206,21 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead) + + for (ap = 0; ap < n_prefetches; ap++) + { ++#ifdef FLAG_SW64_PREFETCH ++ if (flag_sw_prefetch_dc == 1) ++ { ++#endif + if (cst_and_fits_in_hwi (ref->group->step)) + { + /* Determine the address to prefetch. */ ++#ifdef FLAG_SW64_PREFETCH ++ delta = (ahead + ap * ref->prefetch_mod) * ++ int_cst_value (ref->group->step) * 2 ++ + convert_default_to_sw (PF1) * L1_CACHE_LINE_SIZE; ++#else + delta = (ahead + ap * ref->prefetch_mod) * + int_cst_value (ref->group->step); ++#endif + addr = fold_build_pointer_plus_hwi (addr_base, delta); + addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, + NULL, true, GSI_SAME_STMT); +@@ -1220,6 +1252,86 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead) + prefetch = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH), + 3, addr, write_p, local); + gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT); ++#ifdef FLAG_SW64_PREFETCH ++ } ++ /* Generate L2 prefetch if the option is open. */ ++ if (flag_sw_prefetch_sc == 1) ++ { ++ if (cst_and_fits_in_hwi (ref->group->step)) ++ { ++ delta = (ahead + ap * ref->prefetch_mod) * ++ int_cst_value (ref->group->step) * 2 ++ + (4 + convert_default_to_sw (PF2)) * L1_CACHE_LINE_SIZE; ++ ++ addr = fold_build_pointer_plus_hwi (addr_base, delta); ++ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, ++ NULL, true, GSI_SAME_STMT); ++ } ++ else ++ { ++ ahead += (unsigned) (convert_default_to_sw (PF2) ++ - convert_default_to_sw (PF1)); ++ forward = fold_build2 (MULT_EXPR, sizetype, ++ fold_convert (sizetype, ref->group->step), ++ fold_convert (sizetype, size_int (ahead))); ++ addr = fold_build_pointer_plus (addr_base, forward); ++ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, ++ NULL, true, GSI_SAME_STMT); ++ } ++ ++ if (addr_base != addr && TREE_CODE (addr_base) == SSA_NAME ++ && TREE_CODE (addr) == SSA_NAME) ++ { ++ duplicate_ssa_name_ptr_info (addr, SSA_NAME_PTR_INFO (addr_base)); ++ if (SSA_NAME_PTR_INFO (addr)) ++ mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (addr)); ++ } ++ ++ /* Create the L2 prefetch instruction. */ ++ prefetch ++ = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH_SC), ++ 3, addr, write_p, local); ++ gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT); ++ } ++ /* Generate L3 prefetch if the option is open. */ ++ if (flag_sw_prefetch_tc == 1) ++ { ++ if (cst_and_fits_in_hwi (ref->group->step)) ++ { ++ delta = (ahead + ap * ref->prefetch_mod) * ++ int_cst_value (ref->group->step) * 2 ++ + (10 + convert_default_to_sw (PF3)) * L1_CACHE_LINE_SIZE; ++ ++ addr = fold_build_pointer_plus_hwi (addr_base, delta); ++ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, ++ NULL, true, GSI_SAME_STMT); ++ } ++ else ++ { ++ ahead += (unsigned) (convert_default_to_sw (PF3) ++ - convert_default_to_sw (PF1)); ++ forward = fold_build2 (MULT_EXPR, sizetype, ++ fold_convert (sizetype, ref->group->step), ++ fold_convert (sizetype, size_int (ahead))); ++ addr = fold_build_pointer_plus (addr_base, forward); ++ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, ++ NULL, true, GSI_SAME_STMT); ++ } ++ ++ if (addr_base != addr && TREE_CODE (addr_base) == SSA_NAME ++ && TREE_CODE (addr) == SSA_NAME) ++ { ++ duplicate_ssa_name_ptr_info (addr, SSA_NAME_PTR_INFO (addr_base)); ++ if (SSA_NAME_PTR_INFO (addr)) ++ mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (addr)); ++ } ++ /* Create the L3 prefetch instruction. */ ++ prefetch ++ = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH_TC), ++ 3, addr, write_p, local); ++ gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT); ++ } ++#endif + } + } + +@@ -1375,9 +1487,22 @@ should_unroll_loop_p (class loop *loop, class tree_niter_desc *desc, + as well; but the unrolling/prefetching is usually more profitable for + loops consisting of a single basic block, and we want to limit the + code growth. */ ++#ifdef FLAG_SW64_PREFETCH ++ if (flag_sw_prefetch_unroll == 1) ++ { ++ if (loop->num_nodes > 7) ++ return false; ++ } ++ else ++ { ++ if (loop->num_nodes > 2) ++ return false; ++ } ++#else + if (loop->num_nodes > 2) + return false; + ++#endif + return true; + } + +@@ -1422,6 +1547,12 @@ determine_unroll_factor (class loop *loop, struct mem_ref_group *refs, + if (should_issue_prefetch_p (ref)) + { + mod_constraint = ref->prefetch_mod; ++#ifdef FLAG_SW64_PREFETCH ++ /* TODO: mod_constraint is set to 4 by experience, but we should do it ++ * with precision. */ ++ if (mod_constraint > upper_bound) ++ mod_constraint = 4; ++#endif + nfactor = least_common_multiple (mod_constraint, factor); + if (nfactor <= upper_bound) + factor = nfactor; +@@ -2022,6 +2153,28 @@ tree_ssa_prefetch_arrays (void) + DECL_IS_NOVOPS (decl) = true; + set_builtin_decl (BUILT_IN_PREFETCH, decl, false); + } ++#ifdef FLAG_SW64_PREFETCH ++ if (!builtin_decl_explicit_p (BUILT_IN_PREFETCH_SC)) ++ { ++ tree type = build_function_type_list (void_type_node, const_ptr_type_node, ++ NULL_TREE); ++ tree decl = add_builtin_function ("__builtin_prefetch_sc", type, ++ BUILT_IN_PREFETCH_SC, BUILT_IN_NORMAL, ++ NULL, NULL_TREE); ++ DECL_IS_NOVOPS (decl) = true; ++ set_builtin_decl (BUILT_IN_PREFETCH_SC, decl, false); ++ } ++ if (!builtin_decl_explicit_p (BUILT_IN_PREFETCH_TC)) ++ { ++ tree type = build_function_type_list (void_type_node, const_ptr_type_node, ++ NULL_TREE); ++ tree decl = add_builtin_function ("__builtin_prefetch_tc", type, ++ BUILT_IN_PREFETCH_TC, BUILT_IN_NORMAL, ++ NULL, NULL_TREE); ++ DECL_IS_NOVOPS (decl) = true; ++ set_builtin_decl (BUILT_IN_PREFETCH_TC, decl, false); ++ } ++#endif + + for (auto loop : loops_list (cfun, LI_FROM_INNERMOST)) + { +-- +2.25.1 + diff --git a/0004-Sw64-Port-update-gcc-testsuite-for-sw64.patch b/0004-Sw64-Port-update-gcc-testsuite-for-sw64.patch new file mode 100644 index 0000000000000000000000000000000000000000..e097fa3cb9ca7164faedc50b22e42b0296cb1d6c --- /dev/null +++ b/0004-Sw64-Port-update-gcc-testsuite-for-sw64.patch @@ -0,0 +1,688 @@ +From f0e14563ae35b0e0c52bed8f091a750028a42e67 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:44:09 +0800 +Subject: [PATCH 04/16] Sw64 Port: update gcc/testsuite for sw64 + +--- + contrib/compare-all-tests | 3 +- + .../c-c++-common/torture/asm-inline.c | 2 +- + gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C | 2 +- + .../g++.dg/no-stack-protector-attr-3.C | 4 +-- + gcc/testsuite/g++.dg/opt/devirt2.C | 3 +- + gcc/testsuite/g++.dg/pr49718.C | 2 +- + .../gcc.c-torture/execute/20101011-1.c | 3 ++ + gcc/testsuite/gcc.dg/20020312-2.c | 2 ++ + .../gcc.dg/atomic/c11-atomic-exec-5.c | 2 +- + gcc/testsuite/gcc.dg/attr-alloc_size-11.c | 4 +-- + gcc/testsuite/gcc.dg/cpp/assert4.c | 4 +-- + gcc/testsuite/gcc.dg/pr44194-1.c | 2 +- + gcc/testsuite/gcc.dg/stack-usage-1.c | 2 ++ + gcc/testsuite/gcc.dg/torture/restrict-8.c | 2 +- + gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c | 2 +- + gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c | 2 +- + gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c | 30 +++++++++---------- + gcc/testsuite/gcc.dg/tree-ssa/stdarg-3.c | 22 +++++++------- + gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c | 8 ++--- + gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c | 14 ++++----- + gcc/testsuite/go.test/go-test.exp | 3 ++ + gcc/testsuite/lib/target-supports.exp | 11 ++++++- + 22 files changed, 75 insertions(+), 54 deletions(-) + +diff --git a/contrib/compare-all-tests b/contrib/compare-all-tests +index 502cc64f5..02519a1f3 100644 +--- a/contrib/compare-all-tests ++++ b/contrib/compare-all-tests +@@ -33,8 +33,9 @@ ppc_opts='-m32 -m64' + s390_opts='-m31 -m31/-mzarch -m64' + sh_opts='-m3 -m3e -m4 -m4a -m4al -m4/-mieee -m1 -m1/-mno-cbranchdi -m2a -m2a/-mieee -m2e -m2e/-mieee' + sparc_opts='-mcpu=v8/-m32 -mcpu=v9/-m32 -m64' ++sw_64_opts='-mlong-double-64/-mieee -mlong-double-64 -mlong-double-128/-mieee -mlong-double-128' + +-all_targets='alpha arm avr bfin cris fr30 frv h8300 ia64 iq2000 m32c m32r m68k mcore mips mmix mn10300 pa pdp11 ppc sh sparc v850 vax xstormy16 xtensa' # e500 ++all_targets='alpha arm avr bfin cris fr30 frv h8300 ia64 iq2000 m32c m32r m68k mcore mips mmix mn10300 pa pdp11 ppc sh sparc sw_64 v850 vax xstormy16 xtensa' # e500 + + test_one_file () + { +diff --git a/gcc/testsuite/c-c++-common/torture/asm-inline.c b/gcc/testsuite/c-c++-common/torture/asm-inline.c +index dea89658b..f860b3a7b 100644 +--- a/gcc/testsuite/c-c++-common/torture/asm-inline.c ++++ b/gcc/testsuite/c-c++-common/torture/asm-inline.c +@@ -1,6 +1,6 @@ + /* { dg-do compile } */ + /* -O0 does no inlining, and -O3 does it too aggressively for this test: */ +-/* { dg-skip-if "" { *-*-* } { "-O0" "-O3" } { "" } } ++/* { dg-skip-if "" { *-*-* } { "-O0" "-O3" "-Og -g" } { "" } } + /* The normal asm is not inlined: */ + /* { dg-final { scan-assembler-times "w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w" 2 } } */ + /* But the asm inline is inlined: */ +diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C +index 424979a60..37c539a54 100644 +--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C ++++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C +@@ -1,6 +1,6 @@ + // PR c++/49673: check that test_data goes into .rodata + // { dg-do compile { target c++11 } } +-// { dg-additional-options -G0 { target { { alpha*-*-* frv*-*-* ia64-*-* lm32*-*-* m32r*-*-* microblaze*-*-* mips*-*-* loongarch*-*-* nios2-*-* powerpc*-*-* rs6000*-*-* } && { ! { *-*-darwin* *-*-aix* alpha*-*-*vms* } } } } } ++// { dg-additional-options -G0 { target { { alpha*-*-* sw_64*-*-* frv*-*-* ia64-*-* lm32*-*-* m32r*-*-* microblaze*-*-* mips*-*-* loongarch*-*-* nios2-*-* powerpc*-*-* rs6000*-*-* } && { ! { *-*-darwin* *-*-aix* alpha*-*-*vms* } } } } } + // { dg-final { scan-assembler "\\.rdata" { target mips*-*-* } } } + // { dg-final { scan-assembler "rodata" { target { { *-*-linux-gnu *-*-gnu* *-*-elf } && { ! { mips*-*-* riscv*-*-* } } } } } } + +diff --git a/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C b/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C +index 76a5ec086..982dd9856 100644 +--- a/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C ++++ b/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C +@@ -20,5 +20,5 @@ int __attribute__((stack_protect)) bar() + return 0; + } + +-/* { dg-final { scan-assembler-times "stack_chk_fail" 1 { target { ! mips*-*-* } } } }*/ +-/* { dg-final { scan-assembler-times "stack_chk_fail" 2 { target { mips*-*-* } } } }*/ ++/* { dg-final { scan-assembler-times "stack_chk_fail" 1 { target { ! { mips*-*-* sw_64*-*-* } } } } }*/ ++/* { dg-final { scan-assembler-times "stack_chk_fail" 2 { target { mips*-*-* sw_64*-*-* } } } }*/ +diff --git a/gcc/testsuite/g++.dg/opt/devirt2.C b/gcc/testsuite/g++.dg/opt/devirt2.C +index cf4842bd4..c6b5a19fa 100644 +--- a/gcc/testsuite/g++.dg/opt/devirt2.C ++++ b/gcc/testsuite/g++.dg/opt/devirt2.C +@@ -5,7 +5,7 @@ + // { dg-additional-options "-mshort-calls" {target epiphany-*-*} } + // Using -mno-abicalls avoids a R_MIPS_JALR .reloc. + // { dg-additional-options "-mno-abicalls" { target mips*-*-* } } +-// { dg-final { scan-assembler-times "xyzzy" 2 { target { ! { alpha*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* *-*-mingw* } } } } } ++// { dg-final { scan-assembler-times "xyzzy" 2 { target { ! { alpha*-*-* sw_64*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* *-*-mingw* } } } } } + // For *-*-mingw* there is additionally one .def match + // { dg-final { scan-assembler-times "xyzzy" 3 { target *-*-mingw* } } } + // The IA64 and HPPA compilers generate external declarations in addition +@@ -15,6 +15,7 @@ + // If assembler supports explicit relocation directives, the alpha compiler generates + // literal/lituse_jsr pairs, so the scans need to be more specific. + // { dg-final { scan-assembler-times "jsr\[^\n\]*xyzzy" 2 { target alpha*-*-* } } } ++// { dg-final { scan-assembler-times "call\[^\n\]*xyzzy" 2 { target sw_64*-*-* } } } + // Unless the assembler supports -relax, the 32-bit SPARC compiler generates + // sethi/jmp instead of just call, so the scans need to be more specific. + // With subexpressions, Tcl regexp -inline -all returns both the complete +diff --git a/gcc/testsuite/g++.dg/pr49718.C b/gcc/testsuite/g++.dg/pr49718.C +index b1cc5deb7..13c661642 100644 +--- a/gcc/testsuite/g++.dg/pr49718.C ++++ b/gcc/testsuite/g++.dg/pr49718.C +@@ -1,6 +1,6 @@ + /* { dg-do compile } */ + /* { dg-options "-O2 -finstrument-functions" } */ +-/* { dg-additional-options "-mno-explicit-relocs" { target alpha*-*-* } } */ ++/* { dg-additional-options "-mno-explicit-relocs" { target alpha*-*-* sw_64*-*-* } } */ + /* { dg-additional-options "-mno-relax-pic-calls" { target mips*-*-* } } */ + /* { dg-final { scan-assembler-times "__cyg_profile_func_enter" 1 { target { ! { hppa*-*-hpux* } } } } } */ + /* { dg-final { scan-assembler-times "__cyg_profile_func_enter,%r" 1 { target hppa*-*-hpux* } } } */ +diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c +index d2c0f9ab7..878be5eab 100644 +--- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c ++++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c +@@ -29,6 +29,9 @@ + #elif defined (__aarch64__) + /* On AArch64 integer division by zero does not trap. */ + # define DO_TEST 0 ++#elif defined (__sw_64__) ++ /* On sw_64 integer division by zero does not trap. */ ++# define DO_TEST 0 + #elif defined (__TMS320C6X__) + /* On TI C6X division by zero does not trap. */ + # define DO_TEST 0 +diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c +index 92bc150df..292964e02 100644 +--- a/gcc/testsuite/gcc.dg/20020312-2.c ++++ b/gcc/testsuite/gcc.dg/20020312-2.c +@@ -15,6 +15,8 @@ extern void abort (void); + + #if defined(__alpha__) + /* PIC register is $29, but is used even without -fpic. */ ++#elif defined(__sw_64__) ++/* PIC register is $29, but is used even without -fpic. */ + #elif defined(__arc__) + # define PIC_REG "26" + #elif defined(__arm__) +diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c +index 692c64ad2..2f5457645 100644 +--- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c ++++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c +@@ -24,7 +24,7 @@ + | FE_OVERFLOW \ + | FE_UNDERFLOW) + +-#if defined __alpha__ || defined __aarch64__ ++#if defined __alpha__ || defined __aarch64__ || defined __sw_64__ + #define ITER_COUNT 100 + #else + #define ITER_COUNT 10000 +diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-11.c b/gcc/testsuite/gcc.dg/attr-alloc_size-11.c +index 8332b3993..3d5a2e28a 100644 +--- a/gcc/testsuite/gcc.dg/attr-alloc_size-11.c ++++ b/gcc/testsuite/gcc.dg/attr-alloc_size-11.c +@@ -47,8 +47,8 @@ typedef __SIZE_TYPE__ size_t; + + /* The following tests fail because of missing range information. The xfail + exclusions are PR79356. */ +-TEST (signed char, SCHAR_MIN + 2, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" "missing range info for signed char" { xfail { ! { aarch64*-*-* arm*-*-* avr-*-* alpha*-*-* ia64-*-* mips*-*-* or1k*-*-* pdp11*-*-* powerpc*-*-* sparc*-*-* s390*-*-* visium-*-* msp430-*-* nvptx*-*-*} } } } */ +-TEST (short, SHRT_MIN + 2, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" "missing range info for short" { xfail { ! { aarch64*-*-* arm*-*-* alpha*-*-* avr-*-* ia64-*-* mips*-*-* or1k*-*-* pdp11*-*-* powerpc*-*-* sparc*-*-* s390x-*-* visium-*-* msp430-*-* nvptx*-*-* } } } } */ ++TEST (signed char, SCHAR_MIN + 2, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" "missing range info for signed char" { xfail { ! { aarch64*-*-* arm*-*-* avr-*-* alpha*-*-* sw_64*-*-* ia64-*-* mips*-*-* or1k*-*-* pdp11*-*-* powerpc*-*-* sparc*-*-* s390*-*-* visium-*-* msp430-*-* nvptx*-*-*} } } } */ ++TEST (short, SHRT_MIN + 2, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" "missing range info for short" { xfail { ! { aarch64*-*-* arm*-*-* alpha*-*-* sw_64*-*-* avr-*-* ia64-*-* mips*-*-* or1k*-*-* pdp11*-*-* powerpc*-*-* sparc*-*-* s390x-*-* visium-*-* msp430-*-* nvptx*-*-* } } } } */ + TEST (int, INT_MIN + 2, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" } */ + TEST (int, -3, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" } */ + TEST (int, -2, ALLOC_MAX); /* { dg-warning "argument 1 range \\\[13, \[0-9\]+\\\] exceeds maximum object size 12" } */ +diff --git a/gcc/testsuite/gcc.dg/cpp/assert4.c b/gcc/testsuite/gcc.dg/cpp/assert4.c +index 92e3dba5c..1b40ddeb6 100644 +--- a/gcc/testsuite/gcc.dg/cpp/assert4.c ++++ b/gcc/testsuite/gcc.dg/cpp/assert4.c +@@ -151,8 +151,8 @@ + || (!defined __alpha_ev4__ && #cpu(ev4)) + # error + # endif +-#elif #cpu(alpha) || #machine(alpha) || #cpu(cix) || #cpu(fix) || #cpu(bwx) \ +- || #cpu(max) || #cpu(ev6) || #cpu(ev5) || #cpu(ev4) ++#elif (#cpu(alpha) || #machine(alpha) || #cpu(cix) || #cpu(fix) || #cpu(bwx) \ ++ || #cpu(max) || #cpu(ev6) || #cpu(ev5) || #cpu(ev4)) && !#cpu(sw_64) + # error + #endif + +diff --git a/gcc/testsuite/gcc.dg/pr44194-1.c b/gcc/testsuite/gcc.dg/pr44194-1.c +index a38270b79..13709e727 100644 +--- a/gcc/testsuite/gcc.dg/pr44194-1.c ++++ b/gcc/testsuite/gcc.dg/pr44194-1.c +@@ -1,4 +1,4 @@ +-/* { dg-do compile { target { { { { { { { { { { i?86-*-* x86_64-*-* } && x32 } || lp64 } && { ! s390*-*-* } } && { ! hppa*64*-*-* } } && { ! alpha*-*-* } } && { { ! powerpc*-*-linux* } || powerpc_elfv2 } } && { ! nvptx-*-* } } } } } } */ ++/* { dg-do compile { target { { { { { { { { { { i?86-*-* x86_64-*-* } && x32 } || lp64 } && { ! s390*-*-* } } && { ! hppa*64*-*-* } } && { ! alpha*-*-* } } && { ! sw_64*-*-* } } && { { ! powerpc*-*-linux* } || powerpc_elfv2 } } && { ! nvptx-*-* } } } } } */ + /* { dg-skip-if "returns that struct in memory" { mmix-*-* } } */ + /* { dg-options "-O2 -fdump-rtl-dse1 -fdump-rtl-final" } */ + +diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c +index 21cce0f44..618be5603 100644 +--- a/gcc/testsuite/gcc.dg/stack-usage-1.c ++++ b/gcc/testsuite/gcc.dg/stack-usage-1.c +@@ -31,6 +31,8 @@ + # define SIZE 192 + #elif defined (__alpha__) + # define SIZE 240 ++#elif defined (__sw_64__) ++# define SIZE 240 + #elif defined (__ia64__) + # define SIZE 272 + #elif defined(__mips__) +diff --git a/gcc/testsuite/gcc.dg/torture/restrict-8.c b/gcc/testsuite/gcc.dg/torture/restrict-8.c +index 0118de013..7cb50980c 100644 +--- a/gcc/testsuite/gcc.dg/torture/restrict-8.c ++++ b/gcc/testsuite/gcc.dg/torture/restrict-8.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ ++/* { dg-skip-if "" { *-*-* } { "-O0" "-Og -g" } { "" } } */ + /* { dg-options "-fdump-tree-fre1" } */ + + struct S { int i; void *p; int j; }; +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c +index b9f8fd21a..ba487e689 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c +@@ -33,4 +33,4 @@ void test55 (int x, int y) + that the && should be emitted (based on BRANCH_COST). Fix this + by teaching dom to look through && and register all components + as true. */ +-/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "alpha*-*-* arm*-*-* aarch64*-*-* powerpc*-*-* cris-*-* hppa*-*-* i?86-*-* mmix-*-* mips*-*-* m68k*-*-* moxie-*-* nds32*-*-* s390*-*-* sh*-*-* sparc*-*-* visium-*-* x86_64-*-* riscv*-*-* or1k*-*-* msp430-*-* pru*-*-* nvptx*-*-*" } } } } */ ++/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "alpha*-*-* sw_64*-*-* arm*-*-* aarch64*-*-* powerpc*-*-* cris-*-* hppa*-*-* i?86-*-* mmix-*-* mips*-*-* m68k*-*-* moxie-*-* nds32*-*-* s390*-*-* sh*-*-* sparc*-*-* visium-*-* x86_64-*-* riscv*-*-* or1k*-*-* msp430-*-* pru*-*-* nvptx*-*-*" } } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c +index a879d3059..8e9391c11 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c +@@ -27,4 +27,4 @@ foo () + but the loop reads only one element at a time, and DOM cannot resolve these. + The same happens on powerpc depending on the SIMD support available. */ + +-/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { powerpc*-*-* sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } } } } } */ ++/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* sw_64*-*-* hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { powerpc*-*-* sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } } } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c +index 0224997f1..d6bda1658 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c +@@ -23,7 +23,7 @@ f1 (int i, ...) + } + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -44,7 +44,7 @@ f2 (int i, ...) + architecture or bytes on 64-bit architecture. */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 8 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 8 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -63,7 +63,7 @@ f3 (int i, ...) + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 1 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 16 FPR units" "stdarg" { target aarch64*-*-* } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 2" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target ia64-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ +@@ -79,7 +79,7 @@ f4 (int i, ...) + } + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -98,7 +98,7 @@ f5 (int i, ...) + } + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -119,7 +119,7 @@ f6 (int i, ...) + } + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 3 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -137,7 +137,7 @@ f7 (int i, ...) + } + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -157,7 +157,7 @@ f8 (int i, ...) + } + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -175,7 +175,7 @@ f9 (int i, ...) + } + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -195,7 +195,7 @@ f10 (int i, ...) + } + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -216,7 +216,7 @@ f11 (int i, ...) + } + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 3 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -237,7 +237,7 @@ f12 (int i, ...) + } + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ +-/* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 24 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 24 GPR units and 2" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and 3 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and 48 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -258,7 +258,7 @@ f13 (int i, ...) + } + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ +-/* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 24 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 24 GPR units and 2" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and 3 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and 48 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -279,7 +279,7 @@ f14 (int i, ...) + } + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[148\] GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[148\] GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ +-/* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 24 GPR units and 3" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 24 GPR units and 3" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 1 GPR units and 2 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -308,7 +308,7 @@ f15 (int i, ...) + /* { dg-final { scan-tree-dump "f15: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + + /* We may be able to improve upon this after fixing PR66010/PR66013. */ +-/* { dg-final { scan-tree-dump "f15: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f15: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + + /* { dg-final { scan-tree-dump-not "f15: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ + /* { dg-final { scan-tree-dump-not "f15: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target ia64-*-* } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-3.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-3.c +index d044654e0..d92290bb0 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-3.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-3.c +@@ -22,7 +22,7 @@ f1 (int i, ...) + } + /* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -38,7 +38,7 @@ f2 (int i, ...) + } + /* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -57,7 +57,7 @@ f3 (int i, ...) + } + /* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -74,7 +74,7 @@ f4 (int i, ...) + } + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -91,7 +91,7 @@ f5 (int i, ...) + } + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -110,7 +110,7 @@ f6 (int i, ...) + } + /* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -127,7 +127,7 @@ f7 (int i, ...) + } + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -144,7 +144,7 @@ f8 (int i, ...) + } + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -161,7 +161,7 @@ f10 (int i, ...) + } + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -178,7 +178,7 @@ f11 (int i, ...) + } + /* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -195,7 +195,7 @@ f12 (int i, ...) + } + /* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c +index 1a637d6ef..8b2f38929 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c +@@ -25,7 +25,7 @@ f1 (int i, ...) + } + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { x32 || { ! { ia32 || llp64 } } } } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -43,7 +43,7 @@ f2 (int i, ...) + } + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { x32 || { ! { ia32 || llp64 } } } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 2" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -67,7 +67,7 @@ f3 (int i, ...) + } + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +@@ -89,7 +89,7 @@ f4 (int i, ...) + } + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 8 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 8 GPR units and 2" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and 1 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and 16 FPR units" "stdarg" { target aarch64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c +index c8ad4fe32..c3eba1e21 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c +@@ -23,7 +23,7 @@ f1 (int i, ...) + va_end (ap); + } + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + +@@ -37,7 +37,7 @@ f2 (int i, ...) + va_end (ap); + } + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + +@@ -56,7 +56,7 @@ f3 (int i, ...) + } + } + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + +@@ -75,7 +75,7 @@ f4 (int i, ...) + } + } + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 16 GPR units and 16 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 2 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + +@@ -90,7 +90,7 @@ f5 (int i, ...) + bar (__real__ ci + __imag__ ci); + } + /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save (4|2) GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ + +@@ -105,7 +105,7 @@ f6 (int i, ...) + bar (__real__ ci + __imag__ cd); + } + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 32 GPR units and 3" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 32 GPR units and 3" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|2) GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target aarch64*-*-* } } } */ + +@@ -120,6 +120,6 @@ f7 (int i, ...) + bar (__real__ cd + __imag__ cd); + } + /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 0 GPR units and 64 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ +-/* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 32 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 32 GPR units and 2" "stdarg" { target alpha*-*-linux* sw_64*-*-* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 2 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 0 GPR units and 64 FPR units" "stdarg" { target aarch64*-*-* } } } */ +diff --git a/gcc/testsuite/go.test/go-test.exp b/gcc/testsuite/go.test/go-test.exp +index 11c178ad7..d405316e1 100644 +--- a/gcc/testsuite/go.test/go-test.exp ++++ b/gcc/testsuite/go.test/go-test.exp +@@ -174,6 +174,9 @@ proc go-set-goarch { } { + "alpha*-*-*" { + set goarch "alpha" + } ++ "sw_64*-*-*" { ++ set goarch "sw_64" ++ } + "arm*-*-*" - + "ep9312*-*-*" - + "strongarm*-*-*" - +diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp +index 292737dae..534405aa7 100644 +--- a/gcc/testsuite/lib/target-supports.exp ++++ b/gcc/testsuite/lib/target-supports.exp +@@ -3526,6 +3526,7 @@ proc check_effective_target_vect_cmdline_needed { } { + return [check_cached_effective_target vect_cmdline_needed { + if { [istarget alpha*-*-*] + || [istarget ia64-*-*] ++ || [istarget sw_64-*-*] + || (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && ![is-effective-target ia32]) + || ([istarget powerpc*-*-*] +@@ -3554,6 +3555,7 @@ proc check_effective_target_vect_int { } { + || [istarget amdgcn-*-*] + || [istarget sparc*-*-*] + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] +@@ -7019,6 +7021,7 @@ proc check_effective_target_vect_no_int_min_max { } { + return [check_cached_effective_target_indexed vect_no_int_min_max { + expr { [istarget sparc*-*-*] + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) }}] + } +@@ -7031,7 +7034,7 @@ proc check_effective_target_vect_no_int_min_max { } { + proc check_effective_target_vect_no_int_add { } { + # Alpha only supports vector add on V8QI and V4HI. + return [check_cached_effective_target_indexed vect_no_int_add { +- expr { [istarget alpha*-*-*] }}] ++ expr { [istarget alpha*-*-*] || [istarget sw_64*-*-*] }}] + } + + # Return 1 if the target plus current options does not support vector +@@ -8551,6 +8554,7 @@ proc check_effective_target_sync_long_long { } { + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_lp64]) + || [istarget s390*-*-*] } { + return 1 +@@ -8632,6 +8636,7 @@ proc check_effective_target_sync_long_long_runtime { } { + } + } "" ]) + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || ([istarget sparc*-*-*] + && [check_effective_target_lp64] + && [check_effective_target_ultrasparc_hw]) +@@ -8648,6 +8653,7 @@ proc check_effective_target_bswap { } { + return [check_cached_effective_target bswap { + expr { [istarget aarch64*-*-*] + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget m68k-*-*] + || [istarget powerpc*-*-*] +@@ -8672,6 +8678,7 @@ proc check_effective_target_sync_int_long { } { + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-*] +@@ -8708,6 +8715,7 @@ proc check_effective_target_sync_char_short { } { + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-*] +@@ -9149,6 +9157,7 @@ proc check_effective_target_fd_truncate { } { + + proc add_options_for_ieee { flags } { + if { [istarget alpha*-*-*] ++ || [istarget sw_64*-*-*] + || [istarget sh*-*-*] } { + return "$flags -mieee" + } +-- +2.25.1 + diff --git a/0005-Sw64-Port-libatomic.patch b/0005-Sw64-Port-libatomic.patch new file mode 100644 index 0000000000000000000000000000000000000000..182b959e68fc6803f1afe118ee6e06a6a8fa4ff8 --- /dev/null +++ b/0005-Sw64-Port-libatomic.patch @@ -0,0 +1,29 @@ +From 76693fb016acae2a7a1e130e196a5793f2b2f23b Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:50:36 +0800 +Subject: [PATCH 05/16] Sw64 Port: libatomic + +--- + libatomic/configure.tgt | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt +index 33f8c91ce..f9dbd2d35 100644 +--- a/libatomic/configure.tgt ++++ b/libatomic/configure.tgt +@@ -81,6 +81,12 @@ case "${target_cpu}" in + ARCH=sparc + ;; + ++ sw_64*) ++ # fenv.c needs this option to generate inexact exceptions. ++ XCFLAGS="${XCFLAGS} -mfp-trap-mode=sui" ++ ARCH=sw_64 ++ ;; ++ + i[3456]86 | x86_64) + cat > conftestx.c < +Date: Mon, 25 Nov 2024 16:51:15 +0800 +Subject: [PATCH 06/16] Sw64 Port: libgcc + +--- + libgcc/config.host | 18 +++ + libgcc/config/sw_64/crtfastmath.c | 36 +++++ + libgcc/config/sw_64/libgcc-sw_64-ldbl.ver | 50 ++++++ + libgcc/config/sw_64/linux-unwind.h | 103 ++++++++++++ + libgcc/config/sw_64/qrnnd.S | 181 ++++++++++++++++++++++ + libgcc/config/sw_64/t-ieee | 2 + + libgcc/config/sw_64/t-linux | 1 + + libgcc/config/sw_64/t-sw_64 | 6 + + libgcc/libgcc2.c | 2 +- + 9 files changed, 398 insertions(+), 1 deletion(-) + create mode 100644 libgcc/config/sw_64/crtfastmath.c + create mode 100644 libgcc/config/sw_64/libgcc-sw_64-ldbl.ver + create mode 100644 libgcc/config/sw_64/linux-unwind.h + create mode 100644 libgcc/config/sw_64/qrnnd.S + create mode 100644 libgcc/config/sw_64/t-ieee + create mode 100644 libgcc/config/sw_64/t-linux + create mode 100644 libgcc/config/sw_64/t-sw_64 + +diff --git a/libgcc/config.host b/libgcc/config.host +index 8c56fcae5..01cb28d2e 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -212,6 +212,9 @@ s390*-*-*) + sh[123456789lbe]*-*-*) + cpu_type=sh + ;; ++sw_64*-*-*) ++ cpu_type=sw_64 ++ ;; + tilegx*-*-*) + cpu_type=tilegx + ;; +@@ -1467,6 +1470,21 @@ sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux + ;; + sparc64-*-netbsd*) + ;; ++sw_64*-*-linux*) ++ tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee t-crtfm sw_64/t-linux" ++ extra_parts="$extra_parts crtfastmath.o" ++ md_unwind_header=sw_64/linux-unwind.h ++ ;; ++sw_64*-*-freebsd*) ++ tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee t-crtfm" ++ extra_parts="$extra_parts crtbeginT.o crtfastmath.o" ++ ;; ++sw_64*-*-netbsd*) ++ tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee" ++ ;; ++sw_64*-*-openbsd*) ++ tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee" ++ ;; + tic6x-*-uclinux) + tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp \ + c6x/t-elf c6x/t-uclinux t-crtstuff-pic t-libgcc-pic \ +diff --git a/libgcc/config/sw_64/crtfastmath.c b/libgcc/config/sw_64/crtfastmath.c +new file mode 100644 +index 000000000..aec92c819 +--- /dev/null ++++ b/libgcc/config/sw_64/crtfastmath.c +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (C) 2001-2022 Free Software Foundation, Inc. ++ * Contributed by Richard Henderson (rth@redhat.com) ++ * ++ * This file is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 3, or (at your option) any ++ * later version. ++ * ++ * This file is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * Under Section 7 of GPL version 3, you are granted additional ++ * permissions described in the GCC Runtime Library Exception, version ++ * 3.1, as published by the Free Software Foundation. ++ * ++ * You should have received a copy of the GNU General Public License and ++ * a copy of the GCC Runtime Library Exception along with this program; ++ * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ * . ++ */ ++ ++/* Assume SYSV/1 compatible interfaces. */ ++ ++extern void ++__ieee_set_fp_control (unsigned long int); ++ ++#define IEEE_MAP_DMZ (1UL << 12) /* Map denorm inputs to zero */ ++#define IEEE_MAP_UMZ (1UL << 13) /* Map underflowed outputs to zero */ ++ ++static void __attribute__ ((constructor)) set_fast_math (void) ++{ ++ __ieee_set_fp_control (IEEE_MAP_DMZ | IEEE_MAP_UMZ); ++} +diff --git a/libgcc/config/sw_64/libgcc-sw_64-ldbl.ver b/libgcc/config/sw_64/libgcc-sw_64-ldbl.ver +new file mode 100644 +index 000000000..6666bc639 +--- /dev/null ++++ b/libgcc/config/sw_64/libgcc-sw_64-ldbl.ver +@@ -0,0 +1,50 @@ ++# Copyright (C) 2006-2019 Free Software Foundation, Inc. ++# ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . ++ ++%ifdef __LONG_DOUBLE_128__ ++ ++# long double 128 bit support in libgcc_s.so.1 is only available ++# when configured with --with-long-double-128. Make sure all the ++# symbols are available at @@GCC_LDBL_* versions to make it clear ++# there is a configurable symbol set. ++ ++%exclude { ++ __fixtfdi ++ __fixunstfdi ++ __floatditf ++ ++ __divtc3 ++ __multc3 ++ __powitf2 ++} ++ ++%inherit GCC_LDBL_3.0 GCC_3.0 ++GCC_LDBL_3.0 { ++ __fixtfdi ++ __fixunstfdi ++ __floatditf ++} ++ ++%inherit GCC_LDBL_4.0.0 GCC_4.0.0 ++GCC_LDBL_4.0.0 { ++ __divtc3 ++ __multc3 ++ __powitf2 ++} ++ ++%endif +diff --git a/libgcc/config/sw_64/linux-unwind.h b/libgcc/config/sw_64/linux-unwind.h +new file mode 100644 +index 000000000..d446c123f +--- /dev/null ++++ b/libgcc/config/sw_64/linux-unwind.h +@@ -0,0 +1,103 @@ ++/* DWARF2 EH unwinding support for Sw_64 Linux. ++ Copyright (C) 2004-2022 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++Under Section 7 of GPL version 3, you are granted additional ++permissions described in the GCC Runtime Library Exception, version ++3.1, as published by the Free Software Foundation. ++ ++You should have received a copy of the GNU General Public License and ++a copy of the GCC Runtime Library Exception along with this program; ++see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++. */ ++ ++#ifndef inhibit_libc ++/* Do code reading to identify a signal frame, and set the frame ++ state data appropriately. See unwind-dw2.c for the structs. */ ++ ++#include ++#include ++ ++#define MD_FALLBACK_FRAME_STATE_FOR sw_64_fallback_frame_state ++ ++static _Unwind_Reason_Code ++sw_64_fallback_frame_state (struct _Unwind_Context *context, ++ _Unwind_FrameState *fs) ++{ ++ unsigned int *pc = context->ra; ++ struct sigcontext *sc; ++ long new_cfa; ++ int i; ++ ++ if (pc[0] != 0x47fe0410 /* mov $30,$16 */ ++ || pc[2] != 0x00000083) /* callsys */ ++ return _URC_END_OF_STACK; ++ if (context->cfa == 0) ++ return _URC_END_OF_STACK; ++ if (pc[1] == 0x201f0067) /* lda $0,NR_sigreturn */ ++ sc = context->cfa; ++ else if (pc[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ ++ { ++ struct rt_sigframe ++ { ++ siginfo_t info; ++ ucontext_t uc; ++ } *rt_ = context->cfa; ++ /* The void * cast is necessary to avoid an aliasing warning. ++ The aliasing warning is correct, but should not be a problem ++ because it does not alias anything. */ ++ sc = (struct sigcontext *) (void *) &rt_->uc.uc_mcontext; ++ } ++ else ++ return _URC_END_OF_STACK; ++ ++ new_cfa = sc->sc_regs[30]; ++ fs->regs.cfa_how = CFA_REG_OFFSET; ++ fs->regs.cfa_reg = 30; ++ fs->regs.cfa_offset = new_cfa - (long) context->cfa; ++ for (i = 0; i < 30; ++i) ++ { ++ fs->regs.reg[i].how = REG_SAVED_OFFSET; ++ fs->regs.reg[i].loc.offset = (long) &sc->sc_regs[i] - new_cfa; ++ } ++ for (i = 0; i < 31; ++i) ++ { ++ fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; ++ fs->regs.reg[i + 32].loc.offset = (long) &sc->sc_fpregs[i] - new_cfa; ++ } ++ fs->regs.reg[64].how = REG_SAVED_OFFSET; ++ fs->regs.reg[64].loc.offset = (long) &sc->sc_pc - new_cfa; ++ fs->retaddr_column = 64; ++ fs->signal_frame = 1; ++ ++ return _URC_NO_REASON; ++} ++ ++#define MD_FROB_UPDATE_CONTEXT sw_64_frob_update_context ++ ++/* Fix up for signal handlers that don't have S flag set. */ ++ ++static void ++sw_64_frob_update_context (struct _Unwind_Context *context, ++ _Unwind_FrameState *fs ATTRIBUTE_UNUSED) ++{ ++ unsigned int *pc = context->ra; ++ ++ if (pc[0] == 0x47fe0410 /* mov $30,$16 */ ++ && pc[2] == 0x00000083 /* callsys */ ++ && (pc[1] == 0x201f0067 /* lda $0,NR_sigreturn */ ++ || pc[1] == 0x201f015f)) /* lda $0,NR_rt_sigreturn */ ++ _Unwind_SetSignalFrame (context, 1); ++} ++#endif +diff --git a/libgcc/config/sw_64/qrnnd.S b/libgcc/config/sw_64/qrnnd.S +new file mode 100644 +index 000000000..ab2e3d0bc +--- /dev/null ++++ b/libgcc/config/sw_64/qrnnd.S +@@ -0,0 +1,181 @@ ++ # Sw_64 __udiv_qrnnd ++ # Copyright (C) 1992-2022 Free Software Foundation, Inc. ++ ++ # This file is part of GCC. ++ ++ # The GNU MP Library is free software; you can redistribute it and/or modify ++ # it under the terms of the GNU General Public License as published by ++ # the Free Software Foundation; either version 3 of the License, or (at your ++ # option) any later version. ++ ++ # This file is distributed in the hope that it will be useful, but ++ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ # License for more details. ++ ++ # Under Section 7 of GPL version 3, you are granted additional ++ # permissions described in the GCC Runtime Library Exception, version ++ # 3.1, as published by the Free Software Foundation. ++ ++ # You should have received a copy of the GNU General Public License and ++ # a copy of the GCC Runtime Library Exception along with this program; ++ # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ # . ++ ++#ifdef __ELF__ ++.section .note.GNU-stack,"" ++#endif ++ ++ .set noreorder ++ .set noat ++ ++ .text ++ ++ .globl __udiv_qrnnd ++ .ent __udiv_qrnnd ++#ifdef __VMS__ ++__udiv_qrnnd..en: ++ .frame $29,0,$26,0 ++ .prologue ++#else ++__udiv_qrnnd: ++ .frame $30,0,$26,0 ++ .prologue 0 ++#endif ++/* ++ ldiq -> ldi ++ addq->addl ++ subq->subl ++ cmovne qb,tmp,n1->selne qb,tmp,n1,n1 ++ stq ->stl ++ cmoveq tmp,AT,n1(n0)->seleq tmp,AT,n1,n1(n0,n0) */ ++#define cnt $2 ++#define tmp $3 ++#define rem_ptr $16 ++#define n1 $17 ++#define n0 $18 ++#define d $19 ++#define qb $20 ++#define AT $at ++ ++ ldi cnt,16 ++ blt d,$largedivisor ++ ++$loop1: cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule d,n1,qb ++ subl n1,d,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule d,n1,qb ++ subl n1,d,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule d,n1,qb ++ subl n1,d,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule d,n1,qb ++ subl n1,d,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ subl cnt,1,cnt ++ bgt cnt,$loop1 ++ stl n1,0(rem_ptr) ++ bis $31,n0,$0 ++ ret $31,($26),1 ++ ++$largedivisor: ++ and n0,1,$4 ++ ++ srl n0,1,n0 ++ sll n1,63,tmp ++ or tmp,n0,n0 ++ srl n1,1,n1 ++ ++ and d,1,$6 ++ srl d,1,$5 ++ addl $5,$6,$5 ++ ++$loop2: cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule $5,n1,qb ++ subl n1,$5,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule $5,n1,qb ++ subl n1,$5,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule $5,n1,qb ++ subl n1,$5,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addl n1,n1,n1 ++ bis n1,tmp,n1 ++ addl n0,n0,n0 ++ cmpule $5,n1,qb ++ subl n1,$5,tmp ++ selne qb,tmp,n1,n1 ++ bis n0,qb,n0 ++ subl cnt,1,cnt ++ bgt cnt,$loop2 ++ ++ addl n1,n1,n1 ++ addl $4,n1,n1 ++ bne $6,$Odd ++ stl n1,0(rem_ptr) ++ bis $31,n0,$0 ++ ret $31,($26),1 ++ ++$Odd: ++ /* q' in n0. r' in n1 */ ++ addl n1,n0,n1 ++ ++ cmpult n1,n0,tmp # tmp := carry from addl ++ subl n1,d,AT ++ addl n0,tmp,n0 ++ selne tmp,AT,n1,n1 ++ ++ cmpult n1,d,tmp ++ addl n0,1,AT ++ seleq tmp,AT,n0,n0 ++ subl n1,d,AT ++ seleq tmp,AT,n1,n1 ++ ++ stl n1,0(rem_ptr) ++ bis $31,n0,$0 ++ ret $31,($26),1 ++ ++#ifdef __VMS__ ++ .link ++ .align 3 ++__udiv_qrnnd: ++ .pdesc __udiv_qrnnd..en,null ++#endif ++ .end __udiv_qrnnd +diff --git a/libgcc/config/sw_64/t-ieee b/libgcc/config/sw_64/t-ieee +new file mode 100644 +index 000000000..9b66e50ac +--- /dev/null ++++ b/libgcc/config/sw_64/t-ieee +@@ -0,0 +1,2 @@ ++# All sw_64s get an IEEE complaint set of libraries. ++#HOST_LIBGCC2_CFLAGS += -mieee +diff --git a/libgcc/config/sw_64/t-linux b/libgcc/config/sw_64/t-linux +new file mode 100644 +index 000000000..fe9d20e9a +--- /dev/null ++++ b/libgcc/config/sw_64/t-linux +@@ -0,0 +1 @@ ++SHLIB_MAPFILES += $(srcdir)/config/sw_64/libgcc-sw_64-ldbl.ver +diff --git a/libgcc/config/sw_64/t-sw_64 b/libgcc/config/sw_64/t-sw_64 +new file mode 100644 +index 000000000..dffba8ee7 +--- /dev/null ++++ b/libgcc/config/sw_64/t-sw_64 +@@ -0,0 +1,6 @@ ++# This is a support routine for longlong.h, used by libgcc2.c. ++LIB2ADD += $(srcdir)/config/sw_64/qrnnd.S ++ ++# When GAS-generated unwind tables are created, they get created ++# after the __FRAME_END__ terminator, which causes an ld error. ++CRTSTUFF_T_CFLAGS = -fno-unwind-tables +diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c +index 3ebfcc83f..f01a150c4 100644 +--- a/libgcc/libgcc2.c ++++ b/libgcc/libgcc2.c +@@ -2280,7 +2280,7 @@ int mprotect (char *,int, int); + int + getpagesize (void) + { +-#ifdef _ALPHA_ ++#ifdef _ALPHA_ || defined _SW_64_ + return 8192; + #else + return 4096; +-- +2.25.1 + diff --git a/0007-Sw64-Port-libffi.patch b/0007-Sw64-Port-libffi.patch new file mode 100644 index 0000000000000000000000000000000000000000..625243d924ad5cedff4d8659c1f818cbff5c9b97 --- /dev/null +++ b/0007-Sw64-Port-libffi.patch @@ -0,0 +1,1054 @@ +From c66eadc032d38205bdf9b53b8580ffcba9623270 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:51:39 +0800 +Subject: [PATCH 07/16] Sw64 Port: libffi + +--- + libffi/Makefile.in | 23 +- + libffi/configure.host | 7 + + libffi/src/sw_64/ffi.c | 516 +++++++++++++++++++++++++++++++++++ + libffi/src/sw_64/ffitarget.h | 60 ++++ + libffi/src/sw_64/internal.h | 23 ++ + libffi/src/sw_64/sysv.S | 281 +++++++++++++++++++ + libffi/src/types.c | 4 +- + 7 files changed, 910 insertions(+), 4 deletions(-) + create mode 100644 libffi/src/sw_64/ffi.c + create mode 100644 libffi/src/sw_64/ffitarget.h + create mode 100644 libffi/src/sw_64/internal.h + create mode 100644 libffi/src/sw_64/sysv.S + +diff --git a/libffi/Makefile.in b/libffi/Makefile.in +index 5524a6a57..217ce305e 100644 +--- a/libffi/Makefile.in ++++ b/libffi/Makefile.in +@@ -548,6 +548,7 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ + src/s390/ffitarget.h src/s390/internal.h src/sh/ffitarget.h \ + src/sh64/ffitarget.h src/sparc/ffitarget.h \ + src/sparc/internal.h src/tile/ffitarget.h src/vax/ffitarget.h \ ++ src/sw_64/ffitarget.h src/sw_64/internal.h \ + src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h \ + src/x86/asmnames.h src/xtensa/ffitarget.h src/dlmalloc.c \ + src/kvx/ffitarget.h +@@ -576,6 +577,7 @@ EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \ + src/s390/sysv.S src/sh/ffi.c src/sh/sysv.S src/sh64/ffi.c \ + src/sh64/sysv.S src/sparc/ffi.c src/sparc/ffi64.c \ + src/sparc/v8.S src/sparc/v9.S src/tile/ffi.c src/tile/tile.S \ ++ src/sw_64/ffi.c src/sw_64/sysv.S \ + src/vax/ffi.c src/vax/elfbsd.S src/x86/ffi.c src/x86/sysv.S \ + src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \ + src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \ +@@ -1012,6 +1014,16 @@ src/sparc/v8.lo: src/sparc/$(am__dirstamp) \ + src/sparc/$(DEPDIR)/$(am__dirstamp) + src/sparc/v9.lo: src/sparc/$(am__dirstamp) \ + src/sparc/$(DEPDIR)/$(am__dirstamp) ++src/sw_64/$(am__dirstamp): ++ @$(MKDIR_P) src/sw_64 ++ @: > src/sw_64/$(am__dirstamp) ++src/sw_64/$(DEPDIR)/$(am__dirstamp): ++ @$(MKDIR_P) src/sw_64/$(DEPDIR) ++ @: > src/sw_64/$(DEPDIR)/$(am__dirstamp) ++src/sw_64/ffi.lo: src/sw_64/$(am__dirstamp) \ ++ src/sw_64/$(DEPDIR)/$(am__dirstamp) ++src/sw_64/sysv.lo: src/sw_64/$(am__dirstamp) \ ++ src/sw_64/$(DEPDIR)/$(am__dirstamp) + src/tile/$(am__dirstamp): + @$(MKDIR_P) src/tile + @: > src/tile/$(am__dirstamp) +@@ -1139,6 +1151,8 @@ mostlyclean-compile: + -rm -f src/sh64/*.lo + -rm -f src/sparc/*.$(OBJEXT) + -rm -f src/sparc/*.lo ++ -rm -f src/sw_64/*.$(OBJEXT) ++ -rm -f src/sw_64/*.lo + -rm -f src/tile/*.$(OBJEXT) + -rm -f src/tile/*.lo + -rm -f src/vax/*.$(OBJEXT) +@@ -1228,6 +1242,8 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/ffi64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v8.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@src/sw_64/$(DEPDIR)/ffi.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@src/sw_64/$(DEPDIR)/sysv.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/ffi.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/tile.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/vax/$(DEPDIR)/elfbsd.Plo@am__quote@ +@@ -1324,6 +1340,7 @@ clean-libtool: + -rm -rf src/sh/.libs src/sh/_libs + -rm -rf src/sh64/.libs src/sh64/_libs + -rm -rf src/sparc/.libs src/sparc/_libs ++ -rm -rf src/sw_64/.libs src/sw_64/_libs + -rm -rf src/tile/.libs src/tile/_libs + -rm -rf src/vax/.libs src/vax/_libs + -rm -rf src/x86/.libs src/x86/_libs +@@ -1690,6 +1707,8 @@ distclean-generic: + -rm -f src/sh64/$(am__dirstamp) + -rm -f src/sparc/$(DEPDIR)/$(am__dirstamp) + -rm -f src/sparc/$(am__dirstamp) ++ -rm -f src/sw_64/$(DEPDIR)/$(am__dirstamp) ++ -rm -f src/sw_64/$(am__dirstamp) + -rm -f src/tile/$(DEPDIR)/$(am__dirstamp) + -rm -f src/tile/$(am__dirstamp) + -rm -f src/vax/$(DEPDIR)/$(am__dirstamp) +@@ -1712,7 +1731,7 @@ clean-am: clean-aminfo clean-generic clean-libtool clean-local \ + + distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) +- -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/csky/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/kvx/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/or1k/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/riscv/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) ++ -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/csky/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/kvx/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/or1k/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/riscv/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/sw_64/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) + -rm -f Makefile + distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-local distclean-tags +@@ -1851,7 +1870,7 @@ installcheck-am: + maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache +- -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/csky/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/kvx/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/or1k/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/riscv/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) ++ -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/csky/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/kvx/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/or1k/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/riscv/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/sw_64/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) + -rm -f Makefile + maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic maintainer-clean-local \ +diff --git a/libffi/configure.host b/libffi/configure.host +index 268267183..200f2d415 100644 +--- a/libffi/configure.host ++++ b/libffi/configure.host +@@ -247,6 +247,13 @@ case "${host}" in + SOURCES="ffi.c ffi64.c v8.S v9.S" + ;; + ++ sw_64*-*-*) ++ TARGET=SW_64; TARGETDIR=sw_64; ++ # Support 128-bit long double, changeable via command-line switch. ++ HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' ++ SOURCES="ffi.c sysv.S" ++ ;; ++ + tile*-*) + TARGET=TILE; TARGETDIR=tile + SOURCES="ffi.c tile.S" +diff --git a/libffi/src/sw_64/ffi.c b/libffi/src/sw_64/ffi.c +new file mode 100644 +index 000000000..2accc48ad +--- /dev/null ++++ b/libffi/src/sw_64/ffi.c +@@ -0,0 +1,516 @@ ++/* ----------------------------------------------------------------------- ++ ffi.c - Copyright (c) 2012 Anthony Green ++ Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc. ++ Copyright (c) 2023, Wxiat ++ Sunway Foreign Function Interface ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ----------------------------------------------------------------------- */ ++ ++#include ++#include ++#include ++#include "internal.h" ++ ++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; ++ all further uses in this file will refer to the 128-bit type. */ ++#if defined(__LONG_DOUBLE_128__) ++#if FFI_TYPE_LONGDOUBLE != 4 ++#error FFI_TYPE_LONGDOUBLE out of date ++#endif ++#else ++#undef FFI_TYPE_LONGDOUBLE ++#define FFI_TYPE_LONGDOUBLE 4 ++#endif ++ ++extern void ++ffi_call_sysv (void *stack, void *frame, unsigned flags, void *raddr, ++ void (*fn) (void), void *closure) FFI_HIDDEN; ++extern void ++ffi_closure_sysv (void) FFI_HIDDEN; ++extern void ++ffi_go_closure_sysv (void) FFI_HIDDEN; ++ ++/* Promote a float value to its in-register double representation. ++ Unlike actually casting to double, this does not trap on NaN. */ ++static inline UINT64 ++lds (void *ptr) ++{ ++ UINT64 ret; ++ asm ("flds %0,%1" : "=f"(ret) : "m"(*(UINT32 *) ptr)); ++ return ret; ++} ++ ++/* And the reverse. */ ++static inline void ++sts (void *ptr, UINT64 val) ++{ ++ asm ("fsts %1,%0" : "=m"(*(UINT32 *) ptr) : "f"(val)); ++} ++ ++ffi_status FFI_HIDDEN ++ffi_prep_cif_machdep (ffi_cif *cif) ++{ ++ size_t bytes = 0; ++ int flags, i, avn; ++ ffi_type *rtype, *itype; ++ ++ if (cif->abi != FFI_OSF) ++ return FFI_BAD_ABI; ++ ++ /* Compute the size of the argument area. */ ++ for (i = 0, avn = cif->nargs; i < avn; i++) ++ { ++ itype = cif->arg_types[i]; ++ switch (itype->type) ++ { ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ case FFI_TYPE_FLOAT: ++ case FFI_TYPE_DOUBLE: ++ case FFI_TYPE_LONGDOUBLE: ++ /* All take one 8 byte slot. */ ++ bytes += 8; ++ break; ++ ++ case FFI_TYPE_VOID: ++ case FFI_TYPE_STRUCT: ++ /* Passed by value in N slots. */ ++ bytes += FFI_ALIGN (itype->size, FFI_SIZEOF_ARG); ++ break; ++ ++ case FFI_TYPE_COMPLEX: ++ /* _Complex long double passed by reference; others in 2 slots. */ ++ if (itype->elements[0]->type == FFI_TYPE_LONGDOUBLE) ++ bytes += 8; ++ else ++ bytes += 16; ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ ++ /* Set the return type flag */ ++ rtype = cif->rtype; ++ switch (rtype->type) ++ { ++ case FFI_TYPE_VOID: ++ flags = SW_64_FLAGS (SW_64_ST_VOID, SW_64_LD_VOID); ++ break; ++ case FFI_TYPE_INT: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT32: ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_INT32); ++ break; ++ case FFI_TYPE_FLOAT: ++ flags = SW_64_FLAGS (SW_64_ST_FLOAT, SW_64_LD_FLOAT); ++ break; ++ case FFI_TYPE_DOUBLE: ++ flags = SW_64_FLAGS (SW_64_ST_DOUBLE, SW_64_LD_DOUBLE); ++ break; ++ case FFI_TYPE_UINT8: ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_UINT8); ++ break; ++ case FFI_TYPE_SINT8: ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_SINT8); ++ break; ++ case FFI_TYPE_UINT16: ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_UINT16); ++ break; ++ case FFI_TYPE_SINT16: ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_SINT16); ++ break; ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_POINTER: ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_INT64); ++ break; ++ case FFI_TYPE_LONGDOUBLE: ++ case FFI_TYPE_STRUCT: ++ /* Passed in memory, with a hidden pointer. */ ++ flags = SW_64_RET_IN_MEM; ++ break; ++ case FFI_TYPE_COMPLEX: ++ itype = rtype->elements[0]; ++ switch (itype->type) ++ { ++ case FFI_TYPE_FLOAT: ++ flags = SW_64_FLAGS (SW_64_ST_CPLXF, SW_64_LD_CPLXF); ++ break; ++ case FFI_TYPE_DOUBLE: ++ flags = SW_64_FLAGS (SW_64_ST_CPLXD, SW_64_LD_CPLXD); ++ break; ++ default: ++ if (rtype->size <= 8) ++ flags = SW_64_FLAGS (SW_64_ST_INT, SW_64_LD_INT64); ++ else ++ flags = SW_64_RET_IN_MEM; ++ break; ++ } ++ break; ++ default: ++ abort (); ++ } ++ cif->flags = flags; ++ ++ /* Include the hidden structure pointer in args requirement. */ ++ if (flags == SW_64_RET_IN_MEM) ++ bytes += 8; ++ /* Minimum size is 6 slots, so that ffi_call_sysv can pop them. */ ++ if (bytes < 6 * 8) ++ bytes = 6 * 8; ++ cif->bytes = bytes; ++ ++ return FFI_OK; ++} ++ ++static unsigned long ++extend_basic_type (void *valp, int type, int argn) ++{ ++ switch (type) ++ { ++ case FFI_TYPE_SINT8: ++ return *(SINT8 *) valp; ++ case FFI_TYPE_UINT8: ++ return *(UINT8 *) valp; ++ case FFI_TYPE_SINT16: ++ return *(SINT16 *) valp; ++ case FFI_TYPE_UINT16: ++ return *(UINT16 *) valp; ++ ++ case FFI_TYPE_FLOAT: ++ if (argn < 6) ++ return lds (valp); ++ /* FALLTHRU */ ++ ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ /* Note that unsigned 32-bit quantities are sign extended. */ ++ return *(SINT32 *) valp; ++ ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ case FFI_TYPE_DOUBLE: ++ return *(UINT64 *) valp; ++ ++ default: ++ abort (); ++ } ++} ++ ++static void ++ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, ++ void *closure) ++{ ++ unsigned long *argp; ++ long i, avn, argn, flags = cif->flags; ++ ffi_type **arg_types; ++ void *frame; ++ ++ /* If the return value is a struct and we don't have a return ++ value address then we need to make one. */ ++ if (rvalue == NULL && flags == SW_64_RET_IN_MEM) ++ rvalue = alloca (cif->rtype->size); ++ ++ /* Allocate the space for the arguments, plus 4 words of temp ++ space for ffi_call_sysv. */ ++ argp = frame = alloca (cif->bytes + 4 * FFI_SIZEOF_ARG); ++ frame += cif->bytes; ++ ++ argn = 0; ++ if (flags == SW_64_RET_IN_MEM) ++ argp[argn++] = (unsigned long) rvalue; ++ ++ avn = cif->nargs; ++ arg_types = cif->arg_types; ++ ++ for (i = 0, avn = cif->nargs; i < avn; i++) ++ { ++ ffi_type *ty = arg_types[i]; ++ void *valp = avalue[i]; ++ int type = ty->type; ++ size_t size; ++ ++ switch (type) ++ { ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ case FFI_TYPE_FLOAT: ++ case FFI_TYPE_DOUBLE: ++ argp[argn] = extend_basic_type (valp, type, argn); ++ argn++; ++ break; ++ ++ case FFI_TYPE_LONGDOUBLE: ++ by_reference: ++ /* Note that 128-bit long double is passed by reference. */ ++ argp[argn++] = (unsigned long) valp; ++ break; ++ ++ case FFI_TYPE_VOID: ++ case FFI_TYPE_STRUCT: ++ size = ty->size; ++ memcpy (argp + argn, valp, size); ++ argn += FFI_ALIGN (size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; ++ break; ++ ++ case FFI_TYPE_COMPLEX: ++ type = ty->elements[0]->type; ++ if (type == FFI_TYPE_LONGDOUBLE) ++ goto by_reference; ++ ++ /* Most complex types passed as two separate arguments. */ ++ size = ty->elements[0]->size; ++ argp[argn] = extend_basic_type (valp, type, argn); ++ argp[argn + 1] = extend_basic_type (valp + size, type, argn + 1); ++ argn += 2; ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ ++ flags = (flags >> SW_64_ST_SHIFT) & 0xff; ++ ffi_call_sysv (argp, frame, flags, rvalue, fn, closure); ++} ++ ++void ++ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) ++{ ++ ffi_call_int (cif, fn, rvalue, avalue, NULL); ++} ++ ++void ++ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, ++ void *closure) ++{ ++ ffi_call_int (cif, fn, rvalue, avalue, closure); ++} ++ ++ffi_status ++ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, ++ void (*fun) (ffi_cif *, void *, void **, void *), ++ void *user_data, void *codeloc) ++{ ++ unsigned int *tramp; ++ ++ if (cif->abi != FFI_OSF) ++ return FFI_BAD_ABI; ++ ++ tramp = (unsigned int *) &closure->tramp[0]; ++ tramp[0] = 0x43fb0741; /* mov $27,$1 */ ++ tramp[1] = 0x8f7b0010; /* ldl $27,16($27) */ ++ tramp[2] = 0x0ffb0000; /* jmp $31,($27),0 */ ++ tramp[3] = 0x43ff075f; /* nop */ ++ *(void **) &tramp[4] = ffi_closure_sysv; ++ ++ closure->cif = cif; ++ closure->fun = fun; ++ closure->user_data = user_data; ++ ++ /* Flush the Icache. 0x86 is PAL_imb in Tru64 UNIX . */ ++ asm volatile ("sys_call 0x86" : : : "memory"); ++ ++ return FFI_OK; ++} ++ ++ffi_status ++ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif, ++ void (*fun) (ffi_cif *, void *, void **, void *)) ++{ ++ if (cif->abi != FFI_OSF) ++ return FFI_BAD_ABI; ++ ++ closure->tramp = (void *) ffi_go_closure_sysv; ++ closure->cif = cif; ++ closure->fun = fun; ++ ++ return FFI_OK; ++} ++ ++long FFI_HIDDEN ++ffi_closure_sysv_inner (ffi_cif *cif, ++ void (*fun) (ffi_cif *, void *, void **, void *), ++ void *user_data, void *rvalue, unsigned long *argp) ++{ ++ void **avalue; ++ ffi_type **arg_types; ++ long i, avn, argn, flags; ++ ++ avalue = alloca (cif->nargs * sizeof (void *)); ++ flags = cif->flags; ++ argn = 0; ++ ++ /* Copy the caller's structure return address to that the closure ++ returns the data directly to the caller. */ ++ if (flags == SW_64_RET_IN_MEM) ++ { ++ rvalue = (void *) argp[0]; ++ argn = 1; ++ } ++ ++ arg_types = cif->arg_types; ++ ++ /* Grab the addresses of the arguments from the stack frame. */ ++ for (i = 0, avn = cif->nargs; i < avn; i++) ++ { ++ ffi_type *ty = arg_types[i]; ++ int type = ty->type; ++ void *valp = &argp[argn]; ++ size_t size; ++ ++ switch (type) ++ { ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_VOID: ++ case FFI_TYPE_STRUCT: ++ size = ty->size; ++ argn += FFI_ALIGN (size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; ++ break; ++ ++ case FFI_TYPE_FLOAT: ++ /* Floats coming from registers need conversion from double ++ back to float format. */ ++ if (argn < 6) ++ { ++ valp = &argp[argn - 6]; ++ sts (valp, argp[argn - 6]); ++ } ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_DOUBLE: ++ if (argn < 6) ++ valp = &argp[argn - 6]; ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_LONGDOUBLE: ++ by_reference: ++ /* 128-bit long double is passed by reference. */ ++ valp = (void *) argp[argn]; ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_COMPLEX: ++ type = ty->elements[0]->type; ++ switch (type) ++ { ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ /* Passed as separate arguments, but they wind up sequential. */ ++ break; ++ ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ /* Passed as separate arguments. Disjoint, but there's room ++ enough in one slot to hold the pair. */ ++ size = ty->elements[0]->size; ++ memcpy (valp + size, valp + 8, size); ++ break; ++ ++ case FFI_TYPE_FLOAT: ++ /* Passed as separate arguments. Disjoint, and each piece ++ may need conversion back to float. */ ++ if (argn < 6) ++ { ++ valp = &argp[argn - 6]; ++ sts (valp, argp[argn - 6]); ++ } ++ if (argn + 1 < 6) ++ sts (valp + 4, argp[argn + 1 - 6]); ++ else ++ *(UINT32 *) (valp + 4) = argp[argn + 1]; ++ break; ++ ++ case FFI_TYPE_DOUBLE: ++ /* Passed as separate arguments. Only disjoint if one part ++ is in fp regs and the other is on the stack. */ ++ if (argn < 5) ++ valp = &argp[argn - 6]; ++ else if (argn == 5) ++ { ++ valp = alloca (16); ++ ((UINT64 *) valp)[0] = argp[5 - 6]; ++ ((UINT64 *) valp)[1] = argp[6]; ++ } ++ break; ++ ++ case FFI_TYPE_LONGDOUBLE: ++ goto by_reference; ++ ++ default: ++ abort (); ++ } ++ argn += 2; ++ break; ++ ++ default: ++ abort (); ++ } ++ ++ avalue[i] = valp; ++ } ++ ++ /* Invoke the closure. */ ++ fun (cif, rvalue, avalue, user_data); ++ ++ /* Tell ffi_closure_sysv how to perform return type promotions. */ ++ return (flags >> SW_64_LD_SHIFT) & 0xff; ++} +diff --git a/libffi/src/sw_64/ffitarget.h b/libffi/src/sw_64/ffitarget.h +new file mode 100644 +index 000000000..4ea1493c5 +--- /dev/null ++++ b/libffi/src/sw_64/ffitarget.h +@@ -0,0 +1,60 @@ ++/* -----------------------------------------------------------------*-C-*- ++ ffitarget.h - Copyright (c) 2012 Anthony Green ++ Copyright (c) 1996-2003 Red Hat, Inc. ++ Copyright (c) 2023, Wxiat ++ Target configuration macros for Sunway. ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ++ ----------------------------------------------------------------------- */ ++ ++#ifndef LIBFFI_TARGET_H ++#define LIBFFI_TARGET_H ++ ++#ifndef LIBFFI_H ++#error \ ++ "Please do not include ffitarget.h directly into your source. Use ffi.h instead." ++#endif ++ ++#ifndef LIBFFI_ASM ++typedef unsigned long ffi_arg; ++typedef signed long ffi_sarg; ++ ++typedef enum ffi_abi ++{ ++ FFI_FIRST_ABI = 0, ++ FFI_OSF, ++ FFI_LAST_ABI, ++ FFI_DEFAULT_ABI = FFI_OSF ++} ffi_abi; ++#endif ++ ++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION ++#define FFI_TARGET_HAS_COMPLEX_TYPE ++ ++/* ---- Definitions for closures ----------------------------------------- */ ++ ++#define FFI_CLOSURES 1 ++#define FFI_GO_CLOSURES 1 ++#define FFI_TRAMPOLINE_SIZE 24 ++#define FFI_NATIVE_RAW_API 0 ++ ++#endif +diff --git a/libffi/src/sw_64/internal.h b/libffi/src/sw_64/internal.h +new file mode 100644 +index 000000000..92ad32179 +--- /dev/null ++++ b/libffi/src/sw_64/internal.h +@@ -0,0 +1,23 @@ ++#define SW_64_ST_VOID 0 ++#define SW_64_ST_INT 1 ++#define SW_64_ST_FLOAT 2 ++#define SW_64_ST_DOUBLE 3 ++#define SW_64_ST_CPLXF 4 ++#define SW_64_ST_CPLXD 5 ++ ++#define SW_64_LD_VOID 0 ++#define SW_64_LD_INT64 1 ++#define SW_64_LD_INT32 2 ++#define SW_64_LD_UINT16 3 ++#define SW_64_LD_SINT16 4 ++#define SW_64_LD_UINT8 5 ++#define SW_64_LD_SINT8 6 ++#define SW_64_LD_FLOAT 7 ++#define SW_64_LD_DOUBLE 8 ++#define SW_64_LD_CPLXF 9 ++#define SW_64_LD_CPLXD 10 ++ ++#define SW_64_ST_SHIFT 0 ++#define SW_64_LD_SHIFT 8 ++#define SW_64_RET_IN_MEM 0x10000 ++#define SW_64_FLAGS(S, L) (((L) << SW_64_LD_SHIFT) | (S)) +diff --git a/libffi/src/sw_64/sysv.S b/libffi/src/sw_64/sysv.S +new file mode 100644 +index 000000000..2c31400a4 +--- /dev/null ++++ b/libffi/src/sw_64/sysv.S +@@ -0,0 +1,281 @@ ++/* ----------------------------------------------------------------------- ++ sysv.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat ++ Copyright (c) 2023, Wxiat ++ Sunway/SYSV Foreign Function Interface ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ----------------------------------------------------------------------- */ ++#define LIBFFI_ASM ++#include ++#include ++#include ++#include "internal.h" ++ ++ .arch sw6a ++ .text ++ ++/* Aid in building a direct addressed jump table, 4 insns per entry. */ ++.macro E index ++ .align 4 ++ .org 99b + \index * 16 ++.endm ++ ++/* ffi_call_sysv (void *stack, void *frame, unsigned flags, ++ void *raddr, void (*fnaddr)(void), void *closure) ++ ++ Bit o trickiness here -- FRAME is the base of the stack frame ++ for this function. This has been allocated by ffi_call. We also ++ deallocate some of the stack that has been alloca'd. */ ++ ++ .align 4 ++ .globl ffi_call_sysv ++ .ent ffi_call_sysv ++ FFI_HIDDEN(ffi_call_sysv) ++ ++ffi_call_sysv: ++ cfi_startproc ++ cfi_def_cfa($17, 32) ++ mov $16, $30 ++ stl $26, 0($17) ++ stl $15, 8($17) ++ mov $17, $15 ++ .prologue 0 ++ cfi_def_cfa_register($15) ++ cfi_rel_offset($26, 0) ++ cfi_rel_offset($15, 8) ++ ++ stl $18, 16($17) # save flags into frame ++ stl $19, 24($17) # save rvalue into frame ++ mov $20, $27 # fn into place for call ++ mov $21, $1 # closure into static chain ++ ++ # Load up all of the (potential) argument registers. ++ ldl $16, 0($30) ++ fldd $f16, 0($30) ++ fldd $f17, 8($30) ++ ldl $17, 8($30) ++ fldd $f18, 16($30) ++ ldl $18, 16($30) ++ fldd $f19, 24($30) ++ ldl $19, 24($30) ++ fldd $f20, 32($30) ++ ldl $20, 32($30) ++ fldd $f21, 40($30) ++ ldl $21, 40($30) ++ ++ # Deallocate the register argument area. ++ ldi $30, 48($30) ++ ++ call $26, ($27), 0 ++0: ++ ldih $29, 0($26) !gpdisp!1 ++ ldl $2, 24($15) # reload rvalue ++ ldi $29, 0($29) !gpdisp!1 ++ ldl $3, 16($15) # reload flags ++ ldi $1, 99f-0b($26) ++ ldl $26, 0($15) ++ ldl $15, 8($15) ++ cfi_restore($26) ++ cfi_restore($15) ++ cfi_def_cfa($sp, 0) ++ seleq $2, 0, $3 # mash null rvalue to void ++ addl $3, $3, $3 ++ s8addl $3, $1, $1 # 99f + stcode * 16 ++ jmp $31, ($1), $st_int ++ ++ .align 4 ++99: ++E 0 ++ ret ++E 1 ++$st_int: ++ stl $0, 0($2) ++ ret ++E 2 ++ fsts $f0, 0($2) ++ ret ++E 4 ++ fstd $f0, 0($2) ++ ret ++E 6 ++ fsts $f0, 0($2) ++ fsts $f1, 4($2) ++ ret ++E 10 ++ fstd $f0, 0($2) ++ fstd $f1, 8($2) ++ ret ++ ++ cfi_endproc ++ .end ffi_call_sysv ++ ++/* ffi_closure_sysv(...) ++ ++ Receives the closure argument in $1. */ ++ ++#define CLOSURE_FS (16*8) ++ ++ .align 4 ++ .globl ffi_go_closure_sysv ++ .ent ffi_go_closure_sysv ++ FFI_HIDDEN(ffi_go_closure_sysv) ++ ++ffi_go_closure_sysv: ++ cfi_startproc ++ ldgp $29, 0($27) ++ subl $30, CLOSURE_FS, $30 ++ cfi_adjust_cfa_offset(CLOSURE_FS) ++ stl $26, 0($30) ++ .prologue 1 ++ cfi_rel_offset($26, 0) ++ ++ stl $16, 10*8($30) ++ stl $17, 11*8($30) ++ stl $18, 12*8($30) ++ ++ ldl $16, 8($1) # load cif ++ ldl $17, 16($1) # load fun ++ mov $1, $18 # closure is user_data ++ br $do_closure ++ ++ cfi_endproc ++ .end ffi_go_closure_sysv ++ ++ .align 4 ++ .globl ffi_closure_sysv ++ .ent ffi_closure_sysv ++ FFI_HIDDEN(ffi_closure_sysv) ++ ++ffi_closure_sysv: ++ cfi_startproc ++ ldgp $29, 0($27) ++ subl $30, CLOSURE_FS, $30 ++ cfi_adjust_cfa_offset(CLOSURE_FS) ++ stl $26, 0($30) ++ .prologue 1 ++ cfi_rel_offset($26, 0) ++ ++ # Store all of the potential argument registers in va_list format. ++ stl $16, 10*8($30) ++ stl $17, 11*8($30) ++ stl $18, 12*8($30) ++ ++ ldl $16, 24($1) # load cif ++ ldl $17, 32($1) # load fun ++ ldl $18, 40($1) # load user_data ++ ++$do_closure: ++ stl $19, 13*8($30) ++ stl $20, 14*8($30) ++ stl $21, 15*8($30) ++ fstd $f16, 4*8($30) ++ fstd $f17, 5*8($30) ++ fstd $f18, 6*8($30) ++ fstd $f19, 7*8($30) ++ fstd $f20, 8*8($30) ++ fstd $f21, 9*8($30) ++ ++ # Call ffi_closure_sysv_inner to do the bulk of the work. ++ ldi $19, 2*8($30) ++ ldi $20, 10*8($30) ++ call $26, ffi_closure_sysv_inner ++0: ++ ldih $29, 0($26) !gpdisp!2 ++ ldi $2, 99f-0b($26) ++ s4addl $0, 0, $1 # ldcode * 4 ++ ldl $0, 16($30) # preload return value ++ s4addl $1, $2, $1 # 99f + ldcode * 16 ++ ldi $29, 0($29) !gpdisp!2 ++ ldl $26, 0($30) ++ cfi_restore($26) ++ jmp $31, ($1), $load_32 ++ ++.macro epilogue ++ addl $30, CLOSURE_FS, $30 ++ cfi_adjust_cfa_offset(-CLOSURE_FS) ++ ret ++ .align 4 ++ cfi_adjust_cfa_offset(CLOSURE_FS) ++.endm ++ ++ .align 4 ++99: ++E 0 ++ epilogue ++ ++E 1 ++ epilogue ++ ++E 2 ++$load_32: ++ sextl $0, $0 ++ epilogue ++ ++E 3 ++ zapnot $0, 3, $0 ++ epilogue ++ ++E 4 ++#ifdef __sw_64_bwx__ ++ sexth $0, $0 ++#else ++ sll $0, 48, $0 ++ sra $0, 48, $0 ++#endif ++ epilogue ++ ++E 5 ++ and $0, 0xff, $0 ++ epilogue ++ ++E 6 ++#ifdef __sw_64_bwx__ ++ sextb $0, $0 ++#else ++ sll $0, 56, $0 ++ sra $0, 56, $0 ++#endif ++ epilogue ++ ++E 7 ++ flds $f0, 16($sp) ++ epilogue ++ ++E 8 ++ fldd $f0, 16($sp) ++ epilogue ++ ++E 9 ++ flds $f0, 16($sp) ++ flds $f1, 20($sp) ++ epilogue ++ ++E 10 ++ fldd $f0, 16($sp) ++ fldd $f1, 24($sp) ++ epilogue ++ ++ cfi_endproc ++ .end ffi_closure_sysv ++ ++#if defined __ELF__ && defined __linux__ ++ .section .note.GNU-stack,"",@progbits ++#endif +diff --git a/libffi/src/types.c b/libffi/src/types.c +index 9ec27f6cf..6a31d380e 100644 +--- a/libffi/src/types.c ++++ b/libffi/src/types.c +@@ -80,13 +80,13 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const); + FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const); + FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const); + +-#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__ ++#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__ || defined __sw_64__ + #define FFI_LDBL_CONST const + #else + #define FFI_LDBL_CONST + #endif + +-#ifdef __alpha__ ++#ifdef __alpha__ || defined __sw_64__ + /* Even if we're not configured to default to 128-bit long double, + maintain binary compatibility, as -mlong-double-128 can be used + at any time. */ +-- +2.25.1 + diff --git a/0008-Sw64-Port-libgfortran.patch b/0008-Sw64-Port-libgfortran.patch new file mode 100644 index 0000000000000000000000000000000000000000..66d2c7d8167dbcf323c66a8c877cfedbac75a713 --- /dev/null +++ b/0008-Sw64-Port-libgfortran.patch @@ -0,0 +1,57 @@ +From 5920c7d65bf452ddec031bfcbe610404324a38bc Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:52:12 +0800 +Subject: [PATCH 08/16] Sw64 Port: libgfortran + +--- + libgfortran/config/fpu-glibc.h | 6 +++--- + libgfortran/configure.host | 2 ++ + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h +index 265ef6938..8a5eb3c99 100644 +--- a/libgfortran/config/fpu-glibc.h ++++ b/libgfortran/config/fpu-glibc.h +@@ -446,7 +446,7 @@ set_fpu_state (void *state) + int + support_fpu_underflow_control (int kind __attribute__((unused))) + { +-#if defined(__alpha__) && defined(FE_MAP_UMZ) ++#if (defined(__alpha__) || defined(__sw_64__)) && defined(FE_MAP_UMZ) + return (kind == 4 || kind == 8) ? 1 : 0; + #else + return 0; +@@ -457,7 +457,7 @@ support_fpu_underflow_control (int kind __attribute__((unused))) + int + get_fpu_underflow_mode (void) + { +-#if defined(__alpha__) && defined(FE_MAP_UMZ) ++#if (defined(__alpha__) || defined(__sw_64__)) && defined(FE_MAP_UMZ) + + fenv_t state = __ieee_get_fp_control (); + +@@ -475,7 +475,7 @@ get_fpu_underflow_mode (void) + void + set_fpu_underflow_mode (int gradual __attribute__((unused))) + { +-#if defined(__alpha__) && defined(FE_MAP_UMZ) ++#if (defined(__alpha__) || defined(__sw_64__)) && defined(FE_MAP_UMZ) + + fenv_t state = __ieee_get_fp_control (); + +diff --git a/libgfortran/configure.host b/libgfortran/configure.host +index 3d6c2db77..ddd24ac12 100644 +--- a/libgfortran/configure.host ++++ b/libgfortran/configure.host +@@ -71,6 +71,8 @@ case "${host_cpu}" in + ieee_flags="-mieee" ;; + sh*) + ieee_flags="-mieee" ;; ++ sw_64*) ++ ieee_flags="-mieee" ;; + esac + + tmake_file= +-- +2.25.1 + diff --git a/0009-Sw64-Port-libgo.patch b/0009-Sw64-Port-libgo.patch new file mode 100644 index 0000000000000000000000000000000000000000..9eba652e63cdc781c9b491ba9286a37eabd895ed --- /dev/null +++ b/0009-Sw64-Port-libgo.patch @@ -0,0 +1,629 @@ +From 9e32a64afd05cb18a5dcb09a27322e243cd245f4 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:52:50 +0800 +Subject: [PATCH 09/16] Sw64 Port: libgo + +--- + libgo/configure | 7 +- + libgo/configure.ac | 7 +- + libgo/go/cmd/cgo/main.go | 2 + + libgo/go/cmd/internal/sys/arch.go | 11 +++ + libgo/go/debug/elf/elf.go | 72 ++++++++++++++++++ + libgo/go/debug/elf/elf_test.go | 1 + + libgo/go/debug/elf/file.go | 47 ++++++++++++ + libgo/go/encoding/xml/xml.go | 1 + + libgo/go/go/build/syslist.go | 2 +- + .../syscall/unix/getrandom_linux_sw_64.go | 9 +++ + .../syscall/unix/sysnum_linux_sw_64.go | 10 +++ + libgo/go/net/listen_test.go | 2 +- + libgo/go/regexp/testdata/basic.dat | 1 + + libgo/go/runtime/hash64.go | 2 +- + libgo/go/runtime/lfstack_64bit.go | 2 +- + libgo/go/runtime/mpagealloc_64bit.go | 2 +- + libgo/go/syscall/endian_little.go | 2 +- + libgo/go/syscall/libcall_linux_sw_64.go | 13 ++++ + libgo/go/syscall/syscall_linux_sw_64.go | 25 ++++++ + libgo/goarch.sh | 5 ++ + libgo/mksysinfo.sh | 5 ++ + libgo/runtime/go-signal.c | 76 ++++++++++--------- + 22 files changed, 257 insertions(+), 47 deletions(-) + create mode 100644 libgo/go/internal/syscall/unix/getrandom_linux_sw_64.go + create mode 100644 libgo/go/internal/syscall/unix/sysnum_linux_sw_64.go + create mode 100644 libgo/go/syscall/libcall_linux_sw_64.go + create mode 100644 libgo/go/syscall/syscall_linux_sw_64.go + +diff --git a/libgo/configure b/libgo/configure +index ffe17c9be..b90dd9dae 100755 +--- a/libgo/configure ++++ b/libgo/configure +@@ -14124,10 +14124,10 @@ esac + # - libgo/go/syscall/endian_XX.go + # - possibly others + # - possibly update files in libgo/go/internal/syscall/unix +-ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc ppc64 ppc64le riscv riscv64 s390 s390x sh shbe sparc sparc64 wasm" ++ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc ppc64 ppc64le riscv riscv64 s390 s390x sh shbe sparc sparc64 sw_64 wasm" + + # All known GOARCH family values. +-ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 NIOS2 PPC PPC64 RISCV RISCV64 S390 S390X SH SPARC SPARC64 WASM" ++ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 NIOS2 PPC PPC64 RISCV RISCV64 S390 S390X SH SPARC SPARC64 SW_64 WASM" + + GOARCH=unknown + case ${host} in +@@ -14323,6 +14323,9 @@ else + fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; ++ sw_64*-*-*) ++ GOARCH=sw_64 ++ ;; + esac + + +diff --git a/libgo/configure.ac b/libgo/configure.ac +index 7e2b98ba6..9f903c64e 100644 +--- a/libgo/configure.ac ++++ b/libgo/configure.ac +@@ -239,10 +239,10 @@ AC_SUBST(USE_DEJAGNU) + # - libgo/go/syscall/endian_XX.go + # - possibly others + # - possibly update files in libgo/go/internal/syscall/unix +-ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc ppc64 ppc64le riscv riscv64 s390 s390x sh shbe sparc sparc64 wasm" ++ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc ppc64 ppc64le riscv riscv64 s390 s390x sh shbe sparc sparc64 sw_64 wasm" + + # All known GOARCH family values. +-ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 NIOS2 PPC PPC64 RISCV RISCV64 S390 S390X SH SPARC SPARC64 WASM" ++ALLGOARCHFAMILY="I386 ALPHA SW_64 AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 NIOS2 PPC PPC64 RISCV RISCV64 S390 S390X SH SPARC SPARC64 SW_64 WASM" + + GOARCH=unknown + case ${host} in +@@ -370,6 +370,9 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + [GOARCH=sparc], + [GOARCH=sparc64]) + ;; ++ sw_64*-*-*) ++ GOARCH=sw_64 ++ ;; + esac + AC_SUBST(GOARCH) + AC_SUBST(ALLGOARCH) +diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go +index 58477e470..842237774 100644 +--- a/libgo/go/cmd/cgo/main.go ++++ b/libgo/go/cmd/cgo/main.go +@@ -194,6 +194,7 @@ var ptrSizeMap = map[string]int64{ + "shbe": 4, + "sparc": 4, + "sparc64": 8, ++ "sw_64": 8, + } + + var intSizeMap = map[string]int64{ +@@ -221,6 +222,7 @@ var intSizeMap = map[string]int64{ + "shbe": 4, + "sparc": 4, + "sparc64": 8, ++ "sw_64": 8, + } + + var cPrefix string +diff --git a/libgo/go/cmd/internal/sys/arch.go b/libgo/go/cmd/internal/sys/arch.go +index 97d0ac9bb..dea328a34 100644 +--- a/libgo/go/cmd/internal/sys/arch.go ++++ b/libgo/go/cmd/internal/sys/arch.go +@@ -12,6 +12,7 @@ type ArchFamily byte + + const ( + NoArch ArchFamily = iota ++ SW_64 + AMD64 + ARM + ARM64 +@@ -229,7 +230,17 @@ var ArchWasm = &Arch{ + CanMergeLoads: false, + } + ++/*TODO*/ ++var ArchSW_64 = &Arch{ ++ Name: "sw_64", ++ Family: SW_64, ++ ByteOrder: binary.LittleEndian, ++ PtrSize: 8, ++ RegSize: 8, ++ MinLC: 1, ++} + var Archs = [...]*Arch{ ++ ArchSW_64, + Arch386, + ArchAMD64, + ArchARM, +diff --git a/libgo/go/debug/elf/elf.go b/libgo/go/debug/elf/elf.go +index 4c51bc4de..1899a4245 100644 +--- a/libgo/go/debug/elf/elf.go ++++ b/libgo/go/debug/elf/elf.go +@@ -6,6 +6,7 @@ + * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $ + * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $ + * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $ ++ * $FreeBSD: src/sys/sw_64/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $ + * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $ + * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $ + * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $ +@@ -390,6 +391,8 @@ const ( + EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */ + EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */ + EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */ ++ EM_SW_64_STD Machine = 41 /* Digital Sw_64 (standard value). */ ++ EM_SW_64 Machine = 0x9916 /* Mieee-opt Sw_64 (written in the absence of an ABI) */ + ) + + var machineStrings = []intName{ +@@ -581,6 +584,8 @@ var machineStrings = []intName{ + {10, "EM_MIPS_RS4_BE"}, + {41, "EM_ALPHA_STD"}, + {0x9026, "EM_ALPHA"}, ++ {41, "EM_SW_64_STD"}, ++ {0x9916, "EM_SW_64"}, + } + + func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) } +@@ -1645,6 +1650,73 @@ var ralphaStrings = []intName{ + func (i R_ALPHA) String() string { return stringName(uint32(i), ralphaStrings, false) } + func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) } + ++// Relocation types for SW_64. ++type R_SW_64 int ++ ++const ( ++ R_SW_64_NONE R_SW_64 = 0 /* No reloc */ ++ R_SW_64_REFLONG R_SW_64 = 1 /* Direct 32 bit */ ++ R_SW_64_REFQUAD R_SW_64 = 2 /* Direct 64 bit */ ++ R_SW_64_GPREL32 R_SW_64 = 3 /* GP relative 32 bit */ ++ R_SW_64_LITERAL R_SW_64 = 4 /* GP relative 16 bit w/optimization */ ++ R_SW_64_LITUSE R_SW_64 = 5 /* Optimization hint for LITERAL */ ++ R_SW_64_GPDISP R_SW_64 = 6 /* Add displacement to GP */ ++ R_SW_64_BRADDR R_SW_64 = 7 /* PC+4 relative 23 bit shifted */ ++ R_SW_64_HINT R_SW_64 = 8 /* PC+4 relative 16 bit shifted */ ++ R_SW_64_SREL16 R_SW_64 = 9 /* PC relative 16 bit */ ++ R_SW_64_SREL32 R_SW_64 = 10 /* PC relative 32 bit */ ++ R_SW_64_SREL64 R_SW_64 = 11 /* PC relative 64 bit */ ++ R_SW_64_OP_PUSH R_SW_64 = 12 /* OP stack push */ ++ R_SW_64_OP_STORE R_SW_64 = 13 /* OP stack pop and store */ ++ R_SW_64_OP_PSUB R_SW_64 = 14 /* OP stack subtract */ ++ R_SW_64_OP_PRSHIFT R_SW_64 = 15 /* OP stack right shift */ ++ R_SW_64_GPVALUE R_SW_64 = 16 ++ R_SW_64_GPRELHIGH R_SW_64 = 17 ++ R_SW_64_GPRELLOW R_SW_64 = 18 ++ R_SW_64_IMMED_GP_16 R_SW_64 = 19 ++ R_SW_64_IMMED_GP_HI32 R_SW_64 = 20 ++ R_SW_64_IMMED_SCN_HI32 R_SW_64 = 21 ++ R_SW_64_IMMED_BR_HI32 R_SW_64 = 22 ++ R_SW_64_IMMED_LO32 R_SW_64 = 23 ++ R_SW_64_COPY R_SW_64 = 24 /* Copy sympol at runtime */ ++ R_SW_64_GLOB_DAT R_SW_64 = 25 /* Create GOT entry */ ++ R_SW_64_JMP_SLOT R_SW_64 = 26 /* Create PLT entry */ ++ R_SW_64_RELATIVE R_SW_64 = 27 /* Adjust by program base */ ++) ++var rsw_64Strings = []intName{ ++ {0, "R_SW_64_NONE"}, ++ {1, "R_SW_64_REFLONG"}, ++ {2, "R_SW_64_REFQUAD"}, ++ {3, "R_SW_64_GPREL32"}, ++ {4, "R_SW_64_LITERAL"}, ++ {5, "R_SW_64_LITUSE"}, ++ {6, "R_SW_64_GPDISP"}, ++ {7, "R_SW_64_BRADDR"}, ++ {8, "R_SW_64_HINT"}, ++ {9, "R_SW_64_SREL16"}, ++ {10, "R_SW_64_SREL32"}, ++ {11, "R_SW_64_SREL64"}, ++ {12, "R_SW_64_OP_PUSH"}, ++ {13, "R_SW_64_OP_STORE"}, ++ {14, "R_SW_64_OP_PSUB"}, ++ {15, "R_SW_64_OP_PRSHIFT"}, ++ {16, "R_SW_64_GPVALUE"}, ++ {17, "R_SW_64_GPRELHIGH"}, ++ {18, "R_SW_64_GPRELLOW"}, ++ {19, "R_SW_64_IMMED_GP_16"}, ++ {20, "R_SW_64_IMMED_GP_HI32"}, ++ {21, "R_SW_64_IMMED_SCN_HI32"}, ++ {22, "R_SW_64_IMMED_BR_HI32"}, ++ {23, "R_SW_64_IMMED_LO32"}, ++ {24, "R_SW_64_COPY"}, ++ {25, "R_SW_64_GLOB_DAT"}, ++ {26, "R_SW_64_JMP_SLOT"}, ++ {27, "R_SW_64_RELATIVE"}, ++} ++ ++func (i R_SW_64) String() string { return stringName(uint32(i), rsw_64Strings, false) } ++func (i R_SW_64) GoString() string { return stringName(uint32(i), rsw_64Strings, true) } ++ + // Relocation types for ARM. + type R_ARM int + +diff --git a/libgo/go/debug/elf/elf_test.go b/libgo/go/debug/elf/elf_test.go +index b8c310dba..940af9c51 100644 +--- a/libgo/go/debug/elf/elf_test.go ++++ b/libgo/go/debug/elf/elf_test.go +@@ -31,6 +31,7 @@ var nameTests = []nameTest{ + {STV_HIDDEN, "STV_HIDDEN"}, + {R_X86_64_PC32, "R_X86_64_PC32"}, + {R_ALPHA_OP_PUSH, "R_ALPHA_OP_PUSH"}, ++ {R_SW_64_OP_PUSH, "R_SW_64_OP_PUSH"}, + {R_ARM_THM_ABS5, "R_ARM_THM_ABS5"}, + {R_386_GOT32, "R_386_GOT32"}, + {R_PPC_GOT16_HI, "R_PPC_GOT16_HI"}, +diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go +index 60d2788c9..53f34d78c 100644 +--- a/libgo/go/debug/elf/file.go ++++ b/libgo/go/debug/elf/file.go +@@ -632,6 +632,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error { + return f.applyRelocationsSPARC64(dst, rels) + case f.Class == ELFCLASS64 && f.Machine == EM_ALPHA: + return f.applyRelocationsALPHA(dst, rels) ++ case f.Class == ELFCLASS64 && f.Machine == EM_SW_64: ++ return f.applyRelocationsSW_64(dst, rels) + default: + return errors.New("applyRelocations: not implemented") + } +@@ -1266,6 +1268,51 @@ func (f *File) applyRelocationsALPHA(dst []byte, rels []byte) error { + return nil + } + ++func (f *File) applyRelocationsSW_64(dst []byte, rels []byte) error { ++ // 24 is the size of Rela64. ++ if len(rels)%24 != 0 { ++ return errors.New("length of relocation section is not a multiple of 24") ++ } ++ ++ symbols, _, err := f.getSymbols(SHT_SYMTAB) ++ if err != nil { ++ return err ++ } ++ ++ b := bytes.NewReader(rels) ++ var rela Rela64 ++ for b.Len() > 0 { ++ binary.Read(b, f.ByteOrder, &rela) ++ symNo := rela.Info >> 32 ++ t := R_SW_64(rela.Info & 0xffff) ++ ++ if symNo == 0 || symNo > uint64(len(symbols)) { ++ continue ++ } ++ sym := &symbols[symNo-1] ++ if SymType(sym.Info&0xf) != STT_SECTION { ++ // We don't handle non-section relocations for now. ++ continue ++ } ++ ++ // There are relocations, so this must be a normal ++ // object file, and we only look at section symbols, ++ // so we assume that the symbol value is 0. ++ switch t { ++ case R_SW_64_REFQUAD: ++ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { ++ continue ++ } ++ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) ++ case R_SW_64_REFLONG: ++ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { ++ } ++ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) ++ } ++ } ++ return nil ++} ++ + func (f *File) DWARF() (*dwarf.Data, error) { + dwarfSuffix := func(s *Section) string { + switch { +diff --git a/libgo/go/encoding/xml/xml.go b/libgo/go/encoding/xml/xml.go +index 8a0a9c253..f40099a1b 100644 +--- a/libgo/go/encoding/xml/xml.go ++++ b/libgo/go/encoding/xml/xml.go +@@ -1727,6 +1727,7 @@ var htmlEntity = map[string]string{ + "Psi": "\u03A8", + "Omega": "\u03A9", + "alpha": "\u03B1", ++ "sw_64": "\u03B1", + "beta": "\u03B2", + "gamma": "\u03B3", + "delta": "\u03B4", +diff --git a/libgo/go/go/build/syslist.go b/libgo/go/go/build/syslist.go +index 1b11365f5..74d7fec11 100644 +--- a/libgo/go/go/build/syslist.go ++++ b/libgo/go/go/build/syslist.go +@@ -8,4 +8,4 @@ package build + // Do not remove from this list, as these are used for go/build filename matching. + + const goosList = "aix android darwin dragonfly freebsd hurd illumos ios js linux nacl netbsd openbsd plan9 solaris windows zos " +-const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be loong64 mips mipsle mips64 mips64le ppc ppc64 ppc64le riscv riscv64 s390 s390x sparc sparc64 wasm alpha m68k nios2 sh shbe " ++const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be loong64 mips mipsle mips64 mips64le ppc ppc64 ppc64le riscv riscv64 s390 s390x sparc sparc64 wasm alpha m68k nios2 sh shbe sw_64" +diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_sw_64.go b/libgo/go/internal/syscall/unix/getrandom_linux_sw_64.go +new file mode 100644 +index 000000000..9587b5aa4 +--- /dev/null ++++ b/libgo/go/internal/syscall/unix/getrandom_linux_sw_64.go +@@ -0,0 +1,9 @@ ++// Copyright 2016 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package unix ++ ++// Linux getrandom system call number. ++// See GetRandom in getrandom_linux.go. ++const randomTrap uintptr = 511 +diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_sw_64.go b/libgo/go/internal/syscall/unix/sysnum_linux_sw_64.go +new file mode 100644 +index 000000000..c40bc8488 +--- /dev/null ++++ b/libgo/go/internal/syscall/unix/sysnum_linux_sw_64.go +@@ -0,0 +1,10 @@ ++// Copyright 2016 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package unix ++ ++const ( ++ getrandomTrap uintptr = 511 ++ copyFileRangeTrap uintptr = 519 ++) +diff --git a/libgo/go/net/listen_test.go b/libgo/go/net/listen_test.go +index 59c011212..d61055a04 100644 +--- a/libgo/go/net/listen_test.go ++++ b/libgo/go/net/listen_test.go +@@ -673,7 +673,7 @@ func multicastRIBContains(ip IP) (bool, error) { + case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos", "windows": + return true, nil // not implemented yet + case "linux": +- if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" { ++ if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" || runtime.GOARCH == "sw_64" { + return true, nil // not implemented yet + } + } +diff --git a/libgo/go/regexp/testdata/basic.dat b/libgo/go/regexp/testdata/basic.dat +index 1776b1ff9..b53926812 100644 +--- a/libgo/go/regexp/testdata/basic.dat ++++ b/libgo/go/regexp/testdata/basic.dat +@@ -153,6 +153,7 @@ E a[bcd]*dcdcde adcdcde (0,7) + E (ab|a)b*c abc (0,3)(0,2) + E ((a)(b)c)(d) abcd (0,4)(0,3)(0,1)(1,2)(3,4) + BE [A-Za-z_][A-Za-z0-9_]* alpha (0,5) ++BE [A-Za-z_][A-Za-z0-9_]* sw_64 (0,5) + E ^a(bc+|b[eh])g|.h$ abh (1,3) + E (bc+d$|ef*g.|h?i(j|k)) effgz (0,5)(0,5) + E (bc+d$|ef*g.|h?i(j|k)) ij (0,2)(0,2)(1,2) +diff --git a/libgo/go/runtime/hash64.go b/libgo/go/runtime/hash64.go +index a1d2529e7..ee793552c 100644 +--- a/libgo/go/runtime/hash64.go ++++ b/libgo/go/runtime/hash64.go +@@ -5,7 +5,7 @@ + // Hashing algorithm inspired by + // wyhash: https://github.com/wangyi-fudan/wyhash + +-//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm || alpha || arm64be || ia64 || sparc64 ++//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm || alpha || sw_64 || arm64be || ia64 || sparc64 + + package runtime + +diff --git a/libgo/go/runtime/lfstack_64bit.go b/libgo/go/runtime/lfstack_64bit.go +index 8e0883094..0e87c5059 100644 +--- a/libgo/go/runtime/lfstack_64bit.go ++++ b/libgo/go/runtime/lfstack_64bit.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm || arm64be || alpha || sparc64 || ia64 ++//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm || arm64be || alpha || sw_64 || sparc64 || ia64 + + package runtime + +diff --git a/libgo/go/runtime/mpagealloc_64bit.go b/libgo/go/runtime/mpagealloc_64bit.go +index 3d0d4c608..aca127d7c 100644 +--- a/libgo/go/runtime/mpagealloc_64bit.go ++++ b/libgo/go/runtime/mpagealloc_64bit.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || arm64be || alpha || sparc64 || ia64 ++//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || arm64be || alpha || sw_64 || sparc64 || ia64 + + package runtime + +diff --git a/libgo/go/syscall/endian_little.go b/libgo/go/syscall/endian_little.go +index 63e46d8b1..37af34bce 100644 +--- a/libgo/go/syscall/endian_little.go ++++ b/libgo/go/syscall/endian_little.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build 386 || alpha || amd64 || amd64p32 || arm || arm64 || ia64 || ppc64le || mips64le || mipsle || mips64p32le || nios2 || riscv || riscv64 || sh || wasm ++//go:build 386 || alpha || sw_64 || amd64 || amd64p32 || arm || arm64 || ia64 || ppc64le || mips64le || mipsle || mips64p32le || nios2 || riscv || riscv64 || sh || wasm + + package syscall + +diff --git a/libgo/go/syscall/libcall_linux_sw_64.go b/libgo/go/syscall/libcall_linux_sw_64.go +new file mode 100644 +index 000000000..13ccf05a6 +--- /dev/null ++++ b/libgo/go/syscall/libcall_linux_sw_64.go +@@ -0,0 +1,13 @@ ++// Copyright 2012 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++// GNU/Linux library calls Alpha specific. ++ ++package syscall ++ ++//sys Ioperm(from int, num int, on int) (err error) ++//ioperm(from _C_long, num _C_long, on _C_int) _C_int ++ ++//sys Iopl(level int) (err error) ++//iopl(level _C_int) _C_int +diff --git a/libgo/go/syscall/syscall_linux_sw_64.go b/libgo/go/syscall/syscall_linux_sw_64.go +new file mode 100644 +index 000000000..5115b9b7c +--- /dev/null ++++ b/libgo/go/syscall/syscall_linux_sw_64.go +@@ -0,0 +1,25 @@ ++// syscall_linux_alpha.go -- GNU/Linux ALPHA specific support ++ ++// Copyright 2011 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package syscall ++ ++import "unsafe" ++ ++func (r *PtraceRegs) PC() uint64 { ++ return r.Pc ++} ++ ++func (r *PtraceRegs) SetPC(pc uint64) { ++ r.Pc = pc ++} ++ ++func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { ++ return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) ++} ++ ++func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { ++ return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) ++} +diff --git a/libgo/goarch.sh b/libgo/goarch.sh +index 977f318b3..a0cdcf17e 100755 +--- a/libgo/goarch.sh ++++ b/libgo/goarch.sh +@@ -54,6 +54,11 @@ case $goarch in + defaultphyspagesize=8192 + pcquantum=4 + ;; ++ sw_64) ++ family=SW_64 ++ defaultphyspagesize=8192 ++ pcquantum=4 ++ ;; + amd64) + family=AMD64 + ;; +diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh +index 0c52ea5d7..11031f5a0 100755 +--- a/libgo/mksysinfo.sh ++++ b/libgo/mksysinfo.sh +@@ -377,7 +377,12 @@ if test "$regs" = ""; then + # mips* + regs=`grep '^type _pt_regs struct' gen-sysinfo.go || true` + fi ++if test "$regs" = ""; then ++ # sw_64* ++ regs=`grep '^type _user_pt_regs struct' gen-sysinfo.go || true` ++fi + if test "$regs" != ""; then ++ regs=`echo $regs | sed -e 's/type _user_pt_regs struct//'` + regs=`echo $regs | sed -e 's/type _pt_regs struct//'` + regs=`echo $regs | + sed -e 's/type __*user_regs_struct struct //' -e 's/[{}]//g'` +diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c +index 528d9b6d9..20e6947b5 100644 +--- a/libgo/runtime/go-signal.c ++++ b/libgo/runtime/go-signal.c +@@ -230,6 +230,8 @@ getSiginfo(siginfo_t *info, void *context __attribute__((unused))) + ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[REG_EIP]; + #elif defined(__alpha__) && defined(__linux__) + ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc; ++#elif defined(__sw_64__) && defined(__linux__) ++ ret.sigpc = ((ucontext_t *) (context))->uc_mcontext.sc_pc; + #elif defined(__PPC64__) && defined(__linux__) + ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gp_regs[32]; + #elif defined(__PPC__) && defined(__linux__) +@@ -311,43 +313,43 @@ dumpregs(siginfo_t *info __attribute__((unused)), void *context __attribute__((u + runtime_printf("fs %x\n", m->gregs[REG_FS]); + runtime_printf("gs %x\n", m->gregs[REG_GS]); + } +-#elif defined(__alpha__) && defined(__linux__) +- { +- mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext; +- +- runtime_printf("v0 %X\n", m->sc_regs[0]); +- runtime_printf("t0 %X\n", m->sc_regs[1]); +- runtime_printf("t1 %X\n", m->sc_regs[2]); +- runtime_printf("t2 %X\n", m->sc_regs[3]); +- runtime_printf("t3 %X\n", m->sc_regs[4]); +- runtime_printf("t4 %X\n", m->sc_regs[5]); +- runtime_printf("t5 %X\n", m->sc_regs[6]); +- runtime_printf("t6 %X\n", m->sc_regs[7]); +- runtime_printf("t7 %X\n", m->sc_regs[8]); +- runtime_printf("s0 %X\n", m->sc_regs[9]); +- runtime_printf("s1 %X\n", m->sc_regs[10]); +- runtime_printf("s2 %X\n", m->sc_regs[11]); +- runtime_printf("s3 %X\n", m->sc_regs[12]); +- runtime_printf("s4 %X\n", m->sc_regs[13]); +- runtime_printf("s5 %X\n", m->sc_regs[14]); +- runtime_printf("fp %X\n", m->sc_regs[15]); +- runtime_printf("a0 %X\n", m->sc_regs[16]); +- runtime_printf("a1 %X\n", m->sc_regs[17]); +- runtime_printf("a2 %X\n", m->sc_regs[18]); +- runtime_printf("a3 %X\n", m->sc_regs[19]); +- runtime_printf("a4 %X\n", m->sc_regs[20]); +- runtime_printf("a5 %X\n", m->sc_regs[21]); +- runtime_printf("t8 %X\n", m->sc_regs[22]); +- runtime_printf("t9 %X\n", m->sc_regs[23]); +- runtime_printf("t10 %X\n", m->sc_regs[24]); +- runtime_printf("t11 %X\n", m->sc_regs[25]); +- runtime_printf("ra %X\n", m->sc_regs[26]); +- runtime_printf("t12 %X\n", m->sc_regs[27]); +- runtime_printf("at %X\n", m->sc_regs[28]); +- runtime_printf("gp %X\n", m->sc_regs[29]); +- runtime_printf("sp %X\n", m->sc_regs[30]); +- runtime_printf("pc %X\n", m->sc_pc); +- } ++#elif (defined(__alpha__) || defined(__sw_64__)) && defined(__linux__) ++ { ++ mcontext_t *m = &((ucontext_t *) (context))->uc_mcontext; ++ ++ runtime_printf ("v0 %X\n", m->sc_regs[0]); ++ runtime_printf ("t0 %X\n", m->sc_regs[1]); ++ runtime_printf ("t1 %X\n", m->sc_regs[2]); ++ runtime_printf ("t2 %X\n", m->sc_regs[3]); ++ runtime_printf ("t3 %X\n", m->sc_regs[4]); ++ runtime_printf ("t4 %X\n", m->sc_regs[5]); ++ runtime_printf ("t5 %X\n", m->sc_regs[6]); ++ runtime_printf ("t6 %X\n", m->sc_regs[7]); ++ runtime_printf ("t7 %X\n", m->sc_regs[8]); ++ runtime_printf ("s0 %X\n", m->sc_regs[9]); ++ runtime_printf ("s1 %X\n", m->sc_regs[10]); ++ runtime_printf ("s2 %X\n", m->sc_regs[11]); ++ runtime_printf ("s3 %X\n", m->sc_regs[12]); ++ runtime_printf ("s4 %X\n", m->sc_regs[13]); ++ runtime_printf ("s5 %X\n", m->sc_regs[14]); ++ runtime_printf ("fp %X\n", m->sc_regs[15]); ++ runtime_printf ("a0 %X\n", m->sc_regs[16]); ++ runtime_printf ("a1 %X\n", m->sc_regs[17]); ++ runtime_printf ("a2 %X\n", m->sc_regs[18]); ++ runtime_printf ("a3 %X\n", m->sc_regs[19]); ++ runtime_printf ("a4 %X\n", m->sc_regs[20]); ++ runtime_printf ("a5 %X\n", m->sc_regs[21]); ++ runtime_printf ("t8 %X\n", m->sc_regs[22]); ++ runtime_printf ("t9 %X\n", m->sc_regs[23]); ++ runtime_printf ("t10 %X\n", m->sc_regs[24]); ++ runtime_printf ("t11 %X\n", m->sc_regs[25]); ++ runtime_printf ("ra %X\n", m->sc_regs[26]); ++ runtime_printf ("t12 %X\n", m->sc_regs[27]); ++ runtime_printf ("at %X\n", m->sc_regs[28]); ++ runtime_printf ("gp %X\n", m->sc_regs[29]); ++ runtime_printf ("sp %X\n", m->sc_regs[30]); ++ runtime_printf ("pc %X\n", m->sc_pc); ++ } + #elif defined(__PPC__) && defined(__linux__) + { + int i; +-- +2.25.1 + diff --git a/0010-Sw64-Port-libgomp.patch b/0010-Sw64-Port-libgomp.patch new file mode 100644 index 0000000000000000000000000000000000000000..fb71443d57b37c3abd4583c6b1e0f2feedc6a1cc --- /dev/null +++ b/0010-Sw64-Port-libgomp.patch @@ -0,0 +1,165 @@ +From 6ecc701c02c54cd1af013e70aef7ccf768f42da2 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:53:22 +0800 +Subject: [PATCH 10/16] Sw64 Port: libgomp + +--- + libgomp/config/linux/sw_64/futex.h | 102 +++++++++++++++++++++++++++++ + libgomp/configure | 6 ++ + libgomp/configure.tgt | 4 ++ + libgomp/libgomp.spec.in | 2 +- + 4 files changed, 113 insertions(+), 1 deletion(-) + create mode 100644 libgomp/config/linux/sw_64/futex.h + +diff --git a/libgomp/config/linux/sw_64/futex.h b/libgomp/config/linux/sw_64/futex.h +new file mode 100644 +index 000000000..258f38289 +--- /dev/null ++++ b/libgomp/config/linux/sw_64/futex.h +@@ -0,0 +1,102 @@ ++/* Copyright (C) 2005-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson . ++ ++ This file is part of the GNU Offloading and Multi Processing Library ++ (libgomp). ++ ++ Libgomp is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ++ FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++/* Provide target-specific access to the futex system call. */ ++ ++#ifndef SYS_futex ++#define SYS_futex 394 ++#endif ++ ++static inline void ++futex_wait (int *addr, int val) ++{ ++ register long sc_0 __asm__("$0"); ++ register long sc_16 __asm__("$16"); ++ register long sc_17 __asm__("$17"); ++ register long sc_18 __asm__("$18"); ++ register long sc_19 __asm__("$19"); ++ ++ sc_0 = SYS_futex; ++ sc_16 = (long) addr; ++ sc_17 = gomp_futex_wait; ++ sc_18 = val; ++ sc_19 = 0; ++ __asm volatile ("callsys" ++ : "=r"(sc_0), "=r"(sc_19) ++ : "0"(sc_0), "r"(sc_16), "r"(sc_17), "r"(sc_18), "1"(sc_19) ++ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", "$23", ++ "$24", "$25", "$27", "$28", "memory"); ++ if (__builtin_expect (sc_19, 0) && sc_0 == ENOSYS) ++ { ++ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; ++ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; ++ sc_0 = SYS_futex; ++ sc_17 &= ~FUTEX_PRIVATE_FLAG; ++ sc_19 = 0; ++ __asm volatile ("callsys" ++ : "=r"(sc_0), "=r"(sc_19) ++ : "0"(sc_0), "r"(sc_16), "r"(sc_17), "r"(sc_18), "1"(sc_19) ++ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", ++ "$23", "$24", "$25", "$27", "$28", "memory"); ++ } ++} ++ ++static inline void ++futex_wake (int *addr, int count) ++{ ++ register long sc_0 __asm__("$0"); ++ register long sc_16 __asm__("$16"); ++ register long sc_17 __asm__("$17"); ++ register long sc_18 __asm__("$18"); ++ register long sc_19 __asm__("$19"); ++ ++ sc_0 = SYS_futex; ++ sc_16 = (long) addr; ++ sc_17 = gomp_futex_wake; ++ sc_18 = count; ++ __asm volatile ("callsys" ++ : "=r"(sc_0), "=r"(sc_19) ++ : "0"(sc_0), "r"(sc_16), "r"(sc_17), "r"(sc_18) ++ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", "$23", ++ "$24", "$25", "$27", "$28", "memory"); ++ if (__builtin_expect (sc_19, 0) && sc_0 == ENOSYS) ++ { ++ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; ++ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; ++ sc_0 = SYS_futex; ++ sc_17 &= ~FUTEX_PRIVATE_FLAG; ++ __asm volatile ("callsys" ++ : "=r"(sc_0), "=r"(sc_19) ++ : "0"(sc_0), "r"(sc_16), "r"(sc_17), "r"(sc_18) ++ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", ++ "$23", "$24", "$25", "$27", "$28", "memory"); ++ } ++} ++ ++static inline void ++cpu_relax (void) ++{ ++ __asm volatile ("" : : : "memory"); ++} +diff --git a/libgomp/configure b/libgomp/configure +index 471c957b7..a1df23705 100755 +--- a/libgomp/configure ++++ b/libgomp/configure +@@ -11841,6 +11841,12 @@ case `echo $GFORTRAN` in + FC=no + fi ;; + esac ++case "${target}" in ++ sw_64-*-*) ++ FC="$GFORTRAN" ++ ;; ++*) ++esac + ac_ext=${ac_fc_srcext-f} + ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' + ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' +diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt +index f924e9f98..a8023d0f2 100644 +--- a/libgomp/configure.tgt ++++ b/libgomp/configure.tgt +@@ -87,6 +87,10 @@ if test x$enable_linux_futex = xyes; then + config_path="linux/s390 linux posix" + ;; + ++ sw_64*-*-linux*) ++ config_path="linux/sw_64 linux posix" ++ ;; ++ + tile*-*-linux*) + config_path="linux/tile linux posix" + ;; +diff --git a/libgomp/libgomp.spec.in b/libgomp/libgomp.spec.in +index 5651603f4..8442e6313 100644 +--- a/libgomp/libgomp.spec.in ++++ b/libgomp/libgomp.spec.in +@@ -1,3 +1,3 @@ + # This spec file is read by gcc when linking. It is used to specify the + # standard libraries we need in order to link with libgomp. +-*link_gomp: @link_gomp@ ++*link_gomp: @link_gomp@ --whole-archive -lpthread --no-whole-archive +-- +2.25.1 + diff --git a/0011-Sw64-Port-libitm.patch b/0011-Sw64-Port-libitm.patch new file mode 100644 index 0000000000000000000000000000000000000000..52a527ed7afccf0718e9fd9594c1f93a5ef706e4 --- /dev/null +++ b/0011-Sw64-Port-libitm.patch @@ -0,0 +1,260 @@ +From c506f4995a68274efbd31ede3751b14dc0fa0718 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:53:43 +0800 +Subject: [PATCH 11/16] Sw64 Port: libitm + +--- + libitm/config/linux/sw_64/futex_bits.h | 56 +++++++++++++ + libitm/config/sw_64/sjlj.S | 112 +++++++++++++++++++++++++ + libitm/config/sw_64/target.h | 44 ++++++++++ + libitm/configure.tgt | 1 + + 4 files changed, 213 insertions(+) + create mode 100644 libitm/config/linux/sw_64/futex_bits.h + create mode 100644 libitm/config/sw_64/sjlj.S + create mode 100644 libitm/config/sw_64/target.h + +diff --git a/libitm/config/linux/sw_64/futex_bits.h b/libitm/config/linux/sw_64/futex_bits.h +new file mode 100644 +index 000000000..478a3078a +--- /dev/null ++++ b/libitm/config/linux/sw_64/futex_bits.h +@@ -0,0 +1,56 @@ ++/* Copyright (C) 2008-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson . ++ ++ This file is part of the GNU Transactional Memory Library (libitm). ++ ++ Libitm is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ Libitm is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ++ FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++/* Provide target-specific access to the futex system call. */ ++ ++#ifndef SYS_futex ++#define SYS_futex 394 ++#endif ++ ++static inline long ++sys_futex0 (std::atomic *addr, int op, int val) ++{ ++ register long sc_0 __asm__("$0"); ++ register long sc_16 __asm__("$16"); ++ register long sc_17 __asm__("$17"); ++ register long sc_18 __asm__("$18"); ++ register long sc_19 __asm__("$19"); ++ long res; ++ ++ sc_0 = SYS_futex; ++ sc_16 = (long) addr; ++ sc_17 = op; ++ sc_18 = val; ++ sc_19 = 0; ++ __asm volatile("callsys" ++ : "=r"(sc_0), "=r"(sc_19) ++ : "0"(sc_0), "r"(sc_16), "r"(sc_17), "r"(sc_18), "1"(sc_19) ++ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", "$23", ++ "$24", "$25", "$27", "$28", "memory"); ++ ++ res = sc_0; ++ if (__builtin_expect (sc_19, 0)) ++ res = -res; ++ return res; ++} +diff --git a/libitm/config/sw_64/sjlj.S b/libitm/config/sw_64/sjlj.S +new file mode 100644 +index 000000000..c4b74d76b +--- /dev/null ++++ b/libitm/config/sw_64/sjlj.S +@@ -0,0 +1,112 @@ ++/* Copyright (C) 2009-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson . ++ ++ This file is part of the GNU Transactional Memory Library (libitm). ++ ++ Libitm is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ Libitm is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ++ FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++ .text ++ .align 4 ++ .globl _ITM_beginTransaction ++ .ent _ITM_beginTransaction ++ ++#define FRAME 144 ++ ++_ITM_beginTransaction: ++ ldgp $29, 0($27) ++ subl $30, FRAME, $30 ++ .frame $30, FRAME, $26, 0 ++ .mask 0x04000000, 0 ++ stl $26, 0($30) ++ .prologue 1 ++ ++ stl $9, 8($30) ++ stl $10, 16($30) ++ addl $30, FRAME, $0 ++ stl $11, 24($30) ++ ++ stl $12, 32($30) ++ stl $13, 40($30) ++ stl $14, 48($30) ++ stl $15, 56($30) ++ ++ stl $0, 64($30) ++ fstd $f2, 72($30) ++ fstd $f3, 80($30) ++ fstd $f4, 88($30) ++ ++ fstd $f5, 96($30) ++ fstd $f6, 104($30) ++ fstd $f7, 112($30) ++ fstd $f8, 120($30) ++ ++ fstd $f9, 128($30) ++ mov $30, $17 ++#ifdef __PIC__ ++ unop ++ bsr $26, GTM_begin_transaction !samegp ++#else ++ call $26, GTM_begin_transaction ++ ldgp $29, 0($26) ++#endif ++ ++ ldl $26, 0($30) ++ addl $30, FRAME, $30 ++ ret ++.end _ITM_beginTransaction ++ ++ .align 4 ++ .globl GTM_longjmp ++#ifdef __ELF__ ++ .hidden GTM_longjmp ++#endif ++ .ent GTM_longjmp ++ ++GTM_longjmp: ++ .prologue 0 ++ ldl $26, 0($17) ++ ldl $9, 8($17) ++ ldl $10, 16($17) ++ ldl $11, 24($17) ++ ++ ldl $12, 32($17) ++ ldl $13, 40($17) ++ ldl $14, 48($17) ++ ldl $15, 56($17) ++ ++ ldl $1, 64($17) ++ fldd $f2, 72($17) ++ fldd $f3, 80($17) ++ fldd $f4, 88($17) ++ ++ fldd $f5, 96($17) ++ fldd $f6, 104($17) ++ fldd $f7, 112($17) ++ fldd $f8, 120($17) ++ ++ fldd $f9, 128($17) ++ mov $16, $0 ++ mov $1, $30 ++ ret ++.end GTM_longjmp ++ ++#ifdef __linux__ ++.section .note.GNU-stack, "", @progbits ++#endif +diff --git a/libitm/config/sw_64/target.h b/libitm/config/sw_64/target.h +new file mode 100644 +index 000000000..7c3f1e3bd +--- /dev/null ++++ b/libitm/config/sw_64/target.h +@@ -0,0 +1,44 @@ ++/* Copyright (C) 2009-2022 Free Software Foundation, Inc. ++ Contributed by Richard Henderson . ++ ++ This file is part of the GNU Transactional Memory Library (libitm). ++ ++ Libitm is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ Libitm is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ++ FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++namespace GTM HIDDEN { ++ ++typedef struct gtm_jmpbuf ++{ ++ unsigned long pc; ++ unsigned long s[7]; ++ void *cfa; ++ unsigned long f[8]; ++} gtm_jmpbuf; ++ ++/* The size of one line in hardware caches (in bytes). */ ++#define HW_CACHELINE_SIZE 64 ++ ++static inline void ++cpu_relax (void) ++{ ++ __asm volatile ("" : : : "memory"); ++} ++ ++} // namespace HIDDEN +diff --git a/libitm/configure.tgt b/libitm/configure.tgt +index 06e90973e..d831da5b0 100644 +--- a/libitm/configure.tgt ++++ b/libitm/configure.tgt +@@ -118,6 +118,7 @@ EOF + *) + ARCH="${target_cpu}" + ;; ++ sw_64*) ARCH=sw_64 ;; + esac + + # For the benefit of top-level configure, determine if the cpu is supported. +-- +2.25.1 + diff --git a/0012-Sw64-Port-libstdc.patch b/0012-Sw64-Port-libstdc.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbce1f8bc3040c32eecf3fa8f256bf6737e4b4e1 --- /dev/null +++ b/0012-Sw64-Port-libstdc.patch @@ -0,0 +1,6237 @@ +From f8ed3d1bb787694d2ad6cd4e46bedea0c6ab6a3b Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:54:30 +0800 +Subject: [PATCH 12/16] Sw64 Port: libstdc++ + +--- + libstdc++-v3/acinclude.m4 | 2 +- + .../post/sw_64-linux-gnu/baseline_symbols.txt | 6154 +++++++++++++++++ + libstdc++-v3/configure | 3 +- + libstdc++-v3/configure.ac | 1 + + libstdc++-v3/configure.host | 3 + + 5 files changed, 6161 insertions(+), 2 deletions(-) + create mode 100644 libstdc++-v3/config/abi/post/sw_64-linux-gnu/baseline_symbols.txt + +diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 +index 04f2153fc..a7d7698bd 100644 +--- a/libstdc++-v3/acinclude.m4 ++++ b/libstdc++-v3/acinclude.m4 +@@ -4846,7 +4846,7 @@ AC_DEFUN([GLIBCXX_CHECK_EXCEPTION_PTR_SYMVER], [ + AC_MSG_CHECKING([for first version to support std::exception_ptr]) + case ${target} in + aarch64-*-* | alpha-*-* | hppa*-*-* | i?86-*-* | x86_64-*-* | \ +- m68k-*-* | powerpc*-*-* | s390*-*-* | *-*-solaris* ) ++ m68k-*-* | powerpc*-*-* | s390*-*-* | sw_64-*-* | *-*-solaris* ) + ac_exception_ptr_since_gcc46=yes + ;; + *) +diff --git a/libstdc++-v3/config/abi/post/sw_64-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/sw_64-linux-gnu/baseline_symbols.txt +new file mode 100644 +index 000000000..0ca027cc9 +--- /dev/null ++++ b/libstdc++-v3/config/abi/post/sw_64-linux-gnu/baseline_symbols.txt +@@ -0,0 +1,6154 @@ ++FUNC:_ZGTtNKSt11logic_error4whatEv@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNKSt13bad_exception4whatEv@@CXXABI_1.3.10 ++FUNC:_ZGTtNKSt13bad_exceptionD1Ev@@CXXABI_1.3.10 ++FUNC:_ZGTtNKSt13runtime_error4whatEv@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNKSt9exception4whatEv@@CXXABI_1.3.10 ++FUNC:_ZGTtNKSt9exceptionD1Ev@@CXXABI_1.3.10 ++FUNC:_ZGTtNSt11logic_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11logic_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11logic_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11logic_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11logic_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt11range_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12domain_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12length_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt12out_of_rangeD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt13runtime_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt14overflow_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt15underflow_errorD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentC1EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentC2EPKc@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZGTtNSt16invalid_argumentD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZN10__cxxabiv116__enum_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv116__enum_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv116__enum_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__array_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__array_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__array_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__class_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__class_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__class_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__pbase_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__pbase_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv117__pbase_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv119__pointer_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv119__pointer_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv119__pointer_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv120__function_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv120__function_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv120__function_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv120__si_class_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv120__si_class_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv120__si_class_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv121__vmi_class_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv123__fundamental_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv123__fundamental_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv123__fundamental_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD0Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD1Ev@@CXXABI_1.3 ++FUNC:_ZN10__cxxabiv129__pointer_to_member_type_infoD2Ev@@CXXABI_1.3 ++FUNC:_ZN10__gnu_norm15_List_node_base4hookEPS0_@@GLIBCXX_3.4 ++FUNC:_ZN10__gnu_norm15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4 ++FUNC:_ZN10__gnu_norm15_List_node_base6unhookEv@@GLIBCXX_3.4 ++FUNC:_ZN10__gnu_norm15_List_node_base7reverseEv@@GLIBCXX_3.4 ++FUNC:_ZN10__gnu_norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv@@GLIBCXX_3.4.9 ++FUNC:_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.9 ++FUNC:_ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv@@GLIBCXX_3.4.9 ++FUNC:_ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug19_Safe_iterator_base9_M_detachEv@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv@@GLIBCXX_3.4.9 ++FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_@@GLIBCXX_3.4 ++FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.26 ++FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17 ++FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17 ++FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17 ++FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_@@GLIBCXX_3.4.17 ++FUNC:_ZN14__gnu_parallel9_Settings3getEv@@GLIBCXX_3.4.10 ++FUNC:_ZN14__gnu_parallel9_Settings3setERS0_@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx12__atomic_addEPVii@@GLIBCXX_3.4 ++FUNC:_ZN9__gnu_cxx17__pool_alloc_base12_M_get_mutexEv@@GLIBCXX_3.4.2 ++FUNC:_ZN9__gnu_cxx17__pool_alloc_base16_M_get_free_listEm@@GLIBCXX_3.4.2 ++FUNC:_ZN9__gnu_cxx17__pool_alloc_base9_M_refillEm@@GLIBCXX_3.4.2 ++FUNC:_ZN9__gnu_cxx18__exchange_and_addEPVii@@GLIBCXX_3.4 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE4fileEv@@GLIBCXX_3.4.2 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE5uflowEv@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE6xsgetnEPcl@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE6xsputnEPKcl@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE8overflowEi@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE9pbackfailEi@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEE9underflowEv@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC1EP8_IO_FILE@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEC2EP8_IO_FILE@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE4fileEv@@GLIBCXX_3.4.2 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE5uflowEv@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE6xsgetnEPwl@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE6xsputnEPKwl@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE8overflowEj@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE9pbackfailEj@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEE9underflowEv@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC1EP8_IO_FILE@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEC2EP8_IO_FILE@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4.10 ++FUNC:_ZN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZN9__gnu_cxx27__verbose_terminate_handlerEv@@CXXABI_1.3 ++FUNC:_ZN9__gnu_cxx6__poolILb0EE10_M_destroyEv@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb0EE13_M_initializeEv@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb0EE16_M_reclaim_blockEPcm@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb0EE16_M_reserve_blockEmm@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE10_M_destroyEv@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEPFvPvE@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE13_M_initializeEv@@GLIBCXX_3.4.6 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_get_thread_idEv@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_reclaim_blockEPcm@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE16_M_reserve_blockEmm@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx6__poolILb1EE21_M_destroy_thread_keyEPv@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx9__freeresEv@@CXXABI_1.3.10 ++FUNC:_ZN9__gnu_cxx9free_list6_M_getEm@@GLIBCXX_3.4.4 ++FUNC:_ZN9__gnu_cxx9free_list8_M_clearEv@@GLIBCXX_3.4.4 ++FUNC:_ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv117__class_type_info12__do_dyncastElNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv117__class_type_info20__do_find_public_srcElPKvPKS0_S2_@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv117__pbase_type_info10__do_catchEPKSt9type_infoPPvj@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv117__pbase_type_info15__pointer_catchEPKS0_PPvj@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv119__pointer_type_info14__is_pointer_pEv@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv119__pointer_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv120__function_type_info15__is_function_pEv@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv120__si_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv120__si_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcElPKvPKNS_17__class_type_infoES2_@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv121__vmi_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv121__vmi_class_type_info20__do_find_public_srcElPKvPKNS_17__class_type_infoES2_@@CXXABI_1.3 ++FUNC:_ZNK10__cxxabiv129__pointer_to_member_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj@@CXXABI_1.3 ++FUNC:_ZNK11__gnu_debug16_Error_formatter10_M_messageENS_13_Debug_msg_idE@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug16_Error_formatter10_Parameter14_M_print_fieldEPKS0_PKc@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug16_Error_formatter10_Parameter20_M_print_descriptionEPKS0_@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug16_Error_formatter13_M_print_wordEPKc@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug16_Error_formatter15_M_print_stringEPKc@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug16_Error_formatter17_M_get_max_lengthEv@@GLIBCXX_3.4.10 ++FUNC:_ZNK11__gnu_debug16_Error_formatter8_M_errorEv@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug19_Safe_iterator_base11_M_singularEv@@GLIBCXX_3.4 ++FUNC:_ZNK11__gnu_debug19_Safe_iterator_base14_M_can_compareERKS0_@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.5 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_m@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_m@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEmmPKc@@GLIBCXX_3.4.5 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEmmPKc@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_m@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_m@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4cendEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_m@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5crendEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5emptyEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.15 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_m@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6cbeginEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6substrEmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmRKS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmRKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7crbeginEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEmPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv@@GLIBCXX_3.4 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS0_EEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4 ++FUNC:_ZNKSi6gcountEv@@GLIBCXX_3.4 ++FUNC:_ZNKSi6sentrycvbEv@@GLIBCXX_3.4 ++FUNC:_ZNKSo6sentrycvbEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs11_M_disjunctEPKc@@GLIBCXX_3.4.5 ++FUNC:_ZNKSs11_M_disjunctEPKc@GLIBCXX_3.4 ++FUNC:_ZNKSs12find_last_ofEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs12find_last_ofEPKcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs12find_last_ofERKSsm@@GLIBCXX_3.4 ++FUNC:_ZNKSs12find_last_ofEcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs13find_first_ofEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs13find_first_ofEPKcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs13find_first_ofERKSsm@@GLIBCXX_3.4 ++FUNC:_ZNKSs13find_first_ofEcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs13get_allocatorEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs15_M_check_lengthEmmPKc@@GLIBCXX_3.4.5 ++FUNC:_ZNKSs15_M_check_lengthEmmPKc@GLIBCXX_3.4 ++FUNC:_ZNKSs16find_last_not_ofEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs16find_last_not_ofEPKcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs16find_last_not_ofERKSsm@@GLIBCXX_3.4 ++FUNC:_ZNKSs16find_last_not_ofEcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs17find_first_not_ofEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs17find_first_not_ofEPKcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs17find_first_not_ofERKSsm@@GLIBCXX_3.4 ++FUNC:_ZNKSs17find_first_not_ofEcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs2atEm@@GLIBCXX_3.4 ++FUNC:_ZNKSs3endEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs4_Rep12_M_is_leakedEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs4_Rep12_M_is_sharedEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs4backEv@@GLIBCXX_3.4.15 ++FUNC:_ZNKSs4cendEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSs4copyEPcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs4dataEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs4findEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs4findEPKcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs4findERKSsm@@GLIBCXX_3.4 ++FUNC:_ZNKSs4findEcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs4rendEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs4sizeEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs5beginEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs5c_strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs5crendEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSs5emptyEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs5frontEv@@GLIBCXX_3.4.15 ++FUNC:_ZNKSs5rfindEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs5rfindEPKcmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs5rfindERKSsm@@GLIBCXX_3.4 ++FUNC:_ZNKSs5rfindEcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs6_M_repEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs6cbeginEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSs6lengthEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs6rbeginEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs6substrEmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs7_M_dataEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs7_M_iendEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs7compareEPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSs7compareERKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSs7compareEmmPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSs7compareEmmPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSs7compareEmmRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSs7compareEmmRKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs7crbeginEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSs8_M_checkEmPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSs8_M_limitEmm@@GLIBCXX_3.4 ++FUNC:_ZNKSs8capacityEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs8max_sizeEv@@GLIBCXX_3.4 ++FUNC:_ZNKSs9_M_ibeginEv@@GLIBCXX_3.4 ++FUNC:_ZNKSscvSt17basic_string_viewIcSt11char_traitsIcEEEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSsixEm@@GLIBCXX_3.4 ++FUNC:_ZNKSt10bad_typeid4whatEv@@GLIBCXX_3.4.9 ++FUNC:_ZNKSt10error_code23default_error_conditionEv@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt10filesystem16filesystem_error4whatEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem16filesystem_error5path1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem16filesystem_error5path2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem18directory_iteratordeEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem28recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem28recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem28recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem28recursive_directory_iteratordeEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path11parent_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path12has_filenameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path13has_root_nameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path13has_root_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path13relative_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path14root_directoryEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path15has_parent_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path16lexically_normalEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path17_M_find_extensionEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path17has_relative_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path18has_root_directoryEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path18lexically_relativeERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path19lexically_proximateERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path5_List3endEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path5_List5beginEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path7compareERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path9root_nameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem4path9root_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error4whatEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1118directory_iteratordeEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path11parent_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path12has_filenameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path13has_root_nameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path13has_root_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path13relative_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path14root_directoryEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path15has_parent_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path16lexically_normalEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path17_M_find_extensionEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path17has_relative_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path18has_root_directoryEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path18lexically_relativeERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path19lexically_proximateERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path5_List3endEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path5_List5beginEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path7compareERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path9root_nameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10filesystem7__cxx114path9root_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt10istrstream5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10lock_error4whatEv@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt10moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE10pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE11curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE11do_groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE11frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE13decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE13do_neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE13do_pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE13negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE13positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE13thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE14do_curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE14do_frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE16do_decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE16do_negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE16do_positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE16do_thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb0EE8groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE10neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE10pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE11curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE11do_groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE11frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE13decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE13do_neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE13do_pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE13negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE13positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE13thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE14do_curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE14do_frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE16do_decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE16do_negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE16do_positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE16do_thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIcLb1EE8groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE10neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE10pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE11curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE11do_groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE11frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE13decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE13do_neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE13do_pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE13negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE13positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE13thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE14do_curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE14do_frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE16do_decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE16do_negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE16do_positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE16do_thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb0EE8groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE10neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE10pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE11curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE11do_groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE11frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE13decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE13do_neg_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE13do_pos_formatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE13negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE13positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE13thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE14do_curr_symbolEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE14do_frac_digitsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE16do_decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE16do_negative_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE16do_positive_signEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE16do_thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10moneypunctIwLb1EE8groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10ostrstream5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt10ostrstream6pcountEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE15_M_am_pm_formatEPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE15_M_date_formatsEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE15_M_time_formatsEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE19_M_days_abbreviatedEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE20_M_date_time_formatsEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE21_M_months_abbreviatedEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE6_M_putEPcmPKcPK2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE7_M_daysEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE8_M_am_pmEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIcE9_M_monthsEPPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE15_M_am_pm_formatEPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE15_M_date_formatsEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE15_M_time_formatsEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE19_M_days_abbreviatedEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE20_M_date_time_formatsEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE21_M_months_abbreviatedEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE6_M_putEPwmPKwPK2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE7_M_daysEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE8_M_am_pmEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11__timepunctIwE9_M_monthsEPPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt11logic_error4whatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt12__basic_fileIcE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt12bad_weak_ptr4whatEv@@GLIBCXX_3.4.15 ++FUNC:_ZNKSt12future_error4whatEv@@GLIBCXX_3.4.14 ++FUNC:_ZNKSt12strstreambuf6pcountEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13bad_exception4whatEv@@GLIBCXX_3.4.9 ++FUNC:_ZNKSt13basic_filebufIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_filebufIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4.5 ++FUNC:_ZNKSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4.5 ++FUNC:_ZNKSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_istreamIwSt11char_traitsIwEE6gcountEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_istreamIwSt11char_traitsIwEE6sentrycvbEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13basic_ostreamIwSt11char_traitsIwEE6sentrycvbEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt13random_device13_M_getentropyEv@@GLIBCXX_3.4.25 ++FUNC:_ZNKSt13runtime_error4whatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4.5 ++FUNC:_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4.5 ++FUNC:_ZNKSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4.5 ++FUNC:_ZNKSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4.5 ++FUNC:_ZNKSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@GLIBCXX_3.4 ++FUNC:_ZNKSt14error_category10equivalentERKSt10error_codei@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt14error_category10equivalentEiRKSt15error_condition@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt14error_category23default_error_conditionEi@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt15__exception_ptr13exception_ptr20__cxa_exception_typeEv@@CXXABI_1.3.3 ++FUNC:_ZNKSt15__exception_ptr13exception_ptrcvMS0_FvvEEv@@CXXABI_1.3.3 ++FUNC:_ZNKSt15__exception_ptr13exception_ptrntEv@@CXXABI_1.3.3 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE4gptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5ebackEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5epptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIcSt11char_traitsIcEE6getlocEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE4gptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE4pptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5ebackEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5egptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5epptrEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5pbaseEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE6getlocEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt16bad_array_length4whatEv@@CXXABI_1.3.8 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16_M_extract_floatES4_S4_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8__do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16_M_extract_floatES4_S4_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8__do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE12_M_group_intEPKcmcRSt8ios_basePcSA_Ri@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES4_S4_RSt8ios_basecT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES4_S4_RSt8ios_basecT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES4_S4_RSt8ios_basecT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES4_S4_RSt8ios_basecT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE14_M_group_floatEPKcmcS7_PcS8_Ri@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES4_S4_RSt8ios_baseccT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIgEES4_S4_RSt8ios_baseccT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecPKv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_RSt8ios_basecy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6_M_padEclRSt8ios_basePcPKcRi@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecPKv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_RSt8ios_basecy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE8__do_putES4_RSt8ios_basecd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE12_M_group_intEPKcmwRSt8ios_basePwSA_Ri@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES4_S4_RSt8ios_basewT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES4_S4_RSt8ios_basewT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES4_S4_RSt8ios_basewT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES4_S4_RSt8ios_basewT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE14_M_group_floatEPKcmwPKwPwSA_Ri@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES4_S4_RSt8ios_basewcT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIgEES4_S4_RSt8ios_basewcT_@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewPKv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_RSt8ios_basewy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6_M_padEwlRSt8ios_basePwPKwRi@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewPKv@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewb@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewl@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewm@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewx@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_RSt8ios_basewy@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE8__do_putES4_RSt8ios_basewd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8__do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRSbIwS3_SaIwEE@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRSbIwS3_SaIwEE@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8__do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basecRKSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basecg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecRKSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE8__do_putES4_bRSt8ios_basecd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKSs@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewRKSbIwS3_SaIwEE@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewRKSbIwS3_SaIwEE@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE8__do_putES4_bRSt8ios_basewd@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKSbIwS3_SaIwEE@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNKSt17bad_function_call4whatEv@@GLIBCXX_3.4.18 ++FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDiE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIDsE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19__codecvt_utf8_baseIwE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt19basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_istringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_istringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDiE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIDsE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20__codecvt_utf16_baseIwE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt20bad_array_new_length4whatEv@@CXXABI_1.3.8 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE5do_inER11__mbstate_tPKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE6do_outER11__mbstate_tPKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDiE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE5do_inER11__mbstate_tPKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE6do_outER11__mbstate_tPKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIDsE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE10do_unshiftER11__mbstate_tPcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE5do_inER11__mbstate_tPKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE6do_outER11__mbstate_tPKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt25__codecvt_utf8_utf16_baseIwE9do_lengthER11__mbstate_tPKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3_V214error_category10_M_messageB5cxx11Ei@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3_V214error_category10_M_messageEi@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3_V214error_category10equivalentERKSt10error_codei@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3_V214error_category10equivalentEiRKSt15error_condition@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3_V214error_category23default_error_conditionEi@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3tr14hashINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEclES6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3tr14hashINSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEEclES6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt3tr14hashIRKSbIwSt11char_traitsIwESaIwEEEclES6_@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt3tr14hashIRKSsEclES2_@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt3tr14hashISbIwSt11char_traitsIwESaIwEEEclES4_@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt3tr14hashISsEclESs@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt3tr14hashIeEclEe@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt3tr14hashIgEclEg@@GLIBCXX_LDBL_3.4.10 ++FUNC:_ZNKSt4hashIRKSbIwSt11char_traitsIwESaIwEEEclES5_@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt4hashIRKSsEclES1_@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt4hashISbIwSt11char_traitsIwESaIwEEEclES3_@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt4hashISsEclESs@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt4hashISt10error_codeEclES0_@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt4hashIeEclEe@@GLIBCXX_3.4.10 ++FUNC:_ZNKSt4hashIgEclEg@@GLIBCXX_LDBL_3.4.10 ++FUNC:_ZNKSt5ctypeIcE10do_tolowerEPcPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE10do_tolowerEc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE10do_toupperEPcPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE10do_toupperEc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE13_M_widen_initEv@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt5ctypeIcE14_M_narrow_initEv@@GLIBCXX_3.4.11 ++FUNC:_ZNKSt5ctypeIcE8do_widenEPKcS2_Pc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE8do_widenEc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE9do_narrowEPKcS2_cPc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIcE9do_narrowEcc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE10do_scan_isEtPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE10do_tolowerEPwPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE10do_tolowerEw@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE10do_toupperEPwPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE10do_toupperEw@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE11do_scan_notEtPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE19_M_convert_to_wmaskEt@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE5do_isEPKwS2_Pt@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE5do_isEtw@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE8do_widenEPKcS2_Pw@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE8do_widenEc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE9do_narrowEPKwS2_cPc@@GLIBCXX_3.4 ++FUNC:_ZNKSt5ctypeIwE9do_narrowEwc@@GLIBCXX_3.4 ++FUNC:_ZNKSt6locale2id5_M_idEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt6locale4nameB5cxx11Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt6locale4nameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt6localeeqERKS_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE10pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11do_groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE11frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13do_neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13do_pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE13thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE14do_curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE14do_frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE16do_thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb0EE8groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE10neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE10pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11do_groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE11frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13do_neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13do_pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE13thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE14do_curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE14do_frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE16do_thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIcLb1EE8groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE10neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE10pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11do_groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE11frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13do_neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13do_pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE13thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE14do_curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE14do_frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE16do_thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb0EE8groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE10neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE10pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11do_groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE11frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13do_neg_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13do_pos_formatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE13thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE14do_curr_symbolEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE14do_frac_digitsEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_negative_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_positive_signEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE16do_thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1110moneypunctIwLb1EE8groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_disjunctEPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_is_localEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEPKcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12find_last_ofEcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13get_allocatorEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE15_M_check_lengthEmmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEPKcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16find_last_not_ofEcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEPKcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17find_first_not_ofEcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4cendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4copyEPcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4sizeEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5crendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5emptyEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5frontEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6cbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6rbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6substrEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_M_dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEmmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEmmPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEmmRKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEmmRKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7crbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_limitEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8capacityEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8max_sizeEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEcvSt17basic_string_viewIcS2_EEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_is_localEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEPKwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12find_last_ofEwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEPKwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13find_first_ofEwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13get_allocatorEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE15_M_check_lengthEmmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16find_last_not_ofEwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17find_first_not_ofEwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4cendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4copyEPwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEPKwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4findEwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4sizeEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5c_strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5crendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5emptyEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEPKwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindERKS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5rfindEwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6cbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6substrEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_M_dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEmmPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEmmPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEmmRKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7compareEmmRKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7crbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_checkEmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS2_EEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE10_M_compareEPKcS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE10do_compareEPKcS3_S3_S3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE12_M_transformEPcPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE12do_transformEPKcS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE4hashEPKcS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE7compareEPKcS3_S3_S3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE7do_hashEPKcS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIcE9transformEPKcS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE10_M_compareEPKwS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE10do_compareEPKwS3_S3_S3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE12_M_transformEPwPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE12do_transformEPKwS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE4hashEPKwS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE7compareEPKwS3_S3_S3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE7do_hashEPKwS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx117collateIwE9transformEPKwS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE18_M_convert_to_charERKNS_12basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE20_M_convert_from_charEPc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE3getEiiiRKNS_12basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6localePKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE5closeEi@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE6do_getEiiiRKNS_12basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE7do_openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIcE8do_closeEi@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE18_M_convert_to_charERKNS_12basic_stringIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE20_M_convert_from_charEPc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE3getEiiiRKNS_12basic_stringIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE4openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6localePKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE5closeEi@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE6do_getEiiiRKNS_12basic_stringIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE7do_openERKNS_12basic_stringIcSt11char_traitsIcESaIcEEERKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118messagesIwE8do_closeEi@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE11do_groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE11do_truenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE12do_falsenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE13decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE13thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE16do_decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE16do_thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE8groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE8truenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIcE9falsenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE11do_groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE11do_truenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE12do_falsenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE13decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE13thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE16do_decimal_pointEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE16do_thousands_sepEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE8groupingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE8truenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118numpunctIwE9falsenameEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10date_orderEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13do_date_orderEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_numES4_S4_RiiimRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES4_S4_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES4_S4_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSD_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10date_orderEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13do_date_orderEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_numES4_S4_RiiimRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_weekdayES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES4_S4_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES4_S4_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSD_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES4_S4_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS2_IcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES4_S4_S4_RSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIcS2_IcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES4_S4_bRSt8ios_baseRSt12_Ios_IostateRg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES4_bRSt8ios_basecg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES4_S4_RSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES4_S4_RSt8ios_basecRKNS_12basic_stringIcS3_SaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES4_bRSt8ios_basewg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewg@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE6do_outERS0_PKDiS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE9do_lengthERS0_PKDuS4_m@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE5do_inERS0_PKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE6do_outERS0_PKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDic11__mbstate_tE9do_lengthERS0_PKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE6do_outERS0_PKDsS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE9do_lengthERS0_PKDuS4_m@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE5do_inERS0_PKcS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE6do_outERS0_PKDsS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE9do_lengthERS0_PKcS4_m@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE5do_inERS0_PKcS4_RS4_PcS6_RS6_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE6do_outERS0_PKcS4_RS4_PcS6_RS6_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIcc11__mbstate_tE9do_lengthERS0_PKcS4_m@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE5do_inERS0_PKcS4_RS4_PwS6_RS6_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE6do_outERS0_PKwS4_RS4_PcS6_RS6_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7codecvtIwc11__mbstate_tE9do_lengthERS0_PKcS4_m@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE10_M_compareEPKcS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE10do_compareEPKcS2_S2_S2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE12_M_transformEPcPKcm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE12do_transformEPKcS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE4hashEPKcS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE7compareEPKcS2_S2_S2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE7do_hashEPKcS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIcE9transformEPKcS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE10_M_compareEPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE10do_compareEPKwS2_S2_S2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE12_M_transformEPwPKwm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE12do_transformEPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE4hashEPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE7compareEPKwS2_S2_S2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE7do_hashEPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7collateIwE9transformEPKwS2_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIjEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIlEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intImEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intItEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIxEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_intIyEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16_M_extract_floatES3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRPv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRf@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRj@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRt@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateRy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE12_M_group_intEPKcmcRSt8ios_basePcS9_Ri@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIxEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIyEES3_S3_RSt8ios_basecT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE14_M_group_floatEPKcmcS6_PcS7_Ri@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIeEES3_S3_RSt8ios_baseccT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPKv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basece@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6_M_padEclRSt8ios_basePcPKcRi@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecPKv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basece@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE12_M_group_intEPKcmwRSt8ios_basePwS9_Ri@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIlEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intImEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIxEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE13_M_insert_intIyEES3_S3_RSt8ios_basewT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE14_M_group_floatEPKcmwPKwPwS9_Ri@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIdEES3_S3_RSt8ios_basewcT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE15_M_insert_floatIeEES3_S3_RSt8ios_basewcT_@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPKv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewe@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewy@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6_M_padEwlRSt8ios_basePwPKwRi@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewPKv@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewb@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewd@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewe@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewl@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewm@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewx@@GLIBCXX_3.4 ++FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewy@@GLIBCXX_3.4 ++FUNC:_ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm@@GLIBCXX_3.4.18 ++FUNC:_ZNKSt8__detail20_Prime_rehash_policy14_M_need_rehashEmmm@@GLIBCXX_3.4.18 ++FUNC:_ZNKSt8bad_cast4whatEv@@GLIBCXX_3.4.9 ++FUNC:_ZNKSt8ios_base7failure4whatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8ios_base7failureB5cxx114whatEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt8messagesIcE18_M_convert_to_charERKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE20_M_convert_from_charEPc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE3getEiiiRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE4openERKSsRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE4openERKSsRKSt6localePKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE5closeEi@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE6do_getEiiiRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE7do_openERKSsRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIcE8do_closeEi@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE18_M_convert_to_charERKSbIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE20_M_convert_from_charEPc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE3getEiiiRKSbIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE4openERKSsRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE4openERKSsRKSt6localePKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE5closeEi@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE6do_getEiiiRKSbIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE7do_openERKSsRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNKSt8messagesIwE8do_closeEi@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE11do_groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE11do_truenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE12do_falsenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE13decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE13thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE16do_decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE16do_thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE8groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE8truenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIcE9falsenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE11do_groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE11do_truenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE12do_falsenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE13decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE13thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE16do_decimal_pointEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE16do_thousands_sepEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE8groupingEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE8truenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8numpunctIwE9falsenameEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10date_orderEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11do_get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE11get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13do_date_orderEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE13get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14_M_extract_numES3_S3_RiiimRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES3_S3_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSC_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10date_orderEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11do_get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE11get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13do_date_orderEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE13get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14_M_extract_numES3_S3_RiiimRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_weekdayES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES3_S3_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSC_@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPK2tmPKcSB_@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPK2tmcc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecPK2tmcc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPK2tmPKwSB_@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_RSt8ios_basewPK2tmcc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewPK2tmcc@@GLIBCXX_3.4 ++FUNC:_ZNKSt8valarrayImE4sizeEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9bad_alloc4whatEv@@GLIBCXX_3.4.9 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE10exceptionsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3badEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3eofEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE3tieEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4failEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE4goodEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEc@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE6narrowEcc@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEcvbEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt9basic_iosIcSt11char_traitsIcEEntEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE10exceptionsEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3badEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3eofEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE3tieEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4failEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4fillEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE4goodEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE5widenEc@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE6narrowEwc@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEE7rdstateEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEcvPvEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEcvbEv@@GLIBCXX_3.4.21 ++FUNC:_ZNKSt9basic_iosIwSt11char_traitsIwEEntEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9exception4whatEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb0EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE10_M_extractILb1EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSbIwS2_SaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRSbIwS2_SaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_bRSt8ios_baseRSt12_Ios_IostateRe@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_bRSt8ios_basecRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_bRSt8ios_basece@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basecRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basece@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb1EEES3_S3_RSt8ios_basecRKSs@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_bRSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE3putES3_bRSt8ios_basewe@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_bRSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_bRSt8ios_basewe@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE@@GLIBCXX_3.4 ++FUNC:_ZNKSt9strstream5rdbufEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9strstream6pcountEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9type_info10__do_catchEPKS_PPvj@@GLIBCXX_3.4 ++FUNC:_ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9type_info14__is_pointer_pEv@@GLIBCXX_3.4 ++FUNC:_ZNKSt9type_info15__is_function_pEv@@GLIBCXX_3.4 ++FUNC:_ZNSaIcEC1ERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSaIcEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIcEC2ERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSaIcEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIwEC1ERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSaIwEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIwEC2ERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSaIwEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSaIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEmm@@GLIBCXX_3.4.16 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEmwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iteratorIPwS2_EEEES6_T_S8_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEmmPKwm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EmwRKS1_@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEm@@GLIBCXX_3.4.5 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEm@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_m@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEmmRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5clearEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EE@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEmm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.15 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEOS2_@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EESt16initializer_listIwE@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEmPKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEmPKwm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEmRKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEmRKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6insertEmmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6resizeEm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6resizeEmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwm@@GLIBCXX_3.4.5 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwm@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEv@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwm@@GLIBCXX_3.4.5 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwm@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_St16initializer_listIwE@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_mw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmPKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmPKwm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmRKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmRKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmmw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7reserveEm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE8pop_backEv@@GLIBCXX_3.4.17 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@@GLIBCXX_3.4.5 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEmmm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_RKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwmRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_RKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mRKS1_@@GLIBCXX_3.4.23 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mmRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS1_@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EmwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_@@GLIBCXX_3.4.15 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_RKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwmRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_RKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mRKS1_@@GLIBCXX_3.4.23 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mmRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS1_@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EmwRKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPKwEET_S6_RKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPwEET_S5_RKS1_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEOS2_@@GLIBCXX_3.4.14 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLEPKw@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE@@GLIBCXX_3.4.11 ++FUNC:_ZNSbIwSt11char_traitsIwESaIwEEpLEw@@GLIBCXX_3.4 ++FUNC:_ZNSd4swapERSd@@GLIBCXX_3.4.21 ++FUNC:_ZNSdC1EOSd@@GLIBCXX_3.4.21 ++FUNC:_ZNSdC1EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSdC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSdC2EOSd@@GLIBCXX_3.4.21 ++FUNC:_ZNSdC2EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSdC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSdD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSdD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSdD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSdaSEOSd@@GLIBCXX_3.4.21 ++FUNC:_ZNSi10_M_extractIPvEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIbEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIdEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIeEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIfEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIgEERSiRT_@@GLIBCXX_LDBL_3.4.7 ++FUNC:_ZNSi10_M_extractIjEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIlEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractImEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractItEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIxEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi10_M_extractIyEERSiRT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSi3getEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSi3getEPclc@@GLIBCXX_3.4 ++FUNC:_ZNSi3getERSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSi3getERSt15basic_streambufIcSt11char_traitsIcEEc@@GLIBCXX_3.4 ++FUNC:_ZNSi3getERc@@GLIBCXX_3.4 ++FUNC:_ZNSi3getEv@@GLIBCXX_3.4 ++FUNC:_ZNSi4peekEv@@GLIBCXX_3.4 ++FUNC:_ZNSi4readEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSi4swapERSi@@GLIBCXX_3.4.21 ++FUNC:_ZNSi4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSi5seekgESt4fposI11__mbstate_tE@@GLIBCXX_3.4 ++FUNC:_ZNSi5seekgElSt12_Ios_Seekdir@@GLIBCXX_3.4 ++FUNC:_ZNSi5tellgEv@@GLIBCXX_3.4 ++FUNC:_ZNSi5ungetEv@@GLIBCXX_3.4 ++FUNC:_ZNSi6ignoreEl@@GLIBCXX_3.4.5 ++FUNC:_ZNSi6ignoreEl@GLIBCXX_3.4 ++FUNC:_ZNSi6ignoreEli@@GLIBCXX_3.4 ++FUNC:_ZNSi6ignoreEv@@GLIBCXX_3.4.5 ++FUNC:_ZNSi6ignoreEv@GLIBCXX_3.4 ++FUNC:_ZNSi6sentryC1ERSib@@GLIBCXX_3.4 ++FUNC:_ZNSi6sentryC2ERSib@@GLIBCXX_3.4 ++FUNC:_ZNSi7getlineEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSi7getlineEPclc@@GLIBCXX_3.4 ++FUNC:_ZNSi7putbackEc@@GLIBCXX_3.4 ++FUNC:_ZNSi8readsomeEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSiC1EOSi@@GLIBCXX_3.4.21 ++FUNC:_ZNSiC1EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSiC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSiC2EOSi@@GLIBCXX_3.4.21 ++FUNC:_ZNSiC2EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSiC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSiD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSiD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSiD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSiaSEOSi@@GLIBCXX_3.4.21 ++FUNC:_ZNSirsEPFRSiS_E@@GLIBCXX_3.4 ++FUNC:_ZNSirsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4 ++FUNC:_ZNSirsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4 ++FUNC:_ZNSirsEPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSirsERPv@@GLIBCXX_3.4 ++FUNC:_ZNSirsERb@@GLIBCXX_3.4 ++FUNC:_ZNSirsERd@@GLIBCXX_3.4 ++FUNC:_ZNSirsERe@@GLIBCXX_3.4 ++FUNC:_ZNSirsERf@@GLIBCXX_3.4 ++FUNC:_ZNSirsERg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSirsERi@@GLIBCXX_3.4 ++FUNC:_ZNSirsERj@@GLIBCXX_3.4 ++FUNC:_ZNSirsERl@@GLIBCXX_3.4 ++FUNC:_ZNSirsERm@@GLIBCXX_3.4 ++FUNC:_ZNSirsERs@@GLIBCXX_3.4 ++FUNC:_ZNSirsERt@@GLIBCXX_3.4 ++FUNC:_ZNSirsERx@@GLIBCXX_3.4 ++FUNC:_ZNSirsERy@@GLIBCXX_3.4 ++FUNC:_ZNSo3putEc@@GLIBCXX_3.4 ++FUNC:_ZNSo4swapERSo@@GLIBCXX_3.4.21 ++FUNC:_ZNSo5flushEv@@GLIBCXX_3.4 ++FUNC:_ZNSo5seekpESt4fposI11__mbstate_tE@@GLIBCXX_3.4 ++FUNC:_ZNSo5seekpElSt12_Ios_Seekdir@@GLIBCXX_3.4 ++FUNC:_ZNSo5tellpEv@@GLIBCXX_3.4 ++FUNC:_ZNSo5writeEPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSo6sentryC1ERSo@@GLIBCXX_3.4 ++FUNC:_ZNSo6sentryC2ERSo@@GLIBCXX_3.4 ++FUNC:_ZNSo6sentryD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSo6sentryD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSo8_M_writeEPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSo9_M_insertIPKvEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertIbEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertIdEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertIeEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertIgEERSoT_@@GLIBCXX_LDBL_3.4.7 ++FUNC:_ZNSo9_M_insertIlEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertImEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertIxEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSo9_M_insertIyEERSoT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSoC1EOSo@@GLIBCXX_3.4.21 ++FUNC:_ZNSoC1EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSoC1ERSd@@GLIBCXX_3.4.21 ++FUNC:_ZNSoC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSoC2EOSo@@GLIBCXX_3.4.21 ++FUNC:_ZNSoC2EPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSoC2ERSd@@GLIBCXX_3.4.21 ++FUNC:_ZNSoC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSoD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSoD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSoD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSoaSEOSo@@GLIBCXX_3.4.21 ++FUNC:_ZNSolsEDn@@GLIBCXX_3.4.26 ++FUNC:_ZNSolsEPFRSoS_E@@GLIBCXX_3.4 ++FUNC:_ZNSolsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4 ++FUNC:_ZNSolsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4 ++FUNC:_ZNSolsEPKv@@GLIBCXX_3.4 ++FUNC:_ZNSolsEPSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++FUNC:_ZNSolsEb@@GLIBCXX_3.4 ++FUNC:_ZNSolsEd@@GLIBCXX_3.4 ++FUNC:_ZNSolsEe@@GLIBCXX_3.4 ++FUNC:_ZNSolsEf@@GLIBCXX_3.4 ++FUNC:_ZNSolsEg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSolsEi@@GLIBCXX_3.4 ++FUNC:_ZNSolsEj@@GLIBCXX_3.4 ++FUNC:_ZNSolsEl@@GLIBCXX_3.4 ++FUNC:_ZNSolsEm@@GLIBCXX_3.4 ++FUNC:_ZNSolsEs@@GLIBCXX_3.4 ++FUNC:_ZNSolsEt@@GLIBCXX_3.4 ++FUNC:_ZNSolsEx@@GLIBCXX_3.4 ++FUNC:_ZNSolsEy@@GLIBCXX_3.4 ++FUNC:_ZNSs10_S_compareEmm@@GLIBCXX_3.4.16 ++FUNC:_ZNSs12_Alloc_hiderC1EPcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSs12_Alloc_hiderC2EPcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSs12_M_leak_hardEv@@GLIBCXX_3.4 ++FUNC:_ZNSs12_S_constructEmcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 ++FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 ++FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 ++FUNC:_ZNSs12_S_empty_repEv@@GLIBCXX_3.4 ++FUNC:_ZNSs12__sv_wrapperC1ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSs12__sv_wrapperC2ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_@@GLIBCXX_3.4 ++FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_@@GLIBCXX_3.4 ++FUNC:_ZNSs13_S_copy_charsEPcPKcS1_@@GLIBCXX_3.4 ++FUNC:_ZNSs13_S_copy_charsEPcS_S_@@GLIBCXX_3.4 ++FUNC:_ZNSs13shrink_to_fitEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSs14_M_replace_auxEmmmc@@GLIBCXX_3.4 ++FUNC:_ZNSs15_M_replace_safeEmmPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSs17_S_to_string_viewESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSs18_S_construct_aux_2EmcRKSaIcE@@GLIBCXX_3.4.14 ++FUNC:_ZNSs2atEm@@GLIBCXX_3.4 ++FUNC:_ZNSs3endEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep10_M_destroyERKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep10_M_disposeERKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep10_M_refcopyEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep10_M_refdataEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep12_S_empty_repEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep13_M_set_leakedEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep15_M_set_sharableEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep26_M_set_length_and_sharableEm@@GLIBCXX_3.4.5 ++FUNC:_ZNSs4_Rep26_M_set_length_and_sharableEm@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEm@@GLIBCXX_3.4 ++FUNC:_ZNSs4_Rep9_S_createEmmRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSs4backEv@@GLIBCXX_3.4.15 ++FUNC:_ZNSs4dataEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSs4rendEv@@GLIBCXX_3.4 ++FUNC:_ZNSs4swapERSs@@GLIBCXX_3.4 ++FUNC:_ZNSs5beginEv@@GLIBCXX_3.4 ++FUNC:_ZNSs5clearEv@@GLIBCXX_3.4 ++FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE@@GLIBCXX_3.4 ++FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_@@GLIBCXX_3.4 ++FUNC:_ZNSs5eraseEmm@@GLIBCXX_3.4 ++FUNC:_ZNSs5frontEv@@GLIBCXX_3.4.15 ++FUNC:_ZNSs6appendEPKc@@GLIBCXX_3.4 ++FUNC:_ZNSs6appendEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSs6appendERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSs6appendERKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNSs6appendESt16initializer_listIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSs6appendEmc@@GLIBCXX_3.4 ++FUNC:_ZNSs6assignEOSs@@GLIBCXX_3.4.14 ++FUNC:_ZNSs6assignEPKc@@GLIBCXX_3.4 ++FUNC:_ZNSs6assignEPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSs6assignERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSs6assignERKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNSs6assignESt16initializer_listIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSs6assignEmc@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEESt16initializer_listIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEc@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEmc@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEmPKc@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEmPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEmRKSs@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEmRKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNSs6insertEmmc@@GLIBCXX_3.4 ++FUNC:_ZNSs6rbeginEv@@GLIBCXX_3.4 ++FUNC:_ZNSs6resizeEm@@GLIBCXX_3.4 ++FUNC:_ZNSs6resizeEmc@@GLIBCXX_3.4 ++FUNC:_ZNSs7_M_copyEPcPKcm@@GLIBCXX_3.4.5 ++FUNC:_ZNSs7_M_copyEPcPKcm@GLIBCXX_3.4 ++FUNC:_ZNSs7_M_dataEPc@@GLIBCXX_3.4 ++FUNC:_ZNSs7_M_leakEv@@GLIBCXX_3.4 ++FUNC:_ZNSs7_M_moveEPcPKcm@@GLIBCXX_3.4.5 ++FUNC:_ZNSs7_M_moveEPcPKcm@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKc@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcm@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1_@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2_@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_St16initializer_listIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_mc@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEmmPKc@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEmmPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEmmRKSs@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEmmRKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNSs7replaceEmmmc@@GLIBCXX_3.4 ++FUNC:_ZNSs7reserveEm@@GLIBCXX_3.4 ++FUNC:_ZNSs8pop_backEv@@GLIBCXX_3.4.17 ++FUNC:_ZNSs9_M_assignEPcmc@@GLIBCXX_3.4.5 ++FUNC:_ZNSs9_M_assignEPcmc@GLIBCXX_3.4 ++FUNC:_ZNSs9_M_mutateEmmm@@GLIBCXX_3.4 ++FUNC:_ZNSs9push_backEc@@GLIBCXX_3.4 ++FUNC:_ZNSsC1ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSsC1EOSs@@GLIBCXX_3.4.14 ++FUNC:_ZNSsC1EOSsRKSaIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1EPKcmRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1ERKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSsC1ERKSsRKSaIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSsC1ERKSsmRKSaIcE@@GLIBCXX_3.4.23 ++FUNC:_ZNSsC1ERKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNSsC1ERKSsmmRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1ESt16initializer_listIcERKSaIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSsC1EmcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC1IPcEET_S1_RKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSsC2EOSs@@GLIBCXX_3.4.15 ++FUNC:_ZNSsC2EOSsRKSaIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSsC2EPKcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2EPKcmRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2ERKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSsC2ERKSsRKSaIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSsC2ERKSsmRKSaIcE@@GLIBCXX_3.4.23 ++FUNC:_ZNSsC2ERKSsmm@@GLIBCXX_3.4 ++FUNC:_ZNSsC2ERKSsmmRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2ESt16initializer_listIcERKSaIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSsC2EmcRKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSsC2IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsC2IPcEET_S1_RKSaIcE@@GLIBCXX_3.4 ++FUNC:_ZNSsD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSsD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSsaSEOSs@@GLIBCXX_3.4.14 ++FUNC:_ZNSsaSEPKc@@GLIBCXX_3.4 ++FUNC:_ZNSsaSERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSsaSESt16initializer_listIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSsaSEc@@GLIBCXX_3.4 ++FUNC:_ZNSsixEm@@GLIBCXX_3.4 ++FUNC:_ZNSspLEPKc@@GLIBCXX_3.4 ++FUNC:_ZNSspLERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSspLESt16initializer_listIcE@@GLIBCXX_3.4.11 ++FUNC:_ZNSspLEc@@GLIBCXX_3.4 ++FUNC:_ZNSt10_Sp_lockerC1EPKv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt10_Sp_lockerC1EPKvS1_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt10_Sp_lockerC2EPKv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt10_Sp_lockerC2EPKvS1_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt10_Sp_lockerD1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt10_Sp_lockerD2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt10__num_base15_S_format_floatERKSt8ios_basePcc@@GLIBCXX_3.4 ++FUNC:_ZNSt10bad_typeidD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10bad_typeidD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10bad_typeidD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10hash_valueERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10remove_allERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10remove_allERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEmRSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEmRSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathB5cxx11Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12current_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIlSt5ratioILl1ELl1000000000EEEEEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIlSt5ratioILl1ELl1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIlSt5ratioILl1ELl1000000000EEEEEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIlSt5ratioILl1ELl1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorD0Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorD1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16filesystem_errorD2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem18directory_iteratorppEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem19temp_directory_pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem19temp_directory_pathEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iterator3popEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSEOS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSERKS0_@@GLIBCXX_3.4.27 ++FUNC:_ZNSt10filesystem28recursive_directory_iteratorppEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path14_M_split_cmptsEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path15remove_filenameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path16replace_filenameERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path17replace_extensionERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path5_ListC1ERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path5_ListC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4pathaSERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4pathdVERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem4pathpLERKS0_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem5spaceERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem5spaceERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6removeERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6removeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6statusERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD0Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1118directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorppEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSERKS1_@@GLIBCXX_3.4.27 ++FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path14_M_split_cmptsEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path15remove_filenameEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path16replace_filenameERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path17replace_extensionERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path5_ListC1ERKS2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path5_ListC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114pathaSERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114pathdVERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem7__cxx114pathpLERKS1_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8absoluteERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8absoluteERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9canonicalERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26 ++FUNC:_ZNSt10istrstream3strEv@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC1EPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC1EPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC1EPc@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC1EPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC2EPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC2EPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC2EPc@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamC2EPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10istrstreamD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10money_base20_S_construct_patternEccc@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EEC1EPSt18__moneypunct_cacheIcLb0EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EEC2EPSt18__moneypunct_cacheIcLb0EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb0EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EEC1EPSt18__moneypunct_cacheIcLb1EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EEC2EPSt18__moneypunct_cacheIcLb1EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIcLb1EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EEC1EPSt18__moneypunct_cacheIwLb0EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EEC2EPSt18__moneypunct_cacheIwLb0EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb0EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EEC1EPSt18__moneypunct_cacheIwLb1EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EEC2EPSt18__moneypunct_cacheIwLb1EEm@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10moneypunctIwLb1EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstream3strEv@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstream6freezeEb@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamC1EPciSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamC2EPciSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt10ostrstreamD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcE23_M_initialize_timepunctEP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcEC1EPSt17__timepunct_cacheIcEm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcEC2EPSt17__timepunct_cacheIcEm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwE23_M_initialize_timepunctEP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwEC1EPSt17__timepunct_cacheIwEm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwEC2EPSt17__timepunct_cacheIwEm@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11__timepunctIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@@GLIBCXX_3.4.5 ++FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@GLIBCXX_3.4 ++FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@@GLIBCXX_3.4.5 ++FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@GLIBCXX_3.4 ++FUNC:_ZNSt11logic_errorC1EOS_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11logic_errorC1ERKS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11logic_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt11logic_errorC2EOS_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt11logic_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11logic_errorC2ERKS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11logic_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt11logic_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11logic_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11logic_errorD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11logic_erroraSEOS_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt11logic_erroraSERKS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11range_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11range_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt11range_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11range_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11range_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt11range_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11range_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt11range_errorD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt11regex_errorC1ENSt15regex_constants10error_typeE@@GLIBCXX_3.4.20 ++FUNC:_ZNSt11regex_errorC2ENSt15regex_constants10error_typeE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt11regex_errorD0Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt11regex_errorD1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt11regex_errorD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt11this_thread11__sleep_forENSt6chrono8durationIlSt5ratioILl1ELl1EEEENS1_IlS2_ILl1ELl1000000000EEEE@@GLIBCXX_3.4.18 ++FUNC:_ZNSt12__basic_fileIcE2fdEv@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE4fileEv@@GLIBCXX_3.4.1 ++FUNC:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE6xsgetnEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE6xsputnEPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE7seekoffElSt12_Ios_Seekdir@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE8sys_openEP8_IO_FILESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE8sys_openEiSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE8xsputn_2EPKclS2_l@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcE9showmanycEv@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12__basic_fileIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_@@GLIBCXX_3.4.28 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS4_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS4_@@GLIBCXX_3.4.28 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS4_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS6_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2EOS6_@@GLIBCXX_3.4.28 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_@@GLIBCXX_3.4.28 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 ++FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt12ctype_bynameIcEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIcEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIcEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIcEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIcEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIcEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIwEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIwEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIwEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIwEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIwEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIwEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12ctype_bynameIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12ctype_bynameIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12domain_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12domain_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12domain_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt12domain_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12domain_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12domain_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt12domain_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12domain_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12domain_errorD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt12future_errorD0Ev@@GLIBCXX_3.4.14 ++FUNC:_ZNSt12future_errorD1Ev@@GLIBCXX_3.4.14 ++FUNC:_ZNSt12future_errorD2Ev@@GLIBCXX_3.4.14 ++FUNC:_ZNSt12length_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12length_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12length_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt12length_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12length_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12length_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt12length_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12length_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12length_errorD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt12out_of_rangeC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12out_of_rangeC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12out_of_rangeC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt12out_of_rangeC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12out_of_rangeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt12out_of_rangeC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt12out_of_rangeD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12out_of_rangeD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12out_of_rangeD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt12strstreambuf3strEv@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf6freezeEb@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf6setbufEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf7_M_freeEPc@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf8_M_allocEm@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf8_M_setupEPcS0_l@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf8overflowEi@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf9pbackfailEi@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambuf9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPFPvmEPFvS0_E@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPKal@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPKhl@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPalS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPclS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1EPhlS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC1El@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPFPvmEPFvS0_E@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPKal@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPKhl@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPalS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPclS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2EPhlS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufC2El@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12strstreambufD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt12system_errorD0Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt12system_errorD1Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt12system_errorD2Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt13__future_base11_State_baseD0Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base11_State_baseD1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base11_State_baseD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base12_Result_baseC1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base12_Result_baseC2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base12_Result_baseD0Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base12_Result_baseD1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base12_Result_baseD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13__future_base19_Async_state_commonD0Ev@@GLIBCXX_3.4.17 ++FUNC:_ZNSt13__future_base19_Async_state_commonD1Ev@@GLIBCXX_3.4.17 ++FUNC:_ZNSt13__future_base19_Async_state_commonD2Ev@@GLIBCXX_3.4.17 ++FUNC:_ZNSt13bad_exceptionD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13bad_exceptionD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13bad_exceptionD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE13_M_set_bufferEl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE14_M_get_ext_posER11__mbstate_t@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE15_M_create_pbackEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE16_M_destroy_pbackEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE19_M_terminate_outputEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE26_M_destroy_internal_bufferEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE27_M_allocate_internal_bufferEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6setbufEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6xsgetnEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE6xsputnEPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7_M_seekElSt12_Ios_Seekdir11__mbstate_t@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE8overflowEi@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9pbackfailEi@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9showmanycEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE13_M_set_bufferEl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE14_M_get_ext_posER11__mbstate_t@@GLIBCXX_3.4.15 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE15_M_create_pbackEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE16_M_destroy_pbackEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE19_M_terminate_outputEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE22_M_convert_to_externalEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE26_M_destroy_internal_bufferEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE27_M_allocate_internal_bufferEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6setbufEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6xsgetnEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE6xsputnEPKwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7_M_seekElSt12_Ios_Seekdir11__mbstate_t@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE8overflowEj@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9pbackfailEj@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9showmanycEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIPvEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIbEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIdEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIeEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIfEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIgEERS2_RT_@@GLIBCXX_LDBL_3.4.7 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIjEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIlEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractImEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractItEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIxEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractIyEERS2_RT_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEPwlw@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERSt15basic_streambufIwS1_Ew@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getERw@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE3getEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4peekEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4readEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5seekgESt4fposI11__mbstate_tE@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5seekgElSt12_Ios_Seekdir@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5tellgEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE5ungetEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl@@GLIBCXX_3.4.5 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreElj@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEv@@GLIBCXX_3.4.5 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEv@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6sentryC1ERS2_b@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE6sentryC2ERS2_b@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7getlineEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7getlineEPwlw@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE7putbackEw@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEE8readsomeEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRS2_S3_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERPv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERb@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERd@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERe@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERf@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERi@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERj@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERm@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERs@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERt@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERx@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_istreamIwSt11char_traitsIwEErsERy@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE3putEw@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5flushEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5seekpESt4fposI11__mbstate_tE@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5seekpElSt12_Ios_Seekdir@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5tellpEv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryC1ERS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryC2ERS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentryD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKwl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIPKvEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIbEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIdEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIeEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIgEERS2_T_@@GLIBCXX_LDBL_3.4.7 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIlEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertImEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIxEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertIyEERS2_T_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1ERSt14basic_iostreamIwS1_E@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2ERSt14basic_iostreamIwS1_E@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn@@GLIBCXX_3.4.26 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRS2_S3_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPKv@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEb@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEd@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEe@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEf@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEg@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEi@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEj@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEl@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEm@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEs@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEt@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEx@@GLIBCXX_3.4 ++FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEy@@GLIBCXX_3.4 ++FUNC:_ZNSt13random_device14_M_init_pretr1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13random_device14_M_init_pretr1ERKSs@@GLIBCXX_3.4.18 ++FUNC:_ZNSt13random_device16_M_getval_pretr1Ev@@GLIBCXX_3.4.18 ++FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18 ++FUNC:_ZNSt13random_device7_M_initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18 ++FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18 ++FUNC:_ZNSt13runtime_errorC1EOS_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13runtime_errorC1ERKS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt13runtime_errorC2EOS_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13runtime_errorC2ERKS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt13runtime_erroraSEOS_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt13runtime_erroraSERKS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKNSt7__cxx1112basic_stringIcS0_IcESaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIcc11__mbstate_tED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIcEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIcEC1ERKSsm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt14collate_bynameIcEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIcEC2ERKSsm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt14collate_bynameIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIwEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIwEC1ERKSsm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt14collate_bynameIwEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIwEC2ERKSsm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt14collate_bynameIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14collate_bynameIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14error_categoryC1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt14error_categoryC2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt14error_categoryD0Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt14error_categoryD1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt14error_categoryD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt14overflow_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14overflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14overflow_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt14overflow_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14overflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt14overflow_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt14overflow_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14overflow_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt14overflow_errorD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSt15_List_node_base11_M_transferEPS_S0_@@GLIBCXX_3.4.14 ++FUNC:_ZNSt15_List_node_base4hookEPS_@@GLIBCXX_3.4 ++FUNC:_ZNSt15_List_node_base4swapERS_S0_@@GLIBCXX_3.4 ++FUNC:_ZNSt15_List_node_base6unhookEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15_List_node_base7_M_hookEPS_@@GLIBCXX_3.4.14 ++FUNC:_ZNSt15_List_node_base7reverseEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15_List_node_base8transferEPS_S0_@@GLIBCXX_3.4 ++FUNC:_ZNSt15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSt15__exception_ptr13exception_ptr4swapERS0_@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC1EPv@@CXXABI_1.3.11 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC1ERKS0_@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC1Ev@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC2EMS0_FvvE@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC2ERKS0_@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrC2Ev@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrD1Ev@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptrD2Ev@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptr13exception_ptraSERKS0_@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptreqERKNS_13exception_ptrES2_@@CXXABI_1.3.3 ++FUNC:_ZNSt15__exception_ptrneERKNS_13exception_ptrES2_@@CXXABI_1.3.3 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_gbumpEl@@GLIBCXX_3.4.16 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_pbumpEl@@GLIBCXX_3.4.16 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setgEPcS3_S3_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setpEPcS3_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5gbumpEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5pbumpEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sgetcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sgetnEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sputcEc@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5sputnEPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE5uflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6sbumpcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6setbufEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6snextcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6stosscEv@@GLIBCXX_3.4.10 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsgetnEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7pubsyncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE7sungetcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8in_availEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8overflowEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE8pubimbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9pbackfailEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9pubsetbufEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9showmanycEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9sputbackcEc@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC1ERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC2ERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEaSERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_gbumpEl@@GLIBCXX_3.4.16 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_pbumpEl@@GLIBCXX_3.4.16 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setgEPwS3_S3_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setpEPwS3_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5gbumpEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5pbumpEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sgetcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sgetnEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sputcEw@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5sputnEPKwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE5uflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6sbumpcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6setbufEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6snextcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6stosscEv@@GLIBCXX_3.4.10 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6xsgetnEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE6xsputnEPKwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7pubsyncEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE7sungetcEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8in_availEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8overflowEj@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE8pubimbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9pbackfailEj@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9pubsetbufEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9showmanycEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9sputbackcEw@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC1ERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC2ERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEEaSERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE15_M_update_egptrEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPcl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcmm@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS4_l@@GLIBCXX_3.4.16 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv@@GLIBCXX_3.4.6 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE15_M_update_egptrEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwl@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwmm@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS4_l@@GLIBCXX_3.4.16 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv@@GLIBCXX_3.4.6 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15messages_bynameIcEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIcEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15messages_bynameIcEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIcEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15messages_bynameIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIwEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIwEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15messages_bynameIwEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIwEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15messages_bynameIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15messages_bynameIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIcEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIcEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15numpunct_bynameIcEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIcEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15numpunct_bynameIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIwEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIwEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15numpunct_bynameIwEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIwEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15numpunct_bynameIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15numpunct_bynameIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1ERKNSt7__cxx1112basic_stringIcS2_SaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2ERKNSt7__cxx1112basic_stringIcS2_SaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15underflow_errorC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15underflow_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15underflow_errorC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt15underflow_errorC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15underflow_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt15underflow_errorC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt15underflow_errorD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15underflow_errorD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt15underflow_errorD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIcEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIcEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIwE8_M_cacheERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16__numpunct_cacheIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16bad_array_lengthD0Ev@@CXXABI_1.3.8 ++FUNC:_ZNSt16bad_array_lengthD1Ev@@CXXABI_1.3.8 ++FUNC:_ZNSt16bad_array_lengthD2Ev@@CXXABI_1.3.8 ++FUNC:_ZNSt16invalid_argumentC1EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt16invalid_argumentC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt16invalid_argumentC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt16invalid_argumentC2EPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt16invalid_argumentC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt16invalid_argumentC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt16invalid_argumentD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16invalid_argumentD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt16invalid_argumentD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt16nested_exceptionD0Ev@@CXXABI_1.3.5 ++FUNC:_ZNSt16nested_exceptionD1Ev@@CXXABI_1.3.5 ++FUNC:_ZNSt16nested_exceptionD2Ev@@CXXABI_1.3.5 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_LDBL_3.4 ++FUNC:_ZNSt17__timepunct_cacheIcEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIcEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17__timepunct_cacheIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17bad_function_callD0Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt17bad_function_callD1Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt17bad_function_callD2Ev@@GLIBCXX_3.4.15 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb0EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIcLb1EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb0EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EEC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EEC1ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EEC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EEC2ERKSsm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt17moneypunct_bynameIwLb1EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb0EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb0EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb0EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb0EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb0EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb0EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb1EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb1EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb1EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb1EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb1EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIcLb1EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb0EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb0EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb0EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb0EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb0EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb0EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb1EE8_M_cacheERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb1EEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb1EEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb1EED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb1EED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18__moneypunct_cacheIwLb1EED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt18condition_variable10notify_allEv@@GLIBCXX_3.4.11 ++FUNC:_ZNSt18condition_variable10notify_oneEv@@GLIBCXX_3.4.11 ++FUNC:_ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE@@GLIBCXX_3.4.11 ++FUNC:_ZNSt18condition_variableC1Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt18condition_variableC2Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt18condition_variableD1Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt18condition_variableD2Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19__codecvt_utf8_baseIDiED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIDiED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIDiED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIDsED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIDsED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIDsED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19__codecvt_utf8_baseIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt19istreambuf_iteratorIcSt11char_traitsIcEEppEv@@GLIBCXX_3.4.5 ++FUNC:_ZNSt19istreambuf_iteratorIcSt11char_traitsIcEEppEv@GLIBCXX_3.4 ++FUNC:_ZNSt19istreambuf_iteratorIwSt11char_traitsIwEEppEv@@GLIBCXX_3.4.5 ++FUNC:_ZNSt19istreambuf_iteratorIwSt11char_traitsIwEEppEv@GLIBCXX_3.4 ++FUNC:_ZNSt20__codecvt_utf16_baseIDiED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIDiED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIDiED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIDsED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIDsED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIDsED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20__codecvt_utf16_baseIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt20bad_array_new_lengthD0Ev@@CXXABI_1.3.8 ++FUNC:_ZNSt20bad_array_new_lengthD1Ev@@CXXABI_1.3.8 ++FUNC:_ZNSt20bad_array_new_lengthD2Ev@@CXXABI_1.3.8 ++FUNC:_ZNSt22condition_variable_anyC1Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt22condition_variable_anyC2Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt22condition_variable_anyD1Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt22condition_variable_anyD2Ev@@GLIBCXX_3.4.11 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDiED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIDsED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt25__codecvt_utf8_utf16_baseIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt28__atomic_futex_unsigned_base19_M_futex_notify_allEPj@@GLIBCXX_3.4.21 ++FUNC:_ZNSt28__atomic_futex_unsigned_base19_M_futex_wait_untilEPjjbNSt6chrono8durationIlSt5ratioILl1ELl1EEEENS2_IlS3_ILl1ELl1000000000EEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt3_V214error_categoryD0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt3_V214error_categoryD1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt3_V214error_categoryD2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt3_V215system_categoryEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt3_V216generic_categoryEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt3pmr19new_delete_resourceEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr20get_default_resourceEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr20null_memory_resourceEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr25monotonic_buffer_resource13_M_new_bufferEmm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEmm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvmm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr26synchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resource11do_allocateEmm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resource13do_deallocateEPvmm@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt5ctypeIcE13classic_tableEv@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcEC1EP15__locale_structPKtbm@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcEC1EPKtbm@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcEC2EP15__locale_structPKtbm@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcEC2EPKtbm@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwE19_M_initialize_ctypeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt5ctypeIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6__norm15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSt6__norm15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.14 ++FUNC:_ZNSt6__norm15_List_node_base4hookEPS0_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt6__norm15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt6__norm15_List_node_base6unhookEv@@GLIBCXX_3.4.9 ++FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14 ++FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9 ++FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9 ++FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11 ++FUNC:_ZNSt6chrono3_V212steady_clock3nowEv@@GLIBCXX_3.4.19 ++FUNC:_ZNSt6chrono3_V212system_clock3nowEv@@GLIBCXX_3.4.19 ++FUNC:_ZNSt6gslice8_IndexerC1EmRKSt8valarrayImES4_@@GLIBCXX_3.4 ++FUNC:_ZNSt6gslice8_IndexerC2EmRKSt8valarrayImES4_@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale21_S_normalize_categoryEi@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_Impl16_M_install_cacheEPKNS_5facetEm@@GLIBCXX_3.4.7 ++FUNC:_ZNSt6locale5_Impl16_M_install_facetEPKNS_2idEPKNS_5facetE@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_Impl16_M_replace_facetEPKS0_PKNS_2idE@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_Impl19_M_replace_categoryEPKS0_PKPKNS_2idE@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_Impl21_M_replace_categoriesEPKS0_i@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplC1EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplC1ERKS0_m@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplC2EPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplC2ERKS0_m@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5_ImplD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facet13_S_get_c_nameEv@@GLIBCXX_3.4.6 ++FUNC:_ZNSt6locale5facet15_S_get_c_localeEv@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facet17_S_clone_c_localeERP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facet18_S_create_c_localeERP15__locale_structPKcS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facet19_S_destroy_c_localeERP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facetD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facetD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale5facetD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale6globalERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSt6locale7classicEv@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC1EPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC1EPNS_5_ImplE@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC1ERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC1ERKS_PKci@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC1ERKS_S1_i@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC2EPKc@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC2EPNS_5_ImplE@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC2ERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC2ERKS_PKci@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC2ERKS_S1_i@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4 ++FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11 ++FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFvvE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt6thread15_M_start_threadESt10unique_ptrINS_6_StateESt14default_deleteIS1_EEPFvvE@@GLIBCXX_3.4.22 ++FUNC:_ZNSt6thread20hardware_concurrencyEv@@GLIBCXX_3.4.17 ++FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11 ++FUNC:_ZNSt6thread6_StateD0Ev@@GLIBCXX_3.4.22 ++FUNC:_ZNSt6thread6_StateD1Ev@@GLIBCXX_3.4.22 ++FUNC:_ZNSt6thread6_StateD2Ev@@GLIBCXX_3.4.22 ++FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1EPSt18__moneypunct_cacheIcLb0EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2EPSt18__moneypunct_cacheIcLb0EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb0EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1EPSt18__moneypunct_cacheIcLb1EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2EPSt18__moneypunct_cacheIcLb1EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIcLb1EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1EPSt18__moneypunct_cacheIwLb0EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2EPSt18__moneypunct_cacheIwLb0EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb0EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EE24_M_initialize_moneypunctEP15__locale_structPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1EPSt18__moneypunct_cacheIwLb1EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2EPSt18__moneypunct_cacheIwLb1EEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1110moneypunctIwLb1EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_destroyEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_disposeEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEmmPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_S_compareEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_capacityEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcOS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcOS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKcS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC1ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC2ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_set_lengthEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcS4_EESA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS5_S4_EES8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcPKcS7_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcS5_S5_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13shrink_to_fitEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEmmmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17_S_to_string_viewESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE18_M_construct_aux_2Emc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5clearEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPKcS4_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPcS4_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5frontEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendESt16initializer_listIcE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignESt16initializer_listIcE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EEc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EEmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEmPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEmRKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEmRKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEmmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvS9_T_SA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6rbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_M_dataEPc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_S_copyEPcPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7_S_moveEPcPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_NS6_IPcS4_EESB_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_PcSA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_RKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_S8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S8_m@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_S9_S9_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_St16initializer_listIcE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPKcS4_EES9_mc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_NS6_IPKcS4_EESB_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKcSA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_PKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_RKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_S7_S7_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_S8_S8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEN9__gnu_cxx17__normal_iteratorIPcS4_EES8_mc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEmmPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEmmPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEmmRKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEmmRKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEmmmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_eraseEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8pop_backEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_assignERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_createERmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_lengthEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcmc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_mRKS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ERKS4_mmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ESt16initializer_listIcERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EmcRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_mRKS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ERKS4_mmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ESt16initializer_listIcERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EmcRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSESt16initializer_listIcE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEPKc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLESt16initializer_listIcE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEc@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_destroyEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_disposeEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_M_replaceEmmPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE10_S_compareEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_capacityEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwOS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwOS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructEmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKwS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPwEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_set_lengthEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS4_EESA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS5_S4_EES8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS7_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS5_S5_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE18_M_construct_aux_2Emw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5clearEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPKwS4_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS4_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5eraseEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6appendEmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EEmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EEw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEmPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEmPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEmRKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEmRKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEmmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvS9_T_SA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6resizeEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6resizeEmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_M_dataEPw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_S_copyEPwPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7_S_moveEPwPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_NS6_IPwS4_EESB_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_PwSA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_RKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_S8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S8_m@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_S9_S9_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_St16initializer_listIwE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPKwS4_EES9_mw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_NS6_IPKwS4_EESB_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKwSA_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_PKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_RKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_S7_S7_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_S8_S8_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS4_EES8_mw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEmmPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEmmPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEmmRKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEmmRKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7replaceEmmmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE7reserveEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_eraseEmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8pop_backEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_appendEPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_assignERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_createERmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_lengthEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_mutateEmmPKwm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_S_assignEPwmw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_mRKS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ERKS4_mmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EmwRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_mRKS3_@@GLIBCXX_3.4.23 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_mm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ERKS4_mmRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EmwRKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEaSEw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLEPKw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLERKS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEpLEw@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIcED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1114collate_bynameIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsC1ERKS4_PS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsC2ERKS4_PS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsD1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE14__xfer_bufptrsD2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE15_M_update_egptrEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPcl@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS5_l@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsC1ERKS4_PS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsC2ERKS4_PS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsD1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE14__xfer_bufptrsD2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE15_M_update_egptrEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE17_M_stringbuf_initESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwl@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwmm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS5_l@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIcED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115messages_bynameIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIcED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115numpunct_bynameIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1ERKNS_12basic_stringIcS3_SaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2ERKNS_12basic_stringIcS3_SaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1ERKNS_12basic_stringIcS2_IcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2ERKNS_12basic_stringIcS2_IcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb0EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIcLb1EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb0EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC1EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC1ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC2EPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EEC2ERKNS_12basic_stringIcSt11char_traitsIcESaIcEEEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1117moneypunct_bynameIwLb1EED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strERKNS_12basic_stringIcS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE3strERKNS_12basic_stringIwS2_S3_EE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEaSEOS4_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcEC1EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcEC2EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIcED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwEC1EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwEC2EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx117collateIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcEC1EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcEC2EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIcED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwEC1EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwEC2EP15__locale_structPKcm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118messagesIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcEC1EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcEC1EPSt16__numpunct_cacheIcEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcEC2EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcEC2EPSt16__numpunct_cacheIcEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIcED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwEC1EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwEC1EPSt16__numpunct_cacheIwEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwEC2EP15__locale_structm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwEC2EPSt16__numpunct_cacheIwEm@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118numpunctIwED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7codecvtIDic11__mbstate_tED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIDic11__mbstate_tED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIDic11__mbstate_tED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26 ++FUNC:_ZNSt7codecvtIDsc11__mbstate_tED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIDsc11__mbstate_tED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIDsc11__mbstate_tED2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIcc11__mbstate_tED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7codecvtIwc11__mbstate_tED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7collateIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8__detail15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.15 ++FUNC:_ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.15 ++FUNC:_ZNSt8__detail15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.15 ++FUNC:_ZNSt8__detail15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.15 ++FUNC:_ZNSt8__detail15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.15 ++FUNC:_ZNSt8bad_castD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8bad_castD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8bad_castD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base13_M_grow_wordsEib@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base15sync_with_stdioEb@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base17_M_call_callbacksENS_5eventE@@GLIBCXX_3.4.6 ++FUNC:_ZNSt8ios_base17register_callbackEPFvNS_5eventERS_iEi@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base20_M_dispose_callbacksEv@@GLIBCXX_3.4.6 ++FUNC:_ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base4InitC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base4InitD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base6xallocEv@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base7_M_initEv@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base7_M_moveERS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7_M_swapERS_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11C1EPKcRKSt10error_code@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10error_code@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11C2EPKcRKSt10error_code@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt10error_code@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11D0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11D1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureB5cxx11D2Ev@@GLIBCXX_3.4.21 ++FUNC:_ZNSt8ios_base7failureC1ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base7failureC2ERKSs@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base7failureD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base7failureD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_base7failureD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_baseC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_baseC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_baseD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_baseD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8ios_baseD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwEC1EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwEC2EP15__locale_structPKcm@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8messagesIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcEC1EPSt16__numpunct_cacheIcEm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcEC2EPSt16__numpunct_cacheIcEm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIcED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwE22_M_initialize_numpunctEP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwEC1EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwEC1EPSt16__numpunct_cacheIwEm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwEC2EP15__locale_structm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwEC2EPSt16__numpunct_cacheIwEm@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8numpunctIwED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImEC1ERKS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImEC2ERKS0_@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt8valarrayImEixEm@@GLIBCXX_3.4 ++FUNC:_ZNSt9__atomic011atomic_flag12test_and_setESt12memory_order@@GLIBCXX_3.4.14 ++FUNC:_ZNSt9__atomic011atomic_flag5clearESt12memory_order@@GLIBCXX_3.4.14 ++FUNC:_ZNSt9__cxx199815_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSt9__cxx199815_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.14 ++FUNC:_ZNSt9__cxx199815_List_node_base4hookEPS0_@@GLIBCXX_3.4.10 ++FUNC:_ZNSt9__cxx199815_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.10 ++FUNC:_ZNSt9__cxx199815_List_node_base6unhookEv@@GLIBCXX_3.4.10 ++FUNC:_ZNSt9__cxx199815_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14 ++FUNC:_ZNSt9__cxx199815_List_node_base7reverseEv@@GLIBCXX_3.4.10 ++FUNC:_ZNSt9__cxx199815_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.10 ++FUNC:_ZNSt9__cxx199815_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 ++FUNC:_ZNSt9bad_allocD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9bad_allocD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9bad_allocD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE10exceptionsESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE11_M_setstateESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE15_M_cache_localeERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE3tieEPSo@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEc@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4moveEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4moveERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE5rdbufEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE7copyfmtERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEE9set_rdbufEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC1EPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC2EPSt15basic_streambufIcS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE10exceptionsESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE11_M_setstateESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE15_M_cache_localeERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE3tieEPSt13basic_ostreamIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4fillEw@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4initEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4moveEOS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4moveERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE4swapERS2_@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5clearESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE5rdbufEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE7copyfmtERKS2_@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE8setstateESt12_Ios_Iostate@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEE9set_rdbufEPSt15basic_streambufIwS1_E@@GLIBCXX_3.4.21 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC1EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC2EPSt15basic_streambufIwS1_E@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9basic_iosIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9exceptionD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9exceptionD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9exceptionD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC1Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstream3strEv@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstream6freezeEb@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamC1EPciSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamC1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamC2EPciSt13_Ios_Openmode@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamC2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9strstreamD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9type_infoD0Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9type_infoD1Ev@@GLIBCXX_3.4 ++FUNC:_ZNSt9type_infoD2Ev@@GLIBCXX_3.4 ++FUNC:_ZNVSt9__atomic011atomic_flag12test_and_setESt12memory_order@@GLIBCXX_3.4.11 ++FUNC:_ZNVSt9__atomic011atomic_flag5clearESt12memory_order@@GLIBCXX_3.4.11 ++FUNC:_ZSt10unexpectedv@@GLIBCXX_3.4 ++FUNC:_ZSt11_Hash_bytesPKvmm@@CXXABI_1.3.5 ++FUNC:_ZSt13get_terminatev@@GLIBCXX_3.4.20 ++FUNC:_ZSt13set_terminatePFvvE@@GLIBCXX_3.4 ++FUNC:_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 ++FUNC:_ZSt14__convert_to_vIgEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt14get_unexpectedv@@GLIBCXX_3.4.20 ++FUNC:_ZSt14set_unexpectedPFvvE@@GLIBCXX_3.4 ++FUNC:_ZSt15_Fnv_hash_bytesPKvmm@@CXXABI_1.3.5 ++FUNC:_ZSt15future_categoryv@@GLIBCXX_3.4.15 ++FUNC:_ZSt15get_new_handlerv@@GLIBCXX_3.4.20 ++FUNC:_ZSt15set_new_handlerPFvvE@@GLIBCXX_3.4 ++FUNC:_ZSt15system_categoryv@@GLIBCXX_3.4.11 ++FUNC:_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l@@GLIBCXX_3.4.9 ++FUNC:_ZSt16__ostream_insertIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKS3_l@@GLIBCXX_3.4.9 ++FUNC:_ZSt16__throw_bad_castv@@GLIBCXX_3.4 ++FUNC:_ZSt16generic_categoryv@@GLIBCXX_3.4.11 ++FUNC:_ZSt17__copy_streambufsIcSt11char_traitsIcEElPSt15basic_streambufIT_T0_ES6_@@GLIBCXX_3.4.8 ++FUNC:_ZSt17__copy_streambufsIwSt11char_traitsIwEElPSt15basic_streambufIT_T0_ES6_@@GLIBCXX_3.4.8 ++FUNC:_ZSt17__throw_bad_allocv@@GLIBCXX_3.4 ++FUNC:_ZSt17__verify_groupingPKcmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++FUNC:_ZSt17__verify_groupingPKcmRKSs@@GLIBCXX_3.4.10 ++FUNC:_ZSt17current_exceptionv@@CXXABI_1.3.3 ++FUNC:_ZSt17iostream_categoryv@@GLIBCXX_3.4.21 ++FUNC:_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE@@CXXABI_1.3.3 ++FUNC:_ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base@@GLIBCXX_3.4 ++FUNC:_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4 ++FUNC:_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base@@GLIBCXX_3.4 ++FUNC:_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4 ++FUNC:_ZSt18__throw_bad_typeidv@@GLIBCXX_3.4 ++FUNC:_ZSt18uncaught_exceptionv@@GLIBCXX_3.4 ++FUNC:_ZSt19__throw_ios_failurePKc@@GLIBCXX_3.4 ++FUNC:_ZSt19__throw_ios_failurePKci@@GLIBCXX_3.4.26 ++FUNC:_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt19__throw_range_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE@@GLIBCXX_3.4.15 ++FUNC:_ZSt19uncaught_exceptionsv@@GLIBCXX_3.4.22 ++FUNC:_ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_@@GLIBCXX_3.4 ++FUNC:_ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_@@GLIBCXX_3.4 ++FUNC:_ZSt20__throw_domain_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt20__throw_future_errori@@GLIBCXX_3.4.14 ++FUNC:_ZSt20__throw_length_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt20__throw_out_of_rangePKc@@GLIBCXX_3.4 ++FUNC:_ZSt20__throw_system_errori@@GLIBCXX_3.4.11 ++FUNC:_ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_@@GLIBCXX_3.4 ++FUNC:_ZSt21__copy_streambufs_eofIcSt11char_traitsIcEElPSt15basic_streambufIT_T0_ES6_Rb@@GLIBCXX_3.4.9 ++FUNC:_ZSt21__copy_streambufs_eofIwSt11char_traitsIwEElPSt15basic_streambufIT_T0_ES6_Rb@@GLIBCXX_3.4.9 ++FUNC:_ZSt21__throw_bad_exceptionv@@GLIBCXX_3.4 ++FUNC:_ZSt21__throw_runtime_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt22__throw_overflow_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt23__throw_underflow_errorPKc@@GLIBCXX_3.4 ++FUNC:_ZSt24__throw_invalid_argumentPKc@@GLIBCXX_3.4 ++FUNC:_ZSt24__throw_out_of_range_fmtPKcz@@GLIBCXX_3.4.20 ++FUNC:_ZSt25__throw_bad_function_callv@@GLIBCXX_3.4.14 ++FUNC:_ZSt25notify_all_at_thread_exitRSt18condition_variableSt11unique_lockISt5mutexE@@GLIBCXX_3.4.21 ++FUNC:_ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_@@GLIBCXX_3.4 ++FUNC:_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_@@GLIBCXX_3.4 ++FUNC:_ZSt2wsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt2wsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt4endlIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt4endsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt4endsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt5flushIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt5flushIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4 ++FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 ++FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EES4_@@GLIBCXX_3.4.21 ++FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 ++FUNC:_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_@@GLIBCXX_3.4 ++FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 ++FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EES4_@@GLIBCXX_3.4.21 ++FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 ++FUNC:_ZSt7getlineIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9has_facetINSt7__cxx1110moneypunctIcLb0EEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx1110moneypunctIwLb0EEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx117collateIcEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx117collateIwEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx118messagesIcEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx118messagesIwEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx118numpunctIcEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx118numpunctIwEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEEbRKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9has_facetISt10moneypunctIcLb0EEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt10moneypunctIwLb0EEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt11__timepunctIcEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt11__timepunctIwEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt5ctypeIcEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt5ctypeIwEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7codecvtIcc11__mbstate_tEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7codecvtIwc11__mbstate_tEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7collateIcEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7collateIwEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8messagesIcEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8messagesIwEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8numpunctIcEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8numpunctIwEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9has_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEbRKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9terminatev@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_LDBL_3.4 ++FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIcLb0EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIcLb1EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIwLb0EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx1110moneypunctIwLb1EEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx117collateIcEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx117collateIwEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx118messagesIcEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx118messagesIwEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx118numpunctIcEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx118numpunctIwEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEEERKT_RKSt6locale@@GLIBCXX_3.4.21 ++FUNC:_ZSt9use_facetISt10moneypunctIcLb0EEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt10moneypunctIcLb1EEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt10moneypunctIwLb0EEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt10moneypunctIwLb1EEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt11__timepunctIcEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt11__timepunctIwEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt5ctypeIcEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt5ctypeIwEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7codecvtIcc11__mbstate_tEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7codecvtIwc11__mbstate_tEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7collateIcEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7collateIwEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8messagesIcEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8messagesIwEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8numpunctIcEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8numpunctIwEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZSt9use_facetISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEERKT_RKSt6locale@@GLIBCXX_3.4 ++FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKa@@GLIBCXX_3.4 ++FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4 ++FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKh@@GLIBCXX_3.4 ++FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_a@@GLIBCXX_3.4 ++FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c@@GLIBCXX_3.4 ++FUNC:_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_h@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 ++FUNC:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIdcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIdwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIecSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIewSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIfcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIfwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIgcSt11char_traitsIcEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_LDBL_3.4 ++FUNC:_ZStlsIgwSt11char_traitsIwEERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E@@GLIBCXX_LDBL_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKS3_@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_PKc@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_S3_@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwEERSt13basic_ostreamIT_T0_ES6_c@@GLIBCXX_3.4 ++FUNC:_ZStlsIwSt11char_traitsIwESaIwEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 ++FUNC:_ZStlsIwSt11char_traitsIwESaIwEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E@@GLIBCXX_3.4 ++FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_@@GLIBCXX_3.4.21 ++FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_@@GLIBCXX_3.4.21 ++FUNC:_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_@@GLIBCXX_3.4.21 ++FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_@@GLIBCXX_3.4 ++FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_@@GLIBCXX_3.4 ++FUNC:_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ES3_RKS6_@@GLIBCXX_3.4 ++FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_@@GLIBCXX_3.4.21 ++FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_@@GLIBCXX_3.4.21 ++FUNC:_ZStplIwSt11char_traitsIwESaIwEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_@@GLIBCXX_3.4.21 ++FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_EPKS3_RKS6_@@GLIBCXX_3.4 ++FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ERKS6_S8_@@GLIBCXX_3.4 ++FUNC:_ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ES3_RKS6_@@GLIBCXX_3.4 ++FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Pa@@GLIBCXX_3.4 ++FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Ph@@GLIBCXX_3.4 ++FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Ra@@GLIBCXX_3.4 ++FUNC:_ZStrsISt11char_traitsIcEERSt13basic_istreamIcT_ES5_Rh@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_PS3_@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_RS3_@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 ++FUNC:_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIdcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIdwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIecSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIewSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIfcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIfwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIgcSt11char_traitsIcEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_LDBL_3.4 ++FUNC:_ZStrsIgwSt11char_traitsIwEERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E@@GLIBCXX_LDBL_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_PS3_@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_RS3_@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St12_Setiosflags@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St13_Setprecision@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St14_Resetiosflags@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St5_Setw@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St8_Setbase@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwEERSt13basic_istreamIT_T0_ES6_St8_SetfillIS3_E@@GLIBCXX_3.4 ++FUNC:_ZStrsIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE@@GLIBCXX_3.4.21 ++FUNC:_ZStrsIwSt11char_traitsIwESaIwEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSdD0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSdD1Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZThn16_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZThn16_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZThn16_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZThn16_NSt9strstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZThn16_NSt9strstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSdD0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSdD1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSiD0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSiD1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSoD0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSoD1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt10istrstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt10istrstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt10ostrstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt10ostrstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ifstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ifstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ifstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ofstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ofstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ofstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt14basic_ofstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21 ++FUNC:_ZTv0_n24_NSt9strstreamD0Ev@@GLIBCXX_3.4 ++FUNC:_ZTv0_n24_NSt9strstreamD1Ev@@GLIBCXX_3.4 ++FUNC:_ZdaPv@@GLIBCXX_3.4 ++FUNC:_ZdaPvRKSt9nothrow_t@@GLIBCXX_3.4 ++FUNC:_ZdaPvSt11align_val_t@@CXXABI_1.3.11 ++FUNC:_ZdaPvSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 ++FUNC:_ZdaPvm@@CXXABI_1.3.9 ++FUNC:_ZdaPvmSt11align_val_t@@CXXABI_1.3.11 ++FUNC:_ZdlPv@@GLIBCXX_3.4 ++FUNC:_ZdlPvRKSt9nothrow_t@@GLIBCXX_3.4 ++FUNC:_ZdlPvSt11align_val_t@@CXXABI_1.3.11 ++FUNC:_ZdlPvSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 ++FUNC:_ZdlPvm@@CXXABI_1.3.9 ++FUNC:_ZdlPvmSt11align_val_t@@CXXABI_1.3.11 ++FUNC:_Znam@@GLIBCXX_3.4 ++FUNC:_ZnamRKSt9nothrow_t@@GLIBCXX_3.4 ++FUNC:_ZnamSt11align_val_t@@CXXABI_1.3.11 ++FUNC:_ZnamSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 ++FUNC:_Znwm@@GLIBCXX_3.4 ++FUNC:_ZnwmRKSt9nothrow_t@@GLIBCXX_3.4 ++FUNC:_ZnwmSt11align_val_t@@CXXABI_1.3.11 ++FUNC:_ZnwmSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11 ++FUNC:__atomic_flag_for_address@@GLIBCXX_3.4.11 ++FUNC:__atomic_flag_wait_explicit@@GLIBCXX_3.4.11 ++FUNC:__cxa_allocate_dependent_exception@@CXXABI_1.3.6 ++FUNC:__cxa_allocate_exception@@CXXABI_1.3 ++FUNC:__cxa_bad_cast@@CXXABI_1.3 ++FUNC:__cxa_bad_typeid@@CXXABI_1.3 ++FUNC:__cxa_begin_catch@@CXXABI_1.3 ++FUNC:__cxa_call_unexpected@@CXXABI_1.3 ++FUNC:__cxa_current_exception_type@@CXXABI_1.3 ++FUNC:__cxa_deleted_virtual@@CXXABI_1.3.6 ++FUNC:__cxa_demangle@@CXXABI_1.3 ++FUNC:__cxa_end_catch@@CXXABI_1.3 ++FUNC:__cxa_free_dependent_exception@@CXXABI_1.3.6 ++FUNC:__cxa_free_exception@@CXXABI_1.3 ++FUNC:__cxa_get_exception_ptr@@CXXABI_1.3.1 ++FUNC:__cxa_get_globals@@CXXABI_1.3 ++FUNC:__cxa_get_globals_fast@@CXXABI_1.3 ++FUNC:__cxa_guard_abort@@CXXABI_1.3 ++FUNC:__cxa_guard_acquire@@CXXABI_1.3 ++FUNC:__cxa_guard_release@@CXXABI_1.3 ++FUNC:__cxa_init_primary_exception@@CXXABI_1.3.11 ++FUNC:__cxa_pure_virtual@@CXXABI_1.3 ++FUNC:__cxa_rethrow@@CXXABI_1.3 ++FUNC:__cxa_thread_atexit@@CXXABI_1.3.7 ++FUNC:__cxa_throw@@CXXABI_1.3 ++FUNC:__cxa_throw_bad_array_length@@CXXABI_1.3.8 ++FUNC:__cxa_throw_bad_array_new_length@@CXXABI_1.3.8 ++FUNC:__cxa_tm_cleanup@@CXXABI_TM_1 ++FUNC:__cxa_vec_cctor@@CXXABI_1.3 ++FUNC:__cxa_vec_cleanup@@CXXABI_1.3 ++FUNC:__cxa_vec_ctor@@CXXABI_1.3 ++FUNC:__cxa_vec_delete2@@CXXABI_1.3 ++FUNC:__cxa_vec_delete3@@CXXABI_1.3 ++FUNC:__cxa_vec_delete@@CXXABI_1.3 ++FUNC:__cxa_vec_dtor@@CXXABI_1.3 ++FUNC:__cxa_vec_new2@@CXXABI_1.3 ++FUNC:__cxa_vec_new3@@CXXABI_1.3 ++FUNC:__cxa_vec_new@@CXXABI_1.3 ++FUNC:__dynamic_cast@@CXXABI_1.3 ++FUNC:__gxx_personality_v0@@CXXABI_1.3 ++FUNC:__once_proxy@@GLIBCXX_3.4.11 ++FUNC:acosl@GLIBCXX_3.4.3 ++FUNC:asinl@GLIBCXX_3.4.3 ++FUNC:atan2l@GLIBCXX_3.4 ++FUNC:atanl@GLIBCXX_3.4.3 ++FUNC:atomic_flag_clear_explicit@@GLIBCXX_3.4.11 ++FUNC:atomic_flag_test_and_set_explicit@@GLIBCXX_3.4.11 ++FUNC:ceill@GLIBCXX_3.4.3 ++FUNC:coshl@GLIBCXX_3.4 ++FUNC:cosl@GLIBCXX_3.4 ++FUNC:expl@GLIBCXX_3.4 ++FUNC:floorl@GLIBCXX_3.4.3 ++FUNC:fmodl@GLIBCXX_3.4.3 ++FUNC:frexpl@GLIBCXX_3.4.3 ++FUNC:hypotl@GLIBCXX_3.4 ++FUNC:ldexpl@GLIBCXX_3.4.3 ++FUNC:log10l@GLIBCXX_3.4 ++FUNC:logl@GLIBCXX_3.4 ++FUNC:modfl@GLIBCXX_3.4.3 ++FUNC:powl@GLIBCXX_3.4 ++FUNC:sinhl@GLIBCXX_3.4 ++FUNC:sinl@GLIBCXX_3.4 ++FUNC:sqrtl@GLIBCXX_3.4 ++FUNC:tanhl@GLIBCXX_3.4 ++FUNC:tanl@GLIBCXX_3.4 ++OBJECT:0:CXXABI_1.3 ++OBJECT:0:CXXABI_1.3.1 ++OBJECT:0:CXXABI_1.3.10 ++OBJECT:0:CXXABI_1.3.11 ++OBJECT:0:CXXABI_1.3.12 ++OBJECT:0:CXXABI_1.3.2 ++OBJECT:0:CXXABI_1.3.3 ++OBJECT:0:CXXABI_1.3.4 ++OBJECT:0:CXXABI_1.3.5 ++OBJECT:0:CXXABI_1.3.6 ++OBJECT:0:CXXABI_1.3.7 ++OBJECT:0:CXXABI_1.3.8 ++OBJECT:0:CXXABI_1.3.9 ++OBJECT:0:CXXABI_LDBL_1.3 ++OBJECT:0:CXXABI_TM_1 ++OBJECT:0:GLIBCXX_3.4 ++OBJECT:0:GLIBCXX_3.4.1 ++OBJECT:0:GLIBCXX_3.4.10 ++OBJECT:0:GLIBCXX_3.4.11 ++OBJECT:0:GLIBCXX_3.4.12 ++OBJECT:0:GLIBCXX_3.4.13 ++OBJECT:0:GLIBCXX_3.4.14 ++OBJECT:0:GLIBCXX_3.4.15 ++OBJECT:0:GLIBCXX_3.4.16 ++OBJECT:0:GLIBCXX_3.4.17 ++OBJECT:0:GLIBCXX_3.4.18 ++OBJECT:0:GLIBCXX_3.4.19 ++OBJECT:0:GLIBCXX_3.4.2 ++OBJECT:0:GLIBCXX_3.4.20 ++OBJECT:0:GLIBCXX_3.4.21 ++OBJECT:0:GLIBCXX_3.4.22 ++OBJECT:0:GLIBCXX_3.4.23 ++OBJECT:0:GLIBCXX_3.4.24 ++OBJECT:0:GLIBCXX_3.4.25 ++OBJECT:0:GLIBCXX_3.4.26 ++OBJECT:0:GLIBCXX_3.4.27 ++OBJECT:0:GLIBCXX_3.4.28 ++OBJECT:0:GLIBCXX_3.4.3 ++OBJECT:0:GLIBCXX_3.4.4 ++OBJECT:0:GLIBCXX_3.4.5 ++OBJECT:0:GLIBCXX_3.4.6 ++OBJECT:0:GLIBCXX_3.4.7 ++OBJECT:0:GLIBCXX_3.4.8 ++OBJECT:0:GLIBCXX_3.4.9 ++OBJECT:0:GLIBCXX_LDBL_3.4 ++OBJECT:0:GLIBCXX_LDBL_3.4.10 ++OBJECT:0:GLIBCXX_LDBL_3.4.21 ++OBJECT:0:GLIBCXX_LDBL_3.4.7 ++OBJECT:104:_ZTVNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:104:_ZTVNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:104:_ZTVNSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1110moneypunctIwLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1117moneypunct_bynameIcLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1117moneypunct_bynameIcLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1117moneypunct_bynameIwLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVNSt7__cxx1117moneypunct_bynameIwLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:104:_ZTVSt10moneypunctIcLb0EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt10moneypunctIcLb1EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt10moneypunctIwLb0EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt10moneypunctIwLb1EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 ++OBJECT:104:_ZTVSt17moneypunct_bynameIwLb1EE@@GLIBCXX_3.4 ++OBJECT:112:_ZNSt17__timepunct_cacheIcE12_S_timezonesE@@GLIBCXX_3.4 ++OBJECT:112:_ZNSt17__timepunct_cacheIwE12_S_timezonesE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:120:_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:120:_ZTVSd@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:120:_ZTVSt9strstream@@GLIBCXX_3.4 ++OBJECT:128:_ZTVN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:128:_ZTVNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:128:_ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:128:_ZTVNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:128:_ZTVSt12ctype_bynameIwE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt12strstreambuf@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt13basic_filebufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt13basic_filebufIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt21__ctype_abstract_baseIcE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt21__ctype_abstract_baseIwE@@GLIBCXX_3.4 ++OBJECT:128:_ZTVSt5ctypeIwE@@GLIBCXX_3.4 ++OBJECT:12:_ZTSSt5ctypeIcE@@GLIBCXX_3.4 ++OBJECT:12:_ZTSSt5ctypeIwE@@GLIBCXX_3.4 ++OBJECT:12:_ZTSSt8bad_cast@@GLIBCXX_3.4 ++OBJECT:12:_ZTSSt8ios_base@@GLIBCXX_3.4 ++OBJECT:13:_ZTSSt9bad_alloc@@GLIBCXX_3.4 ++OBJECT:13:_ZTSSt9exception@@GLIBCXX_3.4 ++OBJECT:13:_ZTSSt9strstream@@GLIBCXX_3.4 ++OBJECT:13:_ZTSSt9time_base@@GLIBCXX_3.4 ++OBJECT:13:_ZTSSt9type_info@@GLIBCXX_3.4 ++OBJECT:14:_ZTSSt7collateIcE@@GLIBCXX_3.4 ++OBJECT:14:_ZTSSt7collateIwE@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt10bad_typeid@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt10ctype_base@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt10istrstream@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt10lock_error@@GLIBCXX_3.4.11 ++OBJECT:15:_ZTSSt10money_base@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt10ostrstream@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt8messagesIcE@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt8messagesIwE@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt8numpunctIcE@@GLIBCXX_3.4 ++OBJECT:15:_ZTSSt8numpunctIwE@@GLIBCXX_3.4 ++OBJECT:16:_ZTIDd@@CXXABI_1.3.4 ++OBJECT:16:_ZTIDe@@CXXABI_1.3.4 ++OBJECT:16:_ZTIDf@@CXXABI_1.3.4 ++OBJECT:16:_ZTIDi@@CXXABI_1.3.3 ++OBJECT:16:_ZTIDn@@CXXABI_1.3.5 ++OBJECT:16:_ZTIDs@@CXXABI_1.3.3 ++OBJECT:16:_ZTIDu@@CXXABI_1.3.12 ++OBJECT:16:_ZTIN10__cxxabiv115__forced_unwindE@@CXXABI_1.3.2 ++OBJECT:16:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2 ++OBJECT:16:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15 ++OBJECT:16:_ZTINSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15 ++OBJECT:16:_ZTINSt3_V214error_categoryE@@GLIBCXX_3.4.21 ++OBJECT:16:_ZTINSt6locale5facetE@@GLIBCXX_3.4 ++OBJECT:16:_ZTINSt6thread6_StateE@@GLIBCXX_3.4.22 ++OBJECT:16:_ZTISt10ctype_base@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt10money_base@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt12codecvt_base@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt13messages_base@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt14error_category@@GLIBCXX_3.4.11 ++OBJECT:16:_ZTISt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt16nested_exception@@CXXABI_1.3.5 ++OBJECT:16:_ZTISt8ios_base@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt9exception@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt9time_base@@GLIBCXX_3.4 ++OBJECT:16:_ZTISt9type_info@@GLIBCXX_3.4 ++OBJECT:16:_ZTIa@@CXXABI_1.3 ++OBJECT:16:_ZTIb@@CXXABI_1.3 ++OBJECT:16:_ZTIc@@CXXABI_1.3 ++OBJECT:16:_ZTId@@CXXABI_1.3 ++OBJECT:16:_ZTIe@@CXXABI_1.3 ++OBJECT:16:_ZTIf@@CXXABI_1.3 ++OBJECT:16:_ZTIg@@CXXABI_LDBL_1.3 ++OBJECT:16:_ZTIh@@CXXABI_1.3 ++OBJECT:16:_ZTIi@@CXXABI_1.3 ++OBJECT:16:_ZTIj@@CXXABI_1.3 ++OBJECT:16:_ZTIl@@CXXABI_1.3 ++OBJECT:16:_ZTIm@@CXXABI_1.3 ++OBJECT:16:_ZTIn@@CXXABI_1.3.5 ++OBJECT:16:_ZTIo@@CXXABI_1.3.5 ++OBJECT:16:_ZTIs@@CXXABI_1.3 ++OBJECT:16:_ZTIt@@CXXABI_1.3 ++OBJECT:16:_ZTIv@@CXXABI_1.3 ++OBJECT:16:_ZTIw@@CXXABI_1.3 ++OBJECT:16:_ZTIx@@CXXABI_1.3 ++OBJECT:16:_ZTIy@@CXXABI_1.3 ++OBJECT:16:_ZTSSt11logic_error@@GLIBCXX_3.4 ++OBJECT:16:_ZTSSt11range_error@@GLIBCXX_3.4 ++OBJECT:16:_ZTTSi@@GLIBCXX_3.4 ++OBJECT:16:_ZTTSo@@GLIBCXX_3.4 ++OBJECT:16:_ZTTSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:16:_ZTTSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:17:_ZTSSt12codecvt_base@@GLIBCXX_3.4 ++OBJECT:17:_ZTSSt12domain_error@@GLIBCXX_3.4 ++OBJECT:17:_ZTSSt12future_error@@GLIBCXX_3.4.14 ++OBJECT:17:_ZTSSt12length_error@@GLIBCXX_3.4 ++OBJECT:17:_ZTSSt12out_of_range@@GLIBCXX_3.4 ++OBJECT:17:_ZTSSt12strstreambuf@@GLIBCXX_3.4 ++OBJECT:17:_ZTSSt12system_error@@GLIBCXX_3.4.11 ++OBJECT:18:_ZTSNSt6locale5facetE@@GLIBCXX_3.4 ++OBJECT:18:_ZTSSt13bad_exception@@GLIBCXX_3.4 ++OBJECT:18:_ZTSSt13messages_base@@GLIBCXX_3.4 ++OBJECT:18:_ZTSSt13runtime_error@@GLIBCXX_3.4 ++OBJECT:19:_ZTSNSt6thread6_StateE@@GLIBCXX_3.4.22 ++OBJECT:19:_ZTSSt11__timepunctIcE@@GLIBCXX_3.4 ++OBJECT:19:_ZTSSt11__timepunctIwE@@GLIBCXX_3.4 ++OBJECT:19:_ZTSSt14error_category@@GLIBCXX_3.4.11 ++OBJECT:19:_ZTSSt14overflow_error@@GLIBCXX_3.4 ++OBJECT:1:_ZNSs4_Rep11_S_terminalE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt10moneypunctIcLb0EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt10moneypunctIcLb1EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt10moneypunctIwLb0EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt10moneypunctIwLb1EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt12placeholders2_1E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_2E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_3E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_4E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_5E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_6E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_7E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_8E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders2_9E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_10E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_11E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_12E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_13E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_14E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_15E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_16E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_17E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_18E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_19E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_20E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_21E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_22E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_23E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_24E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_25E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_26E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_27E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_28E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt12placeholders3_29E@@GLIBCXX_3.4.15 ++OBJECT:1:_ZNSt14numeric_limitsIDiE10is_boundedE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE10is_integerE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE12has_infinityE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE13has_quiet_NaNE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE14is_specializedE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE15has_denorm_lossE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE15tinyness_beforeE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE17has_signaling_NaNE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE5trapsE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE8is_exactE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE9is_iec559E@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE9is_moduloE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDiE9is_signedE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE10is_boundedE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE10is_integerE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE12has_infinityE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE13has_quiet_NaNE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE14is_specializedE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE15has_denorm_lossE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE15tinyness_beforeE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE17has_signaling_NaNE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE5trapsE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE8is_exactE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE9is_iec559E@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE9is_moduloE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDsE9is_signedE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt14numeric_limitsIDuE10is_boundedE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE10is_integerE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE12has_infinityE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE13has_quiet_NaNE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE14is_specializedE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE15has_denorm_lossE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE15tinyness_beforeE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE17has_signaling_NaNE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE5trapsE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE8is_exactE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE9is_iec559E@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE9is_moduloE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIDuE9is_signedE@@GLIBCXX_3.4.26 ++OBJECT:1:_ZNSt14numeric_limitsIaE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIaE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIbE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIcE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIdE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIeE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIfE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE10is_boundedE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE10is_integerE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE12has_infinityE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE13has_quiet_NaNE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE14is_specializedE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE15has_denorm_lossE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE15tinyness_beforeE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE17has_signaling_NaNE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE5trapsE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE8is_exactE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE9is_iec559E@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE9is_moduloE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIgE9is_signedE@@GLIBCXX_LDBL_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIhE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIiE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIjE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIlE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsImE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsInE10is_boundedE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE10is_integerE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE12has_infinityE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE13has_quiet_NaNE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE14is_specializedE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE15has_denorm_lossE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE15tinyness_beforeE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE17has_signaling_NaNE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE5trapsE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE8is_exactE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE9is_iec559E@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE9is_moduloE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsInE9is_signedE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE10is_boundedE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE10is_integerE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE12has_infinityE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE13has_quiet_NaNE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE14is_specializedE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE15has_denorm_lossE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE15tinyness_beforeE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE17has_signaling_NaNE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE5trapsE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE8is_exactE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE9is_iec559E@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE9is_moduloE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIoE9is_signedE@@GLIBCXX_3.4.17 ++OBJECT:1:_ZNSt14numeric_limitsIsE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIsE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsItE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIwE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIxE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt14numeric_limitsIyE9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt17moneypunct_bynameIcLb0EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt17moneypunct_bynameIcLb1EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt17moneypunct_bynameIwLb0EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt17moneypunct_bynameIwLb1EE4intlE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base10is_boundedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base10is_integerE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base12has_infinityE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base13has_quiet_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base14is_specializedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base15has_denorm_lossE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base15tinyness_beforeE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base17has_signaling_NaNE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base5trapsE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base8is_exactE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base9is_iec559E@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base9is_moduloE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt21__numeric_limits_base9is_signedE@@GLIBCXX_3.4 ++OBJECT:1:_ZNSt6chrono12system_clock12is_monotonicE@@GLIBCXX_3.4.11 ++OBJECT:1:_ZNSt6chrono3_V212steady_clock9is_steadyE@@GLIBCXX_3.4.19 ++OBJECT:1:_ZNSt6chrono3_V212system_clock9is_steadyE@@GLIBCXX_3.4.19 ++OBJECT:1:_ZNSt7__cxx1110moneypunctIcLb0EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1110moneypunctIcLb1EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1110moneypunctIwLb0EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1110moneypunctIwLb1EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIcLb0EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIcLb1EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIwLb0EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZNSt7__cxx1117moneypunct_bynameIwLb1EE4intlE@@GLIBCXX_3.4.21 ++OBJECT:1:_ZSt10adopt_lock@@GLIBCXX_3.4.11 ++OBJECT:1:_ZSt10defer_lock@@GLIBCXX_3.4.11 ++OBJECT:1:_ZSt11try_to_lock@@GLIBCXX_3.4.11 ++OBJECT:1:_ZSt7nothrow@@GLIBCXX_3.4 ++OBJECT:20:_ZTSSt12ctype_bynameIcE@@GLIBCXX_3.4 ++OBJECT:20:_ZTSSt12ctype_bynameIwE@@GLIBCXX_3.4 ++OBJECT:20:_ZTSSt15underflow_error@@GLIBCXX_3.4 ++OBJECT:21:_ZTSSt16bad_array_length@@CXXABI_1.3.8 ++OBJECT:21:_ZTSSt16invalid_argument@@GLIBCXX_3.4 ++OBJECT:22:_ZTSNSt8ios_base7failureE@@GLIBCXX_3.4 ++OBJECT:22:_ZTSSt10moneypunctIcLb0EE@@GLIBCXX_3.4 ++OBJECT:22:_ZTSSt10moneypunctIcLb1EE@@GLIBCXX_3.4 ++OBJECT:22:_ZTSSt10moneypunctIwLb0EE@@GLIBCXX_3.4 ++OBJECT:22:_ZTSSt10moneypunctIwLb1EE@@GLIBCXX_3.4 ++OBJECT:22:_ZTSSt14collate_bynameIcE@@GLIBCXX_3.4 ++OBJECT:22:_ZTSSt14collate_bynameIwE@@GLIBCXX_3.4 ++OBJECT:23:_ZTSSt15messages_bynameIcE@@GLIBCXX_3.4 ++OBJECT:23:_ZTSSt15messages_bynameIwE@@GLIBCXX_3.4 ++OBJECT:23:_ZTSSt15numpunct_bynameIcE@@GLIBCXX_3.4 ++OBJECT:23:_ZTSSt15numpunct_bynameIwE@@GLIBCXX_3.4 ++OBJECT:2440:_ZNSt3tr18__detail12__prime_listE@@GLIBCXX_3.4.10 ++OBJECT:2440:_ZNSt8__detail12__prime_listE@@GLIBCXX_3.4.10 ++OBJECT:24:_ZTIN10__cxxabiv116__enum_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv117__array_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv120__function_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv123__fundamental_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN10__cxxabiv129__pointer_to_member_type_infoE@@CXXABI_1.3 ++OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTINSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26 ++OBJECT:24:_ZTINSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26 ++OBJECT:24:_ZTINSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:24:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26 ++OBJECT:24:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26 ++OBJECT:24:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115messages_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115numpunct_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115numpunct_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1117moneypunct_bynameIcLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1117moneypunct_bynameIcLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1117moneypunct_bynameIwLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1117moneypunct_bynameIwLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx117collateIcEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx117collateIwEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt8ios_base7failureB5cxx11E@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTINSt8ios_base7failureE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt10bad_typeid@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt10istrstream@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt10lock_error@@GLIBCXX_3.4.11 ++OBJECT:24:_ZTISt10ostrstream@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt11__timepunctIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt11__timepunctIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt11logic_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt11range_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt11regex_error@@GLIBCXX_3.4.15 ++OBJECT:24:_ZTISt12bad_weak_ptr@@GLIBCXX_3.4.15 ++OBJECT:24:_ZTISt12ctype_bynameIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt12ctype_bynameIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt12domain_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt12future_error@@GLIBCXX_3.4.14 ++OBJECT:24:_ZTISt12length_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt12out_of_range@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt12strstreambuf@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt12system_error@@GLIBCXX_3.4.11 ++OBJECT:24:_ZTISt13bad_exception@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt13basic_filebufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt13basic_filebufIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt13runtime_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14collate_bynameIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14collate_bynameIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt14overflow_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15messages_bynameIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15messages_bynameIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15numpunct_bynameIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15numpunct_bynameIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt15underflow_error@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt16bad_array_length@@CXXABI_1.3.8 ++OBJECT:24:_ZTISt16invalid_argument@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt17bad_function_call@@GLIBCXX_3.4.15 ++OBJECT:24:_ZTISt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt17moneypunct_bynameIwLb1EE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt20__codecvt_utf16_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt20__codecvt_utf16_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt20__codecvt_utf16_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt20bad_array_new_length@@CXXABI_1.3.8 ++OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt5ctypeIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26 ++OBJECT:24:_ZTISt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26 ++OBJECT:24:_ZTISt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTISt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7collateIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7collateIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt8bad_cast@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt8numpunctIcE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt8numpunctIwE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9bad_alloc@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:24:_ZTISt9strstream@@GLIBCXX_3.4 ++OBJECT:24:_ZTSNSt7__cxx117collateIcEE@@GLIBCXX_3.4.21 ++OBJECT:24:_ZTSNSt7__cxx117collateIwEE@@GLIBCXX_3.4.21 ++OBJECT:25:_ZTSNSt7__cxx118messagesIcEE@@GLIBCXX_3.4.21 ++OBJECT:25:_ZTSNSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21 ++OBJECT:25:_ZTSNSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21 ++OBJECT:25:_ZTSNSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21 ++OBJECT:25:_ZTSSt20bad_array_new_length@@CXXABI_1.3.8 ++OBJECT:272:_ZSt4cerr@@GLIBCXX_3.4 ++OBJECT:272:_ZSt4clog@@GLIBCXX_3.4 ++OBJECT:272:_ZSt4cout@@GLIBCXX_3.4 ++OBJECT:272:_ZSt5wcerr@@GLIBCXX_3.4 ++OBJECT:272:_ZSt5wclog@@GLIBCXX_3.4 ++OBJECT:272:_ZSt5wcout@@GLIBCXX_3.4 ++OBJECT:27:_ZTSSt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:280:_ZSt3cin@@GLIBCXX_3.4 ++OBJECT:280:_ZSt4wcin@@GLIBCXX_3.4 ++OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:28:_ZTSSt20__codecvt_utf16_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:28:_ZTSSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:28:_ZTSSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSNSt8ios_base7failureB5cxx11E@@GLIBCXX_3.4.21 ++OBJECT:29:_ZTSSt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSSt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSSt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSSt17moneypunct_bynameIwLb1EE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSSt20__codecvt_utf16_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:29:_ZTSSt20__codecvt_utf16_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:29:_ZTSSt21__ctype_abstract_baseIcE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSSt21__ctype_abstract_baseIwE@@GLIBCXX_3.4 ++OBJECT:29:_ZTSSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21 ++OBJECT:29:_ZTSSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21 ++OBJECT:2:_ZNSt10ctype_base5alnumE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5alphaE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5blankE@@GLIBCXX_3.4.21 ++OBJECT:2:_ZNSt10ctype_base5cntrlE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5digitE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5graphE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5lowerE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5printE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5punctE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5spaceE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base5upperE@@GLIBCXX_3.4 ++OBJECT:2:_ZNSt10ctype_base6xdigitE@@GLIBCXX_3.4 ++OBJECT:2:_ZTSa@@CXXABI_1.3 ++OBJECT:2:_ZTSb@@CXXABI_1.3 ++OBJECT:2:_ZTSc@@CXXABI_1.3 ++OBJECT:2:_ZTSd@@CXXABI_1.3 ++OBJECT:2:_ZTSe@@CXXABI_1.3 ++OBJECT:2:_ZTSf@@CXXABI_1.3 ++OBJECT:2:_ZTSg@@CXXABI_LDBL_1.3 ++OBJECT:2:_ZTSh@@CXXABI_1.3 ++OBJECT:2:_ZTSi@@CXXABI_1.3 ++OBJECT:2:_ZTSj@@CXXABI_1.3 ++OBJECT:2:_ZTSl@@CXXABI_1.3 ++OBJECT:2:_ZTSm@@CXXABI_1.3 ++OBJECT:2:_ZTSn@@CXXABI_1.3.9 ++OBJECT:2:_ZTSo@@CXXABI_1.3.9 ++OBJECT:2:_ZTSs@@CXXABI_1.3 ++OBJECT:2:_ZTSt@@CXXABI_1.3 ++OBJECT:2:_ZTSv@@CXXABI_1.3 ++OBJECT:2:_ZTSw@@CXXABI_1.3 ++OBJECT:2:_ZTSx@@CXXABI_1.3 ++OBJECT:2:_ZTSy@@CXXABI_1.3 ++OBJECT:30:_ZTSSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26 ++OBJECT:30:_ZTSSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26 ++OBJECT:32:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4 ++OBJECT:32:_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4 ++OBJECT:32:_ZTIPDd@@CXXABI_1.3.4 ++OBJECT:32:_ZTIPDe@@CXXABI_1.3.4 ++OBJECT:32:_ZTIPDf@@CXXABI_1.3.4 ++OBJECT:32:_ZTIPDi@@CXXABI_1.3.3 ++OBJECT:32:_ZTIPDn@@CXXABI_1.3.5 ++OBJECT:32:_ZTIPDs@@CXXABI_1.3.3 ++OBJECT:32:_ZTIPDu@@CXXABI_1.3.12 ++OBJECT:32:_ZTIPKDd@@CXXABI_1.3.4 ++OBJECT:32:_ZTIPKDe@@CXXABI_1.3.4 ++OBJECT:32:_ZTIPKDf@@CXXABI_1.3.4 ++OBJECT:32:_ZTIPKDi@@CXXABI_1.3.3 ++OBJECT:32:_ZTIPKDn@@CXXABI_1.3.5 ++OBJECT:32:_ZTIPKDs@@CXXABI_1.3.3 ++OBJECT:32:_ZTIPKDu@@CXXABI_1.3.12 ++OBJECT:32:_ZTIPKa@@CXXABI_1.3 ++OBJECT:32:_ZTIPKb@@CXXABI_1.3 ++OBJECT:32:_ZTIPKc@@CXXABI_1.3 ++OBJECT:32:_ZTIPKd@@CXXABI_1.3 ++OBJECT:32:_ZTIPKe@@CXXABI_1.3 ++OBJECT:32:_ZTIPKf@@CXXABI_1.3 ++OBJECT:32:_ZTIPKg@@CXXABI_LDBL_1.3 ++OBJECT:32:_ZTIPKh@@CXXABI_1.3 ++OBJECT:32:_ZTIPKi@@CXXABI_1.3 ++OBJECT:32:_ZTIPKj@@CXXABI_1.3 ++OBJECT:32:_ZTIPKl@@CXXABI_1.3 ++OBJECT:32:_ZTIPKm@@CXXABI_1.3 ++OBJECT:32:_ZTIPKn@@CXXABI_1.3.5 ++OBJECT:32:_ZTIPKo@@CXXABI_1.3.5 ++OBJECT:32:_ZTIPKs@@CXXABI_1.3 ++OBJECT:32:_ZTIPKt@@CXXABI_1.3 ++OBJECT:32:_ZTIPKv@@CXXABI_1.3 ++OBJECT:32:_ZTIPKw@@CXXABI_1.3 ++OBJECT:32:_ZTIPKx@@CXXABI_1.3 ++OBJECT:32:_ZTIPKy@@CXXABI_1.3 ++OBJECT:32:_ZTIPa@@CXXABI_1.3 ++OBJECT:32:_ZTIPb@@CXXABI_1.3 ++OBJECT:32:_ZTIPc@@CXXABI_1.3 ++OBJECT:32:_ZTIPd@@CXXABI_1.3 ++OBJECT:32:_ZTIPe@@CXXABI_1.3 ++OBJECT:32:_ZTIPf@@CXXABI_1.3 ++OBJECT:32:_ZTIPg@@CXXABI_LDBL_1.3 ++OBJECT:32:_ZTIPh@@CXXABI_1.3 ++OBJECT:32:_ZTIPi@@CXXABI_1.3 ++OBJECT:32:_ZTIPj@@CXXABI_1.3 ++OBJECT:32:_ZTIPl@@CXXABI_1.3 ++OBJECT:32:_ZTIPm@@CXXABI_1.3 ++OBJECT:32:_ZTIPn@@CXXABI_1.3.5 ++OBJECT:32:_ZTIPo@@CXXABI_1.3.5 ++OBJECT:32:_ZTIPs@@CXXABI_1.3 ++OBJECT:32:_ZTIPt@@CXXABI_1.3 ++OBJECT:32:_ZTIPv@@CXXABI_1.3 ++OBJECT:32:_ZTIPw@@CXXABI_1.3 ++OBJECT:32:_ZTIPx@@CXXABI_1.3 ++OBJECT:32:_ZTIPy@@CXXABI_1.3 ++OBJECT:32:_ZTSNSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTSNSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTSNSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTSNSt7__cxx1110moneypunctIwLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTSNSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTSNSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:32:_ZTTSt10istrstream@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt10ostrstream@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTTSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTVNSt6locale5facetE@@GLIBCXX_3.4 ++OBJECT:32:_ZTVSt11__timepunctIcE@@GLIBCXX_3.4 ++OBJECT:32:_ZTVSt11__timepunctIwE@@GLIBCXX_3.4 ++OBJECT:32:_ZTVSt16nested_exception@@CXXABI_1.3.5 ++OBJECT:32:_ZTVSt8ios_base@@GLIBCXX_3.4 ++OBJECT:32:_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:32:_ZTVSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:33:_ZTSN10__cxxabiv116__enum_type_infoE@@CXXABI_1.3 ++OBJECT:33:_ZTSNSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:33:_ZTSNSt7__cxx1115messages_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:33:_ZTSNSt7__cxx1115numpunct_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:33:_ZTSNSt7__cxx1115numpunct_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:33:_ZTSSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:34:_ZTSN10__cxxabiv117__array_type_infoE@@CXXABI_1.3 ++OBJECT:34:_ZTSN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 ++OBJECT:34:_ZTSN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3 ++OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:34:_ZTSSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:34:_ZTSSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:36:_ZTSN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3 ++OBJECT:36:_ZTSSt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:36:_ZTSSt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:37:_ZTSN10__cxxabiv120__function_type_infoE@@CXXABI_1.3 ++OBJECT:37:_ZTSN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 ++OBJECT:38:_ZTSN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3 ++OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIcLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIcLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIwLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:39:_ZTSNSt7__cxx1117moneypunct_bynameIwLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:39:_ZTSSt13basic_filebufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:39:_ZTSSt13basic_filebufIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:39:_ZTSSt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:39:_ZTSSt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:39:_ZTSSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:39:_ZTSSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:3:_ZTSPa@@CXXABI_1.3 ++OBJECT:3:_ZTSPb@@CXXABI_1.3 ++OBJECT:3:_ZTSPc@@CXXABI_1.3 ++OBJECT:3:_ZTSPd@@CXXABI_1.3 ++OBJECT:3:_ZTSPe@@CXXABI_1.3 ++OBJECT:3:_ZTSPf@@CXXABI_1.3 ++OBJECT:3:_ZTSPg@@CXXABI_LDBL_1.3 ++OBJECT:3:_ZTSPh@@CXXABI_1.3 ++OBJECT:3:_ZTSPi@@CXXABI_1.3 ++OBJECT:3:_ZTSPj@@CXXABI_1.3 ++OBJECT:3:_ZTSPl@@CXXABI_1.3 ++OBJECT:3:_ZTSPm@@CXXABI_1.3 ++OBJECT:3:_ZTSPn@@CXXABI_1.3.9 ++OBJECT:3:_ZTSPo@@CXXABI_1.3.9 ++OBJECT:3:_ZTSPs@@CXXABI_1.3 ++OBJECT:3:_ZTSPt@@CXXABI_1.3 ++OBJECT:3:_ZTSPv@@CXXABI_1.3 ++OBJECT:3:_ZTSPw@@CXXABI_1.3 ++OBJECT:3:_ZTSPx@@CXXABI_1.3 ++OBJECT:3:_ZTSPy@@CXXABI_1.3 ++OBJECT:3:_ZTSSd@@GLIBCXX_3.4 ++OBJECT:3:_ZTSSi@@GLIBCXX_3.4 ++OBJECT:3:_ZTSSo@@GLIBCXX_3.4 ++OBJECT:40:_ZTISi@@GLIBCXX_3.4 ++OBJECT:40:_ZTISo@@GLIBCXX_3.4 ++OBJECT:40:_ZTISt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTISt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTSN10__cxxabiv123__fundamental_type_infoE@@CXXABI_1.3 ++OBJECT:40:_ZTSSt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTSSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTSSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTSSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTSSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTVNSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26 ++OBJECT:40:_ZTVNSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26 ++OBJECT:40:_ZTVNSt13__future_base11_State_baseE@@GLIBCXX_3.4.15 ++OBJECT:40:_ZTVNSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15 ++OBJECT:40:_ZTVNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 ++OBJECT:40:_ZTVNSt6thread6_StateE@@GLIBCXX_3.4.22 ++OBJECT:40:_ZTVNSt8ios_base7failureB5cxx11E@@GLIBCXX_3.4.21 ++OBJECT:40:_ZTVNSt8ios_base7failureE@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt10bad_typeid@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt10lock_error@@GLIBCXX_3.4.11 ++OBJECT:40:_ZTVSt11logic_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt11range_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt11regex_error@@GLIBCXX_3.4.15 ++OBJECT:40:_ZTVSt12bad_weak_ptr@@GLIBCXX_3.4.15 ++OBJECT:40:_ZTVSt12domain_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt12future_error@@GLIBCXX_3.4.14 ++OBJECT:40:_ZTVSt12length_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt12out_of_range@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt12system_error@@GLIBCXX_3.4.11 ++OBJECT:40:_ZTVSt13bad_exception@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt13runtime_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt14overflow_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt15underflow_error@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt16bad_array_length@@CXXABI_1.3.8 ++OBJECT:40:_ZTVSt16invalid_argument@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt17bad_function_call@@GLIBCXX_3.4.15 ++OBJECT:40:_ZTVSt20bad_array_new_length@@CXXABI_1.3.8 ++OBJECT:40:_ZTVSt8bad_cast@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt9bad_alloc@@GLIBCXX_3.4 ++OBJECT:40:_ZTVSt9exception@@GLIBCXX_3.4 ++OBJECT:41:_ZTSNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 ++OBJECT:41:_ZTSSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:41:_ZTSSt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:45:_ZTSSt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:45:_ZTSSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:46:_ZTSN10__cxxabiv129__pointer_to_member_type_infoE@@CXXABI_1.3 ++OBJECT:46:_ZTSSt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:46:_ZTSSt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:48:_ZTVNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:48:_ZTVNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:48:_ZTVNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:48:_ZTVNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:48:_ZTVSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:48:_ZTVSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:48:_ZTVSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:48:_ZTVSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:49:_ZTSN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:49:_ZTSN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:49:_ZTSSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:49:_ZTSSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_terminalE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt10money_base18_S_default_patternE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIDiE10has_denormE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE11round_styleE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIDiE12max_exponentE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE12min_exponentE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE14max_exponent10E@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE14min_exponent10E@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE5radixE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE6digitsE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDiE8digits10E@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE10has_denormE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE11round_styleE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIDsE12max_exponentE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE12min_exponentE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE14max_exponent10E@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE14min_exponent10E@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE5radixE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E@@GLIBCXX_3.4.11 ++OBJECT:4:_ZNSt14numeric_limitsIDuE10has_denormE@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE11round_styleE@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE12max_exponentE@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE12min_exponentE@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE14max_exponent10E@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE14min_exponent10E@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE5radixE@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE6digitsE@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIDuE8digits10E@@GLIBCXX_3.4.26 ++OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIaE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIaE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIbE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIbE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIcE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIcE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIdE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIdE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIeE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIfE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIfE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE10has_denormE@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE11round_styleE@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE12max_digits10E@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE12max_exponentE@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE12min_exponentE@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE14max_exponent10E@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE14min_exponent10E@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE5radixE@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE6digitsE@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIgE8digits10E@@GLIBCXX_LDBL_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIhE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIhE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIiE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIiE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIjE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIjE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIlE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIlE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsImE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsImE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsInE10has_denormE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE11round_styleE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE12max_digits10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE12max_exponentE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE12min_exponentE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE14max_exponent10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE14min_exponent10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE5radixE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE6digitsE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsInE8digits10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE10has_denormE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE11round_styleE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE12max_digits10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE12max_exponentE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE12min_exponentE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE14max_exponent10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE14min_exponent10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE5radixE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE6digitsE@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIoE8digits10E@@GLIBCXX_3.4.17 ++OBJECT:4:_ZNSt14numeric_limitsIsE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIsE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIsE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsItE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsItE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIwE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIwE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIxE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIxE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt14numeric_limitsIyE12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt14numeric_limitsIyE8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base10has_denormE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base11round_styleE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base12max_digits10E@@GLIBCXX_3.4.14 ++OBJECT:4:_ZNSt21__numeric_limits_base12max_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base12min_exponentE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base14max_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base14min_exponent10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base5radixE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base6digitsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt21__numeric_limits_base8digits10E@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale3allE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale4noneE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale4timeE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale5ctypeE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale7collateE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale7numericE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale8messagesE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt6locale8monetaryE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base10floatfieldE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base10scientificE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base11adjustfieldE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base2inE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3appE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3ateE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3begE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3curE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3decE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3endE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3hexE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3octE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base3outE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base4leftE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base5fixedE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base5rightE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base5truncE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base6badbitE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base6binaryE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base6eofbitE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base6skipwsE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base7failbitE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base7goodbitE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base7showposE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base7unitbufE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base8internalE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base8showbaseE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base9basefieldE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base9boolalphaE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base9showpointE@@GLIBCXX_3.4 ++OBJECT:4:_ZNSt8ios_base9uppercaseE@@GLIBCXX_3.4 ++OBJECT:4:_ZTSPKa@@CXXABI_1.3 ++OBJECT:4:_ZTSPKb@@CXXABI_1.3 ++OBJECT:4:_ZTSPKc@@CXXABI_1.3 ++OBJECT:4:_ZTSPKd@@CXXABI_1.3 ++OBJECT:4:_ZTSPKe@@CXXABI_1.3 ++OBJECT:4:_ZTSPKf@@CXXABI_1.3 ++OBJECT:4:_ZTSPKg@@CXXABI_LDBL_1.3 ++OBJECT:4:_ZTSPKh@@CXXABI_1.3 ++OBJECT:4:_ZTSPKi@@CXXABI_1.3 ++OBJECT:4:_ZTSPKj@@CXXABI_1.3 ++OBJECT:4:_ZTSPKl@@CXXABI_1.3 ++OBJECT:4:_ZTSPKm@@CXXABI_1.3 ++OBJECT:4:_ZTSPKn@@CXXABI_1.3.9 ++OBJECT:4:_ZTSPKo@@CXXABI_1.3.9 ++OBJECT:4:_ZTSPKs@@CXXABI_1.3 ++OBJECT:4:_ZTSPKt@@CXXABI_1.3 ++OBJECT:4:_ZTSPKv@@CXXABI_1.3 ++OBJECT:4:_ZTSPKw@@CXXABI_1.3 ++OBJECT:4:_ZTSPKx@@CXXABI_1.3 ++OBJECT:4:_ZTSPKy@@CXXABI_1.3 ++OBJECT:50:_ZTSSt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:50:_ZTSSt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:50:_ZTSSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:50:_ZTSSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:54:_ZTSN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:54:_ZTSN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:56:_ZTINSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx1110moneypunctIwLb1EEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx118messagesIcEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTINSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTISd@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt10moneypunctIcLb0EE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt10moneypunctIcLb1EE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt10moneypunctIwLb0EE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt10moneypunctIwLb1EE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt21__ctype_abstract_baseIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt21__ctype_abstract_baseIwE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt5ctypeIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt8messagesIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt8messagesIwE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:56:_ZTISt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:56:_ZTSNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTSNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTTSd@@GLIBCXX_3.4 ++OBJECT:56:_ZTTSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:56:_ZTVNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:56:_ZTVNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:56:_ZTVNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:56:_ZTVNSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx1115messages_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx117collateIcEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx117collateIwEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx118messagesIcEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVNSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21 ++OBJECT:56:_ZTVSt14collate_bynameIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt14collate_bynameIwE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt15messages_bynameIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt15messages_bynameIwE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt7collateIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt7collateIwE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt8messagesIcE@@GLIBCXX_3.4 ++OBJECT:56:_ZTVSt8messagesIwE@@GLIBCXX_3.4 ++OBJECT:58:_ZTSSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:58:_ZTSSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:58:_ZTSSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:58:_ZTSSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:59:_ZTSNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:59:_ZTSNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:59:_ZTSSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:59:_ZTSSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:59:_ZTSSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:59:_ZTSSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:60:_ZTSNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:60:_ZTSNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:60:_ZTSNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:60:_ZTSNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:60:_ZTSSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:60:_ZTSSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:60:_ZTSSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:60:_ZTSSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:64:_ZTVN10__cxxabiv116__enum_type_infoE@@CXXABI_1.3 ++OBJECT:64:_ZTVN10__cxxabiv117__array_type_infoE@@CXXABI_1.3 ++OBJECT:64:_ZTVN10__cxxabiv120__function_type_infoE@@CXXABI_1.3 ++OBJECT:64:_ZTVN10__cxxabiv123__fundamental_type_infoE@@CXXABI_1.3 ++OBJECT:64:_ZTVSt9type_info@@GLIBCXX_3.4 ++OBJECT:67:_ZTSSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:67:_ZTSSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:67:_ZTSSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:67:_ZTSSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:69:_ZTSNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:69:_ZTSNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:70:_ZTSNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:70:_ZTSNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:70:_ZTSNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:70:_ZTSNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:72:_ZTVN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3 ++OBJECT:72:_ZTVN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3 ++OBJECT:72:_ZTVN10__cxxabiv129__pointer_to_member_type_infoE@@CXXABI_1.3 ++OBJECT:72:_ZTVNSt7__cxx1115numpunct_bynameIcEE@@GLIBCXX_3.4.21 ++OBJECT:72:_ZTVNSt7__cxx1115numpunct_bynameIwEE@@GLIBCXX_3.4.21 ++OBJECT:72:_ZTVNSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21 ++OBJECT:72:_ZTVNSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21 ++OBJECT:72:_ZTVSt14error_category@@GLIBCXX_3.4.11 ++OBJECT:72:_ZTVSt15numpunct_bynameIcE@@GLIBCXX_3.4 ++OBJECT:72:_ZTVSt15numpunct_bynameIwE@@GLIBCXX_3.4 ++OBJECT:72:_ZTVSt8numpunctIcE@@GLIBCXX_3.4 ++OBJECT:72:_ZTVSt8numpunctIwE@@GLIBCXX_3.4 ++OBJECT:77:_ZTSNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:77:_ZTSNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:79:_ZTSNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:79:_ZTSNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:79:_ZTSNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:79:_ZTSNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:80:_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTTSt13basic_fstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTTSt13basic_fstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTTSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTTSt9strstream@@GLIBCXX_3.4 ++OBJECT:80:_ZTVNSt3_V214error_categoryE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE@@GLIBCXX_3.4.21 ++OBJECT:80:_ZTVSi@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSo@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt10istrstream@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt10ostrstream@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt14basic_ifstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt15time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:80:_ZTVSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 ++OBJECT:81:_ZTSNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:81:_ZTSNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:81:_ZTSNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:81:_ZTSNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4 ++OBJECT:88:_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3 ++OBJECT:88:_ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3 ++OBJECT:88:_ZTVN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3 ++OBJECT:88:_ZTVNSt7__cxx1115time_get_bynameIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVNSt7__cxx1115time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:88:_ZTVSt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:88:_ZTVSt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt20__codecvt_utf16_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt20__codecvt_utf16_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt20__codecvt_utf16_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:88:_ZTVSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:88:_ZTVSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26 ++OBJECT:88:_ZTVSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26 ++OBJECT:88:_ZTVSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21 ++OBJECT:88:_ZTVSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:88:_ZTVSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt10moneypunctIcLb0EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt10moneypunctIcLb1EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt10moneypunctIwLb0EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt10moneypunctIwLb1EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt11__timepunctIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt11__timepunctIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZGVNSt7__cxx1110moneypunctIcLb0EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx1110moneypunctIcLb1EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx1110moneypunctIwLb0EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx1110moneypunctIwLb1EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx117collateIcE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx117collateIwE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx118messagesIcE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx118messagesIwE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx118numpunctIcE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx118numpunctIwE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZGVNSt7collateIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt7collateIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8messagesIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8messagesIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8numpunctIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8numpunctIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZGVNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_max_sizeE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSbIwSt11char_traitsIwESaIwEE4nposE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSs4_Rep11_S_max_sizeE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSs4nposE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10__num_base11_S_atoms_inE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10__num_base12_S_atoms_outE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10money_base8_S_atomsE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10moneypunctIcLb0EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10moneypunctIcLb1EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10moneypunctIwLb0EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt10moneypunctIwLb1EE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt11__timepunctIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt11__timepunctIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1287num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1287num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_LDBL_3.4 ++OBJECT:8:_ZNSt5ctypeIcE10table_sizeE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt5ctypeIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt5ctypeIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7__cxx1110moneypunctIcLb0EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx1110moneypunctIcLb1EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx1110moneypunctIwLb0EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx1110moneypunctIwLb1EE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4nposE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4nposE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx117collateIcE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx117collateIwE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx118messagesIcE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx118messagesIwE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx118numpunctIcE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx118numpunctIwE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx118time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx118time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7codecvtIDiDu11__mbstate_tE2idE@@GLIBCXX_3.4.26 ++OBJECT:8:_ZNSt7codecvtIDic11__mbstate_tE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7codecvtIDsDu11__mbstate_tE2idE@@GLIBCXX_3.4.26 ++OBJECT:8:_ZNSt7codecvtIDsc11__mbstate_tE2idE@@GLIBCXX_3.4.21 ++OBJECT:8:_ZNSt7codecvtIcc11__mbstate_tE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7codecvtIwc11__mbstate_tE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7collateIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7collateIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8messagesIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8messagesIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8numpunctIcE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8numpunctIwE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 ++OBJECT:8:_ZSt15future_category@@GLIBCXX_3.4.14 ++OBJECT:96:_ZTVSt12ctype_bynameIcE@@GLIBCXX_3.4 ++OBJECT:96:_ZTVSt5ctypeIcE@@GLIBCXX_3.4 ++OBJECT:96:_ZTVSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 ++OBJECT:96:_ZTVSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 +diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure +index c07e27569..ffa72a1bb 100755 +--- a/libstdc++-v3/configure ++++ b/libstdc++-v3/configure +@@ -75269,6 +75269,7 @@ case "$target" in + powerpc*-*-linux* | \ + sparc*-*-linux* | \ + s390*-*-linux* | \ ++ sw_64*-*-linux* | \ + alpha*-*-linux*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ +@@ -77752,7 +77753,7 @@ _ACEOF + $as_echo_n "checking for first version to support std::exception_ptr... " >&6; } + case ${target} in + aarch64-*-* | alpha-*-* | hppa*-*-* | i?86-*-* | x86_64-*-* | \ +- m68k-*-* | powerpc*-*-* | s390*-*-* | *-*-solaris* ) ++ m68k-*-* | powerpc*-*-* | s390*-*-* | sw_64-*-* | *-*-solaris* ) + ac_exception_ptr_since_gcc46=yes + ;; + *) +diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac +index e59bcdb29..895240f4e 100644 +--- a/libstdc++-v3/configure.ac ++++ b/libstdc++-v3/configure.ac +@@ -416,6 +416,7 @@ case "$target" in + powerpc*-*-linux* | \ + sparc*-*-linux* | \ + s390*-*-linux* | \ ++ sw_64*-*-linux* | \ + alpha*-*-linux*) + AC_TRY_COMPILE(, [ + #if !defined __LONG_DOUBLE_128__ || (defined(__sparc__) && defined(__arch64__)) +diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host +index ec32980aa..930eef4c5 100644 +--- a/libstdc++-v3/configure.host ++++ b/libstdc++-v3/configure.host +@@ -127,6 +127,9 @@ case "${host_cpu}" in + sparc* | ultrasparc) + try_cpu=sparc + ;; ++ sw_64*) ++ try_cpu=sw_64 ++ ;; + *) + if test -d ${glibcxx_srcdir}/config/cpu/${host_cpu}; then + try_cpu=${host_cpu} +-- +2.25.1 + diff --git a/0013-Sw64-Port-set-raise-FPE-when-DivbyZero-on-Sw_64.patch b/0013-Sw64-Port-set-raise-FPE-when-DivbyZero-on-Sw_64.patch new file mode 100644 index 0000000000000000000000000000000000000000..788d5c804009741aea8d2f493a3ac6c4956eb5f1 --- /dev/null +++ b/0013-Sw64-Port-set-raise-FPE-when-DivbyZero-on-Sw_64.patch @@ -0,0 +1,28 @@ +From e8813c5a4ba57493f92214f6d97433208ac30d9e Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:55:30 +0800 +Subject: [PATCH 13/16] Sw64 Port: set raise FPE when DivbyZero on Sw_64 + platform + +--- + intl/dcigettext.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/intl/dcigettext.c b/intl/dcigettext.c +index a8d4a14d2..a828f0419 100644 +--- a/intl/dcigettext.c ++++ b/intl/dcigettext.c +@@ -72,8 +72,8 @@ extern int errno; + #ifdef _LIBC + /* Guess whether integer division by zero raises signal SIGFPE. + Set to 1 only if you know for sure. In case of doubt, set to 0. */ +-# if defined __alpha__ || defined __arm__ || defined __i386__ \ +- || defined __m68k__ || defined __s390__ ++#if defined __alpha__ || defined __arm__ || defined __i386__ \ ++ || defined __m68k__ || defined __s390__ || defined __sw_64__ + # define INTDIV0_RAISES_SIGFPE 1 + # else + # define INTDIV0_RAISES_SIGFPE 0 +-- +2.25.1 + diff --git a/0014-Sw64-Port-add-lex-builtin-support-in-libcpp.patch b/0014-Sw64-Port-add-lex-builtin-support-in-libcpp.patch new file mode 100644 index 0000000000000000000000000000000000000000..71524b2f9ab5cd43300b63ce36d75e3c6fd618bd --- /dev/null +++ b/0014-Sw64-Port-add-lex-builtin-support-in-libcpp.patch @@ -0,0 +1,35 @@ +From b85fb9eca6a6a7612ae6451995f9908bfbbba72f Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 16:56:12 +0800 +Subject: [PATCH 14/16] Sw64 Port: add lex builtin support in libcpp + +--- + libcpp/lex.cc | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libcpp/lex.cc b/libcpp/lex.cc +index fb1dfabb7..bc2541ef9 100644 +--- a/libcpp/lex.cc ++++ b/libcpp/lex.cc +@@ -168,6 +168,8 @@ acc_char_cmp (word_type val, word_type c) + /* We can get exact results using a compare-bytes instruction. + Get (val == c) via (0 >= (val ^ c)). */ + return __builtin_alpha_cmpbge (0, val ^ c); ++#elif defined(__GNUC__) && defined(__sw_64__) ++ return __builtin_sw_64_cmpbge (0, val ^ c); + #else + word_type magic = 0x7efefefeU; + if (sizeof(word_type) == 8) +@@ -186,7 +188,8 @@ static inline int + acc_char_index (word_type cmp ATTRIBUTE_UNUSED, + word_type val ATTRIBUTE_UNUSED) + { +-#if defined(__GNUC__) && defined(__alpha__) && !WORDS_BIGENDIAN ++#if defined(__GNUC__) && (defined(__alpha__) || defined(__sw_64__)) \ ++ && !WORDS_BIGENDIAN + /* The cmpbge instruction sets *bits* of the result corresponding to + matches in the bytes with no false positives. */ + return __builtin_ctzl (cmp); +-- +2.25.1 + diff --git a/0015-Sw64-Port-libsanitizer.patch b/0015-Sw64-Port-libsanitizer.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0d86ba704a5894c3aa2e7993f71ccf7fe989435 --- /dev/null +++ b/0015-Sw64-Port-libsanitizer.patch @@ -0,0 +1,1290 @@ +From df516f16c04a4806fde50fefc45f9d4c518d6872 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 17:14:17 +0800 +Subject: [PATCH 15/16] Sw64 Port: libsanitizer + +--- + libsanitizer/asan/asan_allocator.h | 5 + + libsanitizer/asan/asan_mapping.h | 3 + + libsanitizer/configure.tgt | 4 + + libsanitizer/lsan/lsan_allocator.cpp | 2 +- + libsanitizer/lsan/lsan_allocator.h | 3 +- + libsanitizer/lsan/lsan_common.cpp | 2 + + libsanitizer/lsan/lsan_common.h | 2 +- + .../sanitizer_common_interceptors.inc | 77 ++++-- + .../sanitizer_common_syscalls.inc | 4 +- + .../sanitizer_common/sanitizer_linux.cpp | 131 +++++++++- + .../sanitizer_common/sanitizer_linux.h | 2 +- + .../sanitizer_linux_libcdep.cpp | 6 +- + .../sanitizer_common/sanitizer_platform.h | 8 + + .../sanitizer_platform_interceptors.h | 6 +- + .../sanitizer_platform_limits_linux.cpp | 2 +- + .../sanitizer_platform_limits_posix.cpp | 16 +- + .../sanitizer_platform_limits_posix.h | 24 +- + .../sanitizer_common/sanitizer_stacktrace.h | 2 + + .../sanitizer_stoptheworld_linux_libcdep.cpp | 8 +- + .../sanitizer_symbolizer_libcdep.cpp | 2 + + libsanitizer/tsan/Makefile.am | 2 +- + libsanitizer/tsan/Makefile.in | 2 +- + libsanitizer/tsan/tsan_interceptors_posix.cpp | 14 +- + libsanitizer/tsan/tsan_platform.h | 41 +++ + libsanitizer/tsan/tsan_platform_linux.cpp | 4 + + libsanitizer/tsan/tsan_rtl.h | 2 +- + libsanitizer/tsan/tsan_rtl_sw64.S | 236 ++++++++++++++++++ + 27 files changed, 550 insertions(+), 60 deletions(-) + create mode 100644 libsanitizer/tsan/tsan_rtl_sw64.S + +diff --git a/libsanitizer/asan/asan_allocator.h b/libsanitizer/asan/asan_allocator.h +index 27d826fb6..8b7b22db6 100644 +--- a/libsanitizer/asan/asan_allocator.h ++++ b/libsanitizer/asan/asan_allocator.h +@@ -149,6 +149,11 @@ typedef DefaultSizeClassMap SizeClassMap; + const uptr kAllocatorSpace = ~(uptr)0; + const uptr kAllocatorSize = 0x8000000000ULL; // 500G + typedef DefaultSizeClassMap SizeClassMap; ++# elif SANITIZER_SW64 ++// If kSpaceBeg is ~0 then SpaceBeg is chosen dynamically my mmap. ++const uptr kAllocatorSpace = ~(uptr)0; ++const uptr kAllocatorSize = 0x40000000000ULL; // 4T. ++typedef DefaultSizeClassMap SizeClassMap; + # else + const uptr kAllocatorSpace = 0x600000000000ULL; + const uptr kAllocatorSize = 0x40000000000ULL; // 4T. +diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h +index 4b0037fce..3b752d81d 100644 +--- a/libsanitizer/asan/asan_mapping.h ++++ b/libsanitizer/asan/asan_mapping.h +@@ -165,6 +165,7 @@ static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; + static const u64 kRiscv64_ShadowOffset64 = 0xd55550000; + static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000; + static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37; ++static const u64 kSW64_ShadowOffset64 = 1ULL << 49; + static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; + static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52; + static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000 +@@ -205,6 +206,8 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 + # define SHADOW_OFFSET kAArch64_ShadowOffset64 + # elif defined(__powerpc64__) + # define SHADOW_OFFSET kPPC64_ShadowOffset64 ++# elif defined(__sw_64__) ++# define SHADOW_OFFSET kSW64_ShadowOffset64 + # elif defined(__s390x__) + # define SHADOW_OFFSET kSystemZ_ShadowOffset64 + # elif SANITIZER_FREEBSD +diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt +index fb89df493..f62e59ef8 100644 +--- a/libsanitizer/configure.tgt ++++ b/libsanitizer/configure.tgt +@@ -54,6 +54,10 @@ case "${target}" in + ;; + arm*-*-linux*) + ;; ++ sw_64*-*-linux*) ++ TSAN_SUPPORTED=yes ++ LSAN_SUPPORTED=yes ++ ;; + mips*-*-linux*) + ;; + aarch64*-*-linux*) +diff --git a/libsanitizer/lsan/lsan_allocator.cpp b/libsanitizer/lsan/lsan_allocator.cpp +index 91e34ebb3..9895719fd 100644 +--- a/libsanitizer/lsan/lsan_allocator.cpp ++++ b/libsanitizer/lsan/lsan_allocator.cpp +@@ -28,7 +28,7 @@ extern "C" void *memset(void *ptr, int value, uptr num); + namespace __lsan { + #if defined(__i386__) || defined(__arm__) + static const uptr kMaxAllowedMallocSize = 1UL << 30; +-#elif defined(__mips64) || defined(__aarch64__) ++#elif defined(__mips64) || defined(__aarch64__) || defined(__sw_64__) + static const uptr kMaxAllowedMallocSize = 4UL << 30; + #else + static const uptr kMaxAllowedMallocSize = 8UL << 30; +diff --git a/libsanitizer/lsan/lsan_allocator.h b/libsanitizer/lsan/lsan_allocator.h +index 45c6ac406..a6ca2b250 100644 +--- a/libsanitizer/lsan/lsan_allocator.h ++++ b/libsanitizer/lsan/lsan_allocator.h +@@ -50,7 +50,8 @@ struct ChunkMetadata { + }; + + #if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) ++ defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) || \ ++ defined(__sw_64__) + template + struct AP32 { + static const uptr kSpaceBeg = 0; +diff --git a/libsanitizer/lsan/lsan_common.cpp b/libsanitizer/lsan/lsan_common.cpp +index 308dbb3e4..16b664b14 100644 +--- a/libsanitizer/lsan/lsan_common.cpp ++++ b/libsanitizer/lsan/lsan_common.cpp +@@ -163,6 +163,8 @@ static inline bool CanBeAHeapPointer(uptr p) { + return ((p >> 47) == 0); + #elif defined(__mips64) + return ((p >> 40) == 0); ++#elif defined(__sw_64__) ++ return ((p >> 52) == 0); + #elif defined(__aarch64__) + unsigned runtimeVMA = + (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); +diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h +index f9b55e4e8..6afff378c 100644 +--- a/libsanitizer/lsan/lsan_common.h ++++ b/libsanitizer/lsan/lsan_common.h +@@ -36,7 +36,7 @@ + #define CAN_SANITIZE_LEAKS 0 + #elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \ + (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ +- defined(__powerpc64__) || defined(__s390x__)) ++ defined(__powerpc64__) || defined(__s390x__) || defined(__sw_64__)) + #define CAN_SANITIZE_LEAKS 1 + #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_MAC) + #define CAN_SANITIZE_LEAKS 1 +diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +index abb38ccfa..2b6a7d612 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc ++++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +@@ -1532,6 +1532,16 @@ VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) + + INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) + VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) ++ ++INTERCEPTOR(int, __isoc23_vscanf, const char *format, va_list ap) ++VSCANF_INTERCEPTOR_IMPL(__isoc23_vscanf, false, format, ap) ++ ++INTERCEPTOR(int, __isoc23_vsscanf, const char *str, const char *format, ++ va_list ap) ++VSCANF_INTERCEPTOR_IMPL(__isoc23_vsscanf, false, str, format, ap) ++ ++INTERCEPTOR(int, __isoc23_vfscanf, void *stream, const char *format, va_list ap) ++VSCANF_INTERCEPTOR_IMPL(__isoc23_vfscanf, false, stream, format, ap) + #endif // SANITIZER_INTERCEPT_ISOC99_SCANF + + INTERCEPTOR(int, scanf, const char *format, ...) +@@ -1552,6 +1562,15 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) + + INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) + FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) ++ ++INTERCEPTOR(int, __isoc23_scanf, const char *format, ...) ++FORMAT_INTERCEPTOR_IMPL(__isoc23_scanf, __isoc23_vscanf, format) ++ ++INTERCEPTOR(int, __isoc23_fscanf, void *stream, const char *format, ...) ++FORMAT_INTERCEPTOR_IMPL(__isoc23_fscanf, __isoc23_vfscanf, stream, format) ++ ++INTERCEPTOR(int, __isoc23_sscanf, const char *str, const char *format, ...) ++FORMAT_INTERCEPTOR_IMPL(__isoc23_sscanf, __isoc23_vsscanf, str, format) + #endif + + #endif +@@ -1575,7 +1594,13 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) + COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \ + COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \ + COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \ +- COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); ++ COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_scanf); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_sscanf); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_fscanf); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_vscanf); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_vsscanf); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_vfscanf); + #else + #define INIT_ISOC99_SCANF + #endif +@@ -3502,30 +3527,26 @@ UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr, + (real_endptr - nptr) + 1 : 0); + } + +- + #if SANITIZER_INTERCEPT_STRTOIMAX +-INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { +- void *ctx; +- COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); +- // FIXME: under ASan the call below may write to freed memory and corrupt +- // its metadata. See +- // https://github.com/google/sanitizers/issues/321. ++template ++static ALWAYS_INLINE auto StrtoimaxImpl(void *ctx, Fn real, const char *nptr, ++ char **endptr, int base) ++ -> decltype(real(nullptr, nullptr, 0)) { + char *real_endptr; +- INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base); ++ auto res = real(nptr, &real_endptr, base); + StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); + return res; + } + ++INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { ++ void *ctx; ++ COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); ++ return StrtoimaxImpl(ctx, REAL(strtoimax), nptr, endptr, base); ++} + INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); +- // FIXME: under ASan the call below may write to freed memory and corrupt +- // its metadata. See +- // https://github.com/google/sanitizers/issues/321. +- char *real_endptr; +- UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base); +- StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); +- return res; ++ return StrtoimaxImpl(ctx, REAL(strtoumax), nptr, endptr, base); + } + + #define INIT_STRTOIMAX \ +@@ -3535,6 +3556,25 @@ INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { + #define INIT_STRTOIMAX + #endif + ++#if SANITIZER_INTERCEPT_STRTOIMAX && SANITIZER_GLIBC ++INTERCEPTOR(INTMAX_T, __isoc23_strtoimax, const char *nptr, char **endptr, int base) { ++ void *ctx; ++ COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoimax, nptr, endptr, base); ++ return StrtoimaxImpl(ctx, REAL(__isoc23_strtoimax), nptr, endptr, base); ++} ++INTERCEPTOR(UINTMAX_T, __isoc23_strtoumax, const char *nptr, char **endptr, int base) { ++ void *ctx; ++ COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoumax, nptr, endptr, base); ++ return StrtoimaxImpl(ctx, REAL(__isoc23_strtoumax), nptr, endptr, base); ++} ++ ++# define INIT_STRTOIMAX_C23 \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_strtoimax); \ ++ COMMON_INTERCEPT_FUNCTION(__isoc23_strtoumax); ++#else ++# define INIT_STRTOIMAX_C23 ++#endif ++ + #if SANITIZER_INTERCEPT_MBSTOWCS + INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { + void *ctx; +@@ -4708,7 +4748,11 @@ INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { + } + return res; + } ++#ifdef SANITIZER_SW64 ++#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION_VER(shmctl, "GLIBC_2.2"); ++#else + #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); ++#endif + #else + #define INIT_SHMCTL + #endif +@@ -10325,6 +10369,7 @@ static void InitializeCommonInterceptors() { + INIT_GETCWD; + INIT_GET_CURRENT_DIR_NAME; + INIT_STRTOIMAX; ++ INIT_STRTOIMAX_C23; + INIT_MBSTOWCS; + INIT_MBSNRTOWCS; + INIT_WCSTOMBS; +diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc +index a38b13408..fd4e1e3b6 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc ++++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc +@@ -2512,7 +2512,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { + # if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ +- SANITIZER_RISCV64) ++ defined(__sw_64__) || SANITIZER_RISCV64) + if (data) { + if (request == ptrace_setregs) { + PRE_READ((void *)data, struct_user_regs_struct_sz); +@@ -2534,7 +2534,7 @@ POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { + # if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ +- SANITIZER_RISCV64) ++ defined(__sw_64__) || SANITIZER_RISCV64) + if (res >= 0 && data) { + // Note that this is different from the interceptor in + // sanitizer_common_interceptors.inc. +diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_linux.cpp +index aa59d9718..711079d86 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_linux.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp +@@ -50,6 +50,16 @@ + #undef stat + #endif + ++#if defined(__sw_64__) ++#define stat kernel_stat ++#define stat64 kernel_stat64 ++#include ++#undef stat ++#undef stat64 ++#include ++#include ++#endif ++ + #include + #include + #include +@@ -282,7 +292,7 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) { + } + #endif + +-#if defined(__mips64) ++#if defined(__mips64) || defined(__sw_64__) + // Undefine compatibility macros from + // so that they would not clash with the kernel_stat + // st_[a|m|c]time fields +@@ -312,6 +322,12 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { + out->st_size = in->st_size; + out->st_blksize = in->st_blksize; + out->st_blocks = in->st_blocks; ++#if defined(__sw_64__) ++ // There's no nsecs in sw_64's struct stat ++ out->st_atim.tv_sec = in->st_atime; ++ out->st_mtim.tv_sec = in->st_mtime; ++ out->st_ctim.tv_sec = in->st_ctime; ++#else + #if defined(__USE_MISC) || \ + defined(__USE_XOPEN2K8) || \ + defined(SANITIZER_ANDROID) +@@ -329,6 +345,7 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { + out->st_ctime = in->st_ctime; + out->st_atimensec = in->st_ctime_nsec; + #endif ++#endif + } + #endif + +@@ -339,8 +356,8 @@ uptr internal_stat(const char *path, void *buf) { + return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, + 0); + #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS +-# if defined(__mips64) +- // For mips64, stat syscall fills buffer in the format of kernel_stat ++# if defined(__mips64) || defined(__sw_64__) ++ // For mips64 and sw_64, stat syscall fills buffer in the format of kernel_stat + struct kernel_stat kbuf; + int res = internal_syscall(SYSCALL(stat), path, &kbuf); + kernel_stat_to_stat(&kbuf, (struct stat *)buf); +@@ -364,8 +381,8 @@ uptr internal_lstat(const char *path, void *buf) { + return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, + AT_SYMLINK_NOFOLLOW); + #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS +-# if SANITIZER_MIPS64 +- // For mips64, lstat syscall fills buffer in the format of kernel_stat ++# if SANITIZER_MIPS64 || SANITIZER_SW64 ++ // For mips64 and sw_64, lstat syscall fills buffer in the format of kernel_stat + struct kernel_stat kbuf; + int res = internal_syscall(SYSCALL(lstat), path, &kbuf); + kernel_stat_to_stat(&kbuf, (struct stat *)buf); +@@ -383,8 +400,8 @@ uptr internal_lstat(const char *path, void *buf) { + + uptr internal_fstat(fd_t fd, void *buf) { + #if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS +-#if SANITIZER_MIPS64 +- // For mips64, fstat syscall fills buffer in the format of kernel_stat ++#if (SANITIZER_MIPS64 || SANITIZER_SW64) ++ // For mips64 and sw_64, fstat syscall fills buffer in the format of kernel_stat + struct kernel_stat kbuf; + int res = internal_syscall(SYSCALL(fstat), fd, &kbuf); + kernel_stat_to_stat(&kbuf, (struct stat *)buf); +@@ -718,6 +735,19 @@ uptr internal_waitpid(int pid, int *status, int options) { + 0 /* rusage */); + } + ++#ifdef __sw_64__ ++uptr internal_getpid() { ++ return internal_syscall(SYSCALL(getxpid)); ++} ++ ++uptr internal_getppid() { ++ uptr ppid; ++ internal_syscall(SYSCALL(getxpid)); ++ asm("mov $20, %0\n" ++ :"=r"(ppid)); ++ return ppid; ++} ++#else + uptr internal_getpid() { + return internal_syscall(SYSCALL(getpid)); + } +@@ -725,6 +755,7 @@ uptr internal_getpid() { + uptr internal_getppid() { + return internal_syscall(SYSCALL(getppid)); + } ++#endif + + int internal_dlinfo(void *handle, int request, void *p) { + #if SANITIZER_FREEBSD +@@ -759,7 +790,7 @@ uptr internal_sigaltstack(const void *ss, void *oss) { + } + + int internal_fork() { +-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS ++#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_SW64 + return internal_syscall(SYSCALL(clone), SIGCHLD, 0); + #else + return internal_syscall(SYSCALL(fork)); +@@ -826,7 +857,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { + // rt_sigaction, so we need to do the same (we'll need to reimplement the + // restorers; for x86_64 the restorer address can be obtained from + // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact). +-#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 ++#if ( !SANITIZER_ANDROID || !SANITIZER_MIPS32 ) && !SANITIZER_SW64 + k_act.sa_restorer = u_act->sa_restorer; + #endif + } +@@ -842,7 +873,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { + internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask, + sizeof(__sanitizer_kernel_sigset_t)); + u_oldact->sa_flags = k_oldact.sa_flags; +-#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 ++#if ( !SANITIZER_ANDROID || !SANITIZER_MIPS32 ) && !SANITIZER_SW64 + u_oldact->sa_restorer = k_oldact.sa_restorer; + #endif + } +@@ -1045,6 +1076,11 @@ uptr GetMaxVirtualAddress() { + return (1ULL << 38) - 1; + # elif defined(__mips64) + return (1ULL << 40) - 1; // 0x000000ffffffffffUL; ++# elif defined(__sw_64__) ++// SW64 has a 42-bit user address space(4TiB) ++// according to TASK_SIZE in kernel. ++// In sw6b PGTABLE is SW_4LEVEL. ++ return (1ULL << 52) - 1; // 0x000fffffffffffffUL; + # elif defined(__s390x__) + return (1ULL << 53) - 1; // 0x001fffffffffffffUL; + #elif defined(__sparc__) +@@ -1377,6 +1413,71 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + : "memory"); + return res; + } ++#elif defined(__sw_64__) ++uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ++ int *parent_tidptr, void *newtls, int *child_tidptr) { ++ long long res; ++ if (!fn || !child_stack) ++ return -EINVAL; ++ child_stack = (char *)child_stack - 4 * sizeof(unsigned long long); ++ ((unsigned long long *)child_stack)[0] = (uptr)fn; ++ ((unsigned long long *)child_stack)[1] = (uptr)arg; ++ ((unsigned long long *)child_stack)[2] = (uptr)flags; ++ ++ register void *r20 __asm__("$20") = newtls; ++ register int *r22 __asm__("$22") = child_tidptr; ++ ++ __asm__ __volatile__( ++ /* $v0 = syscall($v0 = __NR_clone, ++ * $a0 = flags, ++ * $a1 = child_stack, ++ * $a2 = parent_tidptr, ++ * $a3 = child_tidptr, ++ * $a4 = new_tls) ++ */ ++ "mov %[flag],$16\n" ++ "mov %[usp],$17\n" ++ "mov %[ptid],$18\n" ++ "ldl $19,0($sp)\n" ++ "mov %5,$20\n" ++ /* Store the fifth argument on stack ++ * if we are using 32-bit abi. ++ */ ++ "ldi $0,%[NR_clone];\n" ++ "sys_call 0x83;\n" ++ ++ /* if ($v0 != 0) ++ * return; ++ */ ++ "bne $0,1f;\n" ++ "mov $31,$15;\n" ++ /* Call "fn(arg)". */ ++ "ldl $27,0($sp);\n" ++ "ldl $16,8($sp);\n" ++ "ldi $sp,32($sp);\n" ++ ++ "call $26,($27),0;\n" ++ "ldgp $29, 0($26);\n" ++ ++ /* Call _exit($v0). */ ++ "mov $0,$16;\n" ++ "ldi $0,%[NR_exit];\n" ++ "sys_call 0x83;\n" ++ ++ /* Return to parent. */ ++ "1:\n" ++ : "=r" (res) ++ : [flag]"r"(flags), ++ [usp]"r"(child_stack), ++ [ptid]"r"(parent_tidptr), ++ "r"(r20), ++ "r"(r22), ++ [NR_clone]"i"(__NR_clone), ++ [NR_exit]"i"(__NR_exit) ++ : "memory", "$30"); ++ ++ return res; ++} + #elif defined(__aarch64__) + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { +@@ -2026,6 +2127,11 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.regs[29]; + *sp = ucontext->uc_mcontext.sp; ++#elif defined(__sw_64__) ++ ucontext_t *ucontext = (ucontext_t*)context; ++ *pc = ucontext->uc_mcontext.sc_pc; ++ *bp = ucontext->uc_mcontext.sc_regs[15]; ++ *sp = ucontext->uc_mcontext.sc_regs[30]; + #elif defined(__hppa__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.sc_iaoq[0]; +@@ -2103,6 +2209,11 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.gregs[30]; + *sp = ucontext->uc_mcontext.gregs[29]; ++#elif defined(__sw_64__) ++ ucontext_t *ucontext = (ucontext_t*)context; ++ *pc = ucontext->uc_mcontext.sc_pc; ++ *bp = ucontext->uc_mcontext.sc_regs[15]; ++ *sp = ucontext->uc_mcontext.sc_regs[30]; + #elif defined(__s390__) + ucontext_t *ucontext = (ucontext_t*)context; + # if defined(__s390x__) +diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.h b/libsanitizer/sanitizer_common/sanitizer_linux.h +index 6a235db0e..a5d18e73d 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_linux.h ++++ b/libsanitizer/sanitizer_common/sanitizer_linux.h +@@ -73,7 +73,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact); + void internal_sigdelset(__sanitizer_sigset_t *set, int signum); + #if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ + defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64 ++ defined(__arm__) || defined(__sw_64__) || SANITIZER_RISCV64 + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr); + #endif +diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +index 4f22c78a1..ef8ab755f 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +@@ -203,7 +203,7 @@ void InitTlsSize() { + g_use_dlpi_tls_data = + GetLibcVersion(&major, &minor, &patch) && major == 2 && minor >= 25; + +-#if defined(__aarch64__) || defined(__x86_64__) || defined(__powerpc64__) ++#if defined(__aarch64__) || defined(__x86_64__) || defined(__powerpc64__) || defined(__sw_64__) + void *get_tls_static_info = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); + size_t tls_align; + ((void (*)(size_t *, size_t *))get_tls_static_info)(&g_tls_size, &tls_align); +@@ -282,6 +282,8 @@ static uptr ThreadDescriptorSizeFallback() { + val = 1776; + #elif defined(__powerpc64__) + val = 1776; // from glibc.ppc64le 2.20-8.fc21 ++#elif defined(__sw_64__) ++ val = 1776; + #endif + return val; + } +@@ -471,7 +473,7 @@ static void GetTls(uptr *addr, uptr *size) { + *size = g_tls_size; + *addr -= *size; + *addr += ThreadDescriptorSize(); +-#elif SANITIZER_GLIBC && defined(__aarch64__) ++#elif SANITIZER_GLIBC && (defined(__aarch64__) || defined(__sw_64__)) + *addr = reinterpret_cast(__builtin_thread_pointer()) - + ThreadDescriptorSize(); + *size = g_tls_size + ThreadDescriptorSize(); +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h +index 3153de34e..5cec9a7c0 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform.h ++++ b/libsanitizer/sanitizer_common/sanitizer_platform.h +@@ -159,6 +159,12 @@ + # define SANITIZER_MIPS64 0 + #endif + ++#if defined(__sw_64__) ++# define SANITIZER_SW64 1 ++#else ++# define SANITIZER_SW64 0 ++#endif ++ + #if defined(__s390__) + # define SANITIZER_S390 1 + # if defined(__s390x__) +@@ -264,6 +270,8 @@ + # endif + #elif defined(__sparc__) + #define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) ++#elif defined(__sw_64__) ++# define SANITIZER_MMAP_RANGE_SIZE 1ULL << 52 + #else + # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) + #endif +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +index 14610f2df..03cdf0a07 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +@@ -234,7 +234,11 @@ + #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX + #define SANITIZER_INTERCEPT_TIME SI_POSIX + #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) ++#if SANITIZER_SW64 ++#define SANITIZER_INTERCEPT_GLOB64 0 ++#else + #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC ++#endif + #define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX + #define SANITIZER_INTERCEPT_WAIT SI_POSIX + #define SANITIZER_INTERCEPT_INET SI_POSIX +@@ -271,7 +275,7 @@ + #if SI_LINUX_NOT_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) ++ defined(__s390__) || defined(__sw_64__) || SANITIZER_RISCV64) + #define SANITIZER_INTERCEPT_PTRACE 1 + #else + #define SANITIZER_INTERCEPT_PTRACE 0 +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp +index 2b1a2f793..e7b20605f 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp +@@ -68,7 +68,7 @@ namespace __sanitizer { + + # if !defined(__powerpc64__) && !defined(__x86_64__) && \ + !defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \ +- !defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__) ++ !defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__) && !defined(__sw_64__) + COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat)); + #endif + +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +index c335f33dd..c96d9b043 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +@@ -94,7 +94,7 @@ + # include + # include + # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__hexagon__) || SANITIZER_RISCV64 ++ defined(__hexagon__) || defined(__sw_64__) || SANITIZER_RISCV64 + # include + # ifdef __arm__ + typedef struct user_fpregs elf_fpregset_t; +@@ -141,7 +141,7 @@ typedef struct user_fpregs elf_fpregset_t; + #include + #include + #include +-#if defined(__mips64) ++#if defined(__mips64) || defined(__sw_64__) // for elf_gregset_t + # include + #endif + #include +@@ -242,7 +242,7 @@ namespace __sanitizer { + // has been removed from glibc 2.28. + #if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ +- defined(__x86_64__) || SANITIZER_RISCV64 ++ defined(__x86_64__) || SANITIZER_RISCV64 || defined(__sw_64__) + #define SIZEOF_STRUCT_USTAT 32 + # elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \ + defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \ +@@ -322,14 +322,14 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) ++ defined(__s390__) || SANITIZER_RISCV64 || defined(__sw_64__)) + #if defined(__mips64) || defined(__powerpc64__) || defined(__arm__) + unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs); + unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t); + #elif SANITIZER_RISCV64 + unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); + unsigned struct_user_fpregs_struct_sz = sizeof(struct __riscv_q_ext_state); +-#elif defined(__aarch64__) ++#elif defined(__aarch64__) || defined(__sw_64__) + unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); + unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state); + #elif defined(__s390__) +@@ -341,12 +341,12 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + #endif // __mips64 || __powerpc64__ || __aarch64__ + #if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ + defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ +- SANITIZER_RISCV64 ++ defined(__sw_64__) || SANITIZER_RISCV64 + unsigned struct_user_fpxregs_struct_sz = 0; + #else + unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct); + #endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__ +-// || __s390__ ++// || __s390__ || __sw_64__ + #ifdef __arm__ + unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE; + #else +@@ -1080,7 +1080,7 @@ CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); + // didn't exist. + CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); + #endif +-#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) ++#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && !SANITIZER_SW64 + CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); + #endif + +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +index da53b5abe..524a6b942 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +@@ -74,6 +74,9 @@ const unsigned struct_kernel_stat64_sz = 104; + #elif defined(__aarch64__) + const unsigned struct_kernel_stat_sz = 128; + const unsigned struct_kernel_stat64_sz = 104; ++#elif defined(__sw_64__) ++const unsigned struct_kernel_stat_sz = 80; ++const unsigned struct_kernel_stat64_sz = 136; + #elif defined(__powerpc__) && !defined(__powerpc64__) + const unsigned struct_kernel_stat_sz = 72; + const unsigned struct_kernel_stat64_sz = 104; +@@ -105,7 +108,10 @@ const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64 + # elif defined(__hexagon__) + const unsigned struct_kernel_stat_sz = 128; + const unsigned struct_kernel_stat64_sz = 0; +-# endif ++#elif defined(__sw_64__) ++const unsigned struct_kernel_stat_sz = 80; ++const unsigned struct_kernel_stat64_sz = 136; ++#endif + struct __sanitizer_perf_event_attr { + unsigned type; + unsigned size; +@@ -263,15 +269,15 @@ struct __sanitizer_shmid_ds { + u64 shm_ctime; + #else + uptr shm_atime; +-#if !defined(_LP64) && !defined(__mips__) ++#if !defined(_LP64) && !defined(__mips__) && !defined(__sw_64__) + uptr __unused1; + #endif + uptr shm_dtime; +-#if !defined(_LP64) && !defined(__mips__) ++#if !defined(_LP64) && !defined(__mips__) && !defined(__sw_64__) + uptr __unused2; + #endif + uptr shm_ctime; +-#if !defined(_LP64) && !defined(__mips__) ++#if !defined(_LP64) && !defined(__mips__) && !defined(__sw_64__) + uptr __unused3; + #endif + #endif +@@ -515,7 +521,7 @@ typedef int __sanitizer_clockid_t; + + #if SANITIZER_LINUX + # if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ +- defined(__mips__) || defined(__hexagon__) ++ defined(__mips__) || defined(__hexagon__) && !defined(__sw_64__) + typedef unsigned __sanitizer___kernel_uid_t; + typedef unsigned __sanitizer___kernel_gid_t; + #else +@@ -528,7 +534,7 @@ typedef long long __sanitizer___kernel_off_t; + typedef long __sanitizer___kernel_off_t; + #endif + +-#if defined(__powerpc__) || defined(__mips__) ++#if defined(__powerpc__) || defined(__mips__) && !defined(__sw_64__) + typedef unsigned int __sanitizer___kernel_old_uid_t; + typedef unsigned int __sanitizer___kernel_old_gid_t; + #else +@@ -640,7 +646,7 @@ struct __sanitizer_sigaction { + #endif + #endif + #endif +-#if SANITIZER_LINUX ++#if SANITIZER_LINUX && !defined(__sw_64__) + void (*sa_restorer)(); + #endif + #if defined(__mips__) && (SANITIZER_WORDSIZE == 32) +@@ -820,7 +826,7 @@ typedef void __sanitizer_FILE; + #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) ++ defined(__s390__) || defined(__sw_64__) || SANITIZER_RISCV64) + extern unsigned struct_user_regs_struct_sz; + extern unsigned struct_user_fpregs_struct_sz; + extern unsigned struct_user_fpxregs_struct_sz; +@@ -906,7 +912,7 @@ struct __sanitizer_cookie_io_functions_t { + #define IOC_NRBITS 8 + #define IOC_TYPEBITS 8 + #if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || \ +- defined(__sparc__) ++ defined(__sparc__) || defined(__sw_64__) + #define IOC_SIZEBITS 13 + #define IOC_DIRBITS 3 + #define IOC_NONE 1U +diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h +index 11c6154b0..35a4bfd16 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h ++++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h +@@ -24,6 +24,8 @@ static const u32 kStackTraceMax = 256; + + #if SANITIZER_LINUX && defined(__mips__) + # define SANITIZER_CAN_FAST_UNWIND 0 ++#elif defined(__sw_64__) ++# define SANITIZER_CAN_FAST_UNWIND 0 + #elif SANITIZER_WINDOWS + # define SANITIZER_CAN_FAST_UNWIND 0 + #else +diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +index 403bda117..574a82dc5 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +@@ -16,7 +16,7 @@ + #if SANITIZER_LINUX && \ + (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ + defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64) ++ defined(__arm__) || defined(__sw_64__) || SANITIZER_RISCV64) + + #include "sanitizer_stoptheworld.h" + +@@ -508,6 +508,12 @@ typedef struct user regs_struct; + # define REG_SP regs[EF_REG29] + # endif + ++#elif defined(__sw_64__) ++typedef struct user regs_struct; ++static constexpr uptr kExtraRegs[] = {0}; ++#define REG_SP regs[EF_SP] ++#define ARCH_IOVEC_FOR_GETREGSET ++ + #elif defined(__aarch64__) + typedef struct user_pt_regs regs_struct; + #define REG_SP sp +diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +index 3fc994fd3..8f1cba26f 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +@@ -273,6 +273,8 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess { + const char* const kSymbolizerArch = "--default-arch=s390x"; + #elif defined(__s390__) + const char* const kSymbolizerArch = "--default-arch=s390"; ++#elif defined(__sw_64__) ++ const char* const kSymbolizerArch = "--default-arch=sw_64"; + #else + const char* const kSymbolizerArch = "--default-arch=unknown"; + #endif +diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am +index ae588a67d..f0608f3d1 100644 +--- a/libsanitizer/tsan/Makefile.am ++++ b/libsanitizer/tsan/Makefile.am +@@ -50,7 +50,7 @@ tsan_files = \ + tsan_vector_clock.cpp + + libtsan_la_SOURCES = $(tsan_files) +-EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S tsan_rtl_s390x.S ++EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S tsan_rtl_s390x.S tsan_rtl_sw64.S + libtsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(TSAN_TARGET_DEPENDENT_OBJECTS) + libtsan_la_DEPENDENCIES = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(TSAN_TARGET_DEPENDENT_OBJECTS) + if LIBBACKTRACE_SUPPORTED +diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in +index 538d2e8eb..4c1be63a3 100644 +--- a/libsanitizer/tsan/Makefile.in ++++ b/libsanitizer/tsan/Makefile.in +@@ -456,7 +456,7 @@ tsan_files = \ + tsan_vector_clock.cpp + + libtsan_la_SOURCES = $(tsan_files) +-EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S tsan_rtl_s390x.S ++EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S tsan_rtl_s390x.S tsan_rtl_sw64.S + libtsan_la_LIBADD = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(top_builddir)/interception/libinterception.la \ +diff --git a/libsanitizer/tsan/tsan_interceptors_posix.cpp b/libsanitizer/tsan/tsan_interceptors_posix.cpp +index 9a85ee00d..54532a0fd 100644 +--- a/libsanitizer/tsan/tsan_interceptors_posix.cpp ++++ b/libsanitizer/tsan/tsan_interceptors_posix.cpp +@@ -72,7 +72,7 @@ struct ucontext_t { + #endif + + #if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \ +- defined(__s390x__) ++ defined(__s390x__) || defined(__sw_64__) + #define PTHREAD_ABI_BASE "GLIBC_2.3.2" + #elif defined(__aarch64__) || SANITIZER_PPC64V2 + #define PTHREAD_ABI_BASE "GLIBC_2.17" +@@ -141,7 +141,7 @@ typedef __sanitizer::u16 mode_t; + # define F_TLOCK 2 /* Test and lock a region for exclusive use. */ + # define F_TEST 3 /* Test a region for other processes locks. */ + +-#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD ++#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SW64 + const int SA_SIGINFO = 0x40; + const int SIG_SETMASK = 3; + #elif defined(__mips__) +@@ -2487,7 +2487,7 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act, + sigactions[sig].sa_flags = *(volatile int const *)&act->sa_flags; + internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask, + sizeof(sigactions[sig].sa_mask)); +-#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD ++#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_SW64 + sigactions[sig].sa_restorer = act->sa_restorer; + #endif + internal_memcpy(&newact, act, sizeof(newact)); +@@ -2786,6 +2786,14 @@ void InitializeInterceptors() { + TSAN_INTERCEPT(pthread_timedjoin_np); + #endif + ++ #if SANITIZER_SW64 ++ // sw64 have two version of timer function, osf_xxx with @glibc2.0, ++ // which is 32bits syscall for old kernal. xxx with @glibc2.1 is 64bits ++ // syscall for new kernal, we use the new one. ++ TSAN_INTERCEPT_VER(setitimer, "GLIBC_2.1"); ++ TSAN_INTERCEPT_VER(setitimer, "GLIBC_2.1"); ++ #endif ++ + TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE); + TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE); + TSAN_INTERCEPT_VER(pthread_cond_broadcast, PTHREAD_ABI_BASE); +diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h +index 7ff0acace..7ae0c9f3b 100644 +--- a/libsanitizer/tsan/tsan_platform.h ++++ b/libsanitizer/tsan/tsan_platform.h +@@ -392,6 +392,44 @@ struct MappingS390x { + static const uptr kMidAppMemEnd = 0; + }; + ++// TODO(sw64_map): as sw64 kernal doesn't map such large space, we just map ++// it for test, for now it works will. ++// TODO(sw64_map_la): as sw64 map all space in low address, we set all user ++// space ++// in Lo address, perhaps there is some way to change it. ++/* ++C/C++ on linux/sw64 (52-bit VMA) ++0000 0000 0000 - 0001 2000 0000: modules and main thread stack ++0001 2000 0000 - 0008 0000 0000: main binary ++0400 0000 0000 - 0600 0000 0000: pie main binary (including heap) ++0600 0000 0000 - 4000 0000 0000: - ++4000 0000 0000 - 6000 0000 0000: shadow ++6000 0000 0000 - 7000 0000 0000: metainfo ++7000 0000 0000 - 7c00 0000 0000: trace ++*/ ++ ++struct MappingSW64_52 { ++ static const uptr kLoAppMemBeg = 0x0000000000000ull; ++ static const uptr kLoAppMemEnd = 0x0600000000000ull; ++ static const uptr kShadowBeg = 0x4000000000000ull; ++ static const uptr kShadowEnd = 0x6000000000000ull; ++ static const uptr kHiAppMemBeg = 0xfff0000000000ull; ++ static const uptr kHiAppMemEnd = 0xfff0000000000ull; ++ static const uptr kShadowMsk = 0x0000000000000ull; ++ //distans between lo address to shadow begin ++ static const uptr kShadowXor = 0x1000000000000ull; ++ static const uptr kShadowAdd = 0x0000000000000ull; ++ static const uptr kHeapMemBeg = 0xff00000000000ull; ++ static const uptr kHeapMemEnd = 0xff00000000000ull; ++ static const uptr kMetaShadowBeg = 0x6000000000000ull; ++ static const uptr kMetaShadowEnd = 0x7000000000000ull; ++ static const uptr kTraceMemBeg = 0x7000000000000ull; ++ static const uptr kTraceMemEnd = 0x7c00000000000ull; ++ static const uptr kVdsoBeg = 0x3c00000000000000ull; ++ static const uptr kMidAppMemBeg = 0; ++ static const uptr kMidAppMemEnd = 0; ++}; ++ + /* Go on linux, darwin and freebsd on x86_64 + 0000 0000 1000 - 0000 1000 0000: executable + 0000 1000 0000 - 00c0 0000 0000: - +@@ -674,6 +712,8 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { + return Func::template Apply(arg); + # elif defined(__s390x__) + return Func::template Apply(arg); ++# elif defined(__sw_64__) ++ return Func::template Apply(arg); + # else + # error "unsupported platform" + # endif +@@ -693,6 +733,7 @@ void ForEachMapping() { + Func::template Apply(); + Func::template Apply(); + Func::template Apply(); ++ Func::template Apply(); + Func::template Apply(); + Func::template Apply(); + Func::template Apply(); +diff --git a/libsanitizer/tsan/tsan_platform_linux.cpp b/libsanitizer/tsan/tsan_platform_linux.cpp +index 73ec14892..83dfa2391 100644 +--- a/libsanitizer/tsan/tsan_platform_linux.cpp ++++ b/libsanitizer/tsan/tsan_platform_linux.cpp +@@ -400,6 +400,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { + // tcbhead_t.stack_guard + uptr xor_key = ((uptr *)__builtin_thread_pointer())[5]; + return mangled_sp ^ xor_key; ++#elif defined(__sw_64__) ++ return mangled_sp; + #else + #error "Unknown platform" + #endif +@@ -422,6 +424,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { + # define LONG_JMP_SP_ENV_SLOT 1 + # elif defined(__s390x__) + # define LONG_JMP_SP_ENV_SLOT 9 ++# elif defined(__sw_64__) ++# define LONG_JMP_SP_ENV_SLOT 8 + # else + # define LONG_JMP_SP_ENV_SLOT 6 + # endif +diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h +index eab837042..d3ceae483 100644 +--- a/libsanitizer/tsan/tsan_rtl.h ++++ b/libsanitizer/tsan/tsan_rtl.h +@@ -55,7 +55,7 @@ namespace __tsan { + + #if !SANITIZER_GO + struct MapUnmapCallback; +-#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) ++#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) || defined(__sw_64__) + + struct AP32 { + static const uptr kSpaceBeg = 0; +diff --git a/libsanitizer/tsan/tsan_rtl_sw64.S b/libsanitizer/tsan/tsan_rtl_sw64.S +new file mode 100644 +index 000000000..f74bfef8d +--- /dev/null ++++ b/libsanitizer/tsan/tsan_rtl_sw64.S +@@ -0,0 +1,236 @@ ++// The content of this file is sw64-only: ++#if defined(__sw_64__) ++ ++#include "sanitizer_common/sanitizer_asm.h" ++ ++.section .text ++.set noreorder ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception11real_setjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(setjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp)) ++ASM_SYMBOL_INTERCEPTOR(setjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ CFI_OFFSET (0, -16) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ CFI_RESTORE (0) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception11real_setjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp)) ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception12real__setjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(_setjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) ++ASM_SYMBOL_INTERCEPTOR(_setjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ CFI_OFFSET (0, -16) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ CFI_RESTORE (0) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception12real__setjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp)) ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception14real_sigsetjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) ++ASM_SYMBOL_INTERCEPTOR(sigsetjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ stl $r17, 24($sp) ++ CFI_OFFSET (16, -16) ++ CFI_OFFSET (17, -8) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ ldl $r17, 24($sp) ++ CFI_RESTORE (0) ++ CFI_RESTORE (1) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception14real_sigsetjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception16real___sigsetjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) ++ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ stl $r17, 24($sp) ++ CFI_OFFSET (16, -16) ++ CFI_OFFSET (17, -8) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ ldl $r17, 24($sp) ++ CFI_RESTORE (0) ++ CFI_RESTORE (1) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception16real___sigsetjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) ++ ++#endif +-- +2.25.1 + diff --git a/0016-libsanitizer-fix-isoc23-function-interception.patch b/0016-libsanitizer-fix-isoc23-function-interception.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d4c70bef977b09e5646d37bc0e25d7b8f09c1ed --- /dev/null +++ b/0016-libsanitizer-fix-isoc23-function-interception.patch @@ -0,0 +1,104 @@ +From add6d92567cfdc16e0acfaf73fb4b8cbc213661f Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Mon, 25 Nov 2024 17:15:16 +0800 +Subject: [PATCH 16/16] libsanitizer: fix isoc23 function interception for + glibc-2.38 + +--- + libsanitizer/asan/asan_interceptors.cpp | 55 +++++++++++++++---------- + 1 file changed, 33 insertions(+), 22 deletions(-) + +diff --git a/libsanitizer/asan/asan_interceptors.cpp b/libsanitizer/asan/asan_interceptors.cpp +index b28909152..ae1c9bfcb 100644 +--- a/libsanitizer/asan/asan_interceptors.cpp ++++ b/libsanitizer/asan/asan_interceptors.cpp +@@ -41,6 +41,8 @@ + # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" + # elif defined(__mips__) && SANITIZER_LINUX + # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2" ++# elif defined(__sw_64__) ++# define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" + # endif + + namespace __asan { +@@ -472,19 +474,32 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { + return REAL(strncpy)(to, from, size); + } + +-INTERCEPTOR(long, strtol, const char *nptr, char **endptr, int base) { +- void *ctx; +- ASAN_INTERCEPTOR_ENTER(ctx, strtol); +- ENSURE_ASAN_INITED(); +- if (!flags()->replace_str) { +- return REAL(strtol)(nptr, endptr, base); +- } ++template ++static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr, ++ char **endptr, int base) ++ -> decltype(real(nullptr, nullptr, 0)) { ++ if (!flags()->replace_str) ++ return real(nptr, endptr, base); + char *real_endptr; +- long result = REAL(strtol)(nptr, &real_endptr, base); ++ auto res = real(nptr, &real_endptr, base); + StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); +- return result; ++ return res; + } + ++# define INTERCEPTOR_STRTO_BASE(ret_type, func) \ ++ INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base) { \ ++ void *ctx; \ ++ ASAN_INTERCEPTOR_ENTER(ctx, func); \ ++ ENSURE_ASAN_INITED(); \ ++ return StrtolImpl(ctx, REAL(func), nptr, endptr, base); \ ++ } ++ ++INTERCEPTOR_STRTO_BASE(long, strtol) ++ ++#if SANITIZER_GLIBC ++INTERCEPTOR_STRTO_BASE(long, __isoc23_strtol) ++#endif ++ + INTERCEPTOR(int, atoi, const char *nptr) { + void *ctx; + ASAN_INTERCEPTOR_ENTER(ctx, atoi); +@@ -524,18 +539,11 @@ INTERCEPTOR(long, atol, const char *nptr) { + } + + #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL +-INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr, int base) { +- void *ctx; +- ASAN_INTERCEPTOR_ENTER(ctx, strtoll); +- ENSURE_ASAN_INITED(); +- if (!flags()->replace_str) { +- return REAL(strtoll)(nptr, endptr, base); +- } +- char *real_endptr; +- long long result = REAL(strtoll)(nptr, &real_endptr, base); +- StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); +- return result; +-} ++INTERCEPTOR_STRTO_BASE(long long, strtoll) ++ ++#if SANITIZER_GLIBC ++INTERCEPTOR_STRTO_BASE(long long, __isoc23_strtoll) ++#endif + + INTERCEPTOR(long long, atoll, const char *nptr) { + void *ctx; +@@ -639,7 +647,10 @@ void InitializeAsanInterceptors() { + ASAN_INTERCEPT_FUNC(atoll); + ASAN_INTERCEPT_FUNC(strtoll); + #endif +- ++#if SANITIZER_GLIBC ++ ASAN_INTERCEPT_FUNC(__isoc23_strtol); ++ ASAN_INTERCEPT_FUNC(__isoc23_strtoll); ++#endif + // Intecept jump-related functions. + ASAN_INTERCEPT_FUNC(longjmp); + +-- +2.25.1 + diff --git a/0017-Sw64-Port-Fix-target-explicit_mask.patch b/0017-Sw64-Port-Fix-target-explicit_mask.patch new file mode 100644 index 0000000000000000000000000000000000000000..44cf058045d7da5d8bb9617e2200ea9e90b9988a --- /dev/null +++ b/0017-Sw64-Port-Fix-target-explicit_mask.patch @@ -0,0 +1,14 @@ +diff --git a/gcc/config/sw_64/sw_64.opt b/gcc/config/sw_64/sw_64.opt +index c818dff40..22d0cdd5d 100644 +--- a/gcc/config/sw_64/sw_64.opt ++++ b/gcc/config/sw_64/sw_64.opt +@@ -21,6 +21,9 @@ msw-use-32align + C C++ Fortran LTO Driver Target Mask(SW_32ALIGN) Save + Use or not use 32align. + ++TargetVariable ++uint64_t sw_64_dummy_target = 0 ++ + fsw-sf-cmpsel + Target Var(flag_sw_sf_cmpsel) Init(0) + use or not use SF cmp/br/selcet instructions. diff --git a/0097-Improve-non-loop-disambiguation.patch b/0097-Improve-non-loop-disambiguation.patch new file mode 100644 index 0000000000000000000000000000000000000000..ae609d29474c7a05896508e06227959e405b2ad5 --- /dev/null +++ b/0097-Improve-non-loop-disambiguation.patch @@ -0,0 +1,101 @@ +From 6de2e0d400cbe46da482a672810c37b1832c408c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Thu, 25 Jul 2024 19:45:43 +0800 +Subject: [PATCH] Improve non-loop disambiguation + +This optimization is brought from https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=038b077689bb5310386b04d40a2cea234f01e6aa. + +When dr_may_alias_p is called without a loop context, it tries +to use the tree-affine interface to calculate the difference +between the two addresses and use that difference to check whether +the gap between the accesses is known at compile time. However, as the +example in the PR shows, this doesn't expand SSA_NAMEs and so can easily +be defeated by things like reassociation. + +One fix would have been to use aff_combination_expand to expand the +SSA_NAMEs, but we'd then need some way of maintaining the associated +cache. This patch instead reuses the innermost_loop_behavior fields +(which exist even when no loop context is provided). + +It might still be useful to do the aff_combination_expand thing too, +if an example turns out to need it. +--- + gcc/common.opt | 4 ++++ + gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c | 16 +++++++++++++++ + gcc/tree-data-ref.cc | 22 +++++++++++++++++++++ + 3 files changed, 42 insertions(+) + create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c + +diff --git a/gcc/common.opt b/gcc/common.opt +index b18f0b944..75bf9c9c1 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -3217,6 +3217,10 @@ ftree-loop-vectorize + Common Var(flag_tree_loop_vectorize) Optimization EnabledBy(ftree-vectorize) + Enable loop vectorization on trees. + ++falias-analysis-expand-ssa ++Common Var(flag_alias_analysis_expand_ssa) Init(0) ++Enable expanded SSA name analysis during alias analysis. ++ + ftree-slp-vectorize + Common Var(flag_tree_slp_vectorize) Optimization EnabledBy(ftree-vectorize) + Enable basic block vectorization (SLP) on trees. +diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c +new file mode 100644 +index 000000000..5ff8a8a62 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c +@@ -0,0 +1,16 @@ ++/* { dg-do compile } */ ++/* { dg-additional-options "-falias-analysis-expand-ssa" } */ ++ ++void f(double *p, long i) ++{ ++ p[i+0] += 1; ++ p[i+1] += 1; ++} ++void g(double *p, long i) ++{ ++ double *q = p + i; ++ q[0] += 1; ++ q[1] += 1; ++} ++ ++/* { dg-final { scan-tree-dump-not "can't determine dependence" slp2 } } */ +diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc +index e6ae9e847..a05073c51 100644 +--- a/gcc/tree-data-ref.cc ++++ b/gcc/tree-data-ref.cc +@@ -2993,6 +2993,28 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, + disambiguation. */ + if (!loop_nest) + { ++ if (flag_alias_analysis_expand_ssa) ++ { ++ tree tree_size_a = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (a))); ++ tree tree_size_b = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (b))); ++ ++ if (DR_BASE_ADDRESS (a) ++ && DR_BASE_ADDRESS (b) ++ && operand_equal_p (DR_BASE_ADDRESS (a), DR_BASE_ADDRESS (b)) ++ && operand_equal_p (DR_OFFSET (a), DR_OFFSET (b)) ++ && poly_int_tree_p (tree_size_a) ++ && poly_int_tree_p (tree_size_b) ++ && !ranges_maybe_overlap_p (wi::to_widest (DR_INIT (a)), ++ wi::to_widest (tree_size_a), ++ wi::to_widest (DR_INIT (b)), ++ wi::to_widest (tree_size_b))) ++ { ++ gcc_assert (integer_zerop (DR_STEP (a)) ++ && integer_zerop (DR_STEP (b))); ++ return false; ++ } ++ } ++ + aff_tree off1, off2; + poly_widest_int size1, size2; + get_inner_reference_aff (DR_REF (a), &off1, &size1); +-- +2.33.0 + diff --git a/0098-CHREC-multiplication-and-undefined-overflow.patch b/0098-CHREC-multiplication-and-undefined-overflow.patch new file mode 100644 index 0000000000000000000000000000000000000000..9f9a6b7410fd4a910d9eb899401a81f62500a797 --- /dev/null +++ b/0098-CHREC-multiplication-and-undefined-overflow.patch @@ -0,0 +1,265 @@ +From c4e4fef145c1e402f0558cc35f6c1ed0a08beffb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Thu, 25 Jul 2024 20:16:52 +0800 +Subject: [PATCH] CHREC multiplication and undefined overflow + +This optimization is brought from https://gcc.gnu.org/pipermail/gcc-patches/2024-February/646531.html + +When folding a multiply CHRECs are handled like {a, +, b} * c +is {a*c, +, b*c} but that isn't generally correct when overflow +invokes undefined behavior. The following uses unsigned arithmetic +unless either a is zero or a and b have the same sign. + +I've used simple early outs for INTEGER_CSTs and otherwise use +a range-query since we lack a tree_expr_nonpositive_p and +get_range_pos_neg isn't a good fit. +--- + gcc/common.opt | 4 ++ + gcc/testsuite/gcc.dg/pr68317.c | 6 +- + gcc/testsuite/gcc.dg/torture/pr114074.c | 31 ++++++++++ + gcc/tree-chrec.cc | 81 +++++++++++++++++++++---- + gcc/tree-chrec.h | 2 +- + gcc/value-range.cc | 12 ++++ + gcc/value-range.h | 2 + + 7 files changed, 123 insertions(+), 15 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/torture/pr114074.c + +diff --git a/gcc/common.opt b/gcc/common.opt +index b18f0b944..d3af3ba39 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1771,6 +1771,10 @@ floop-interchange + Common Var(flag_loop_interchange) Optimization + Enable loop interchange on trees. + ++fchrec-mul-fold-strict-overflow ++Common Var(flag_chrec_mul_fold_strict_overflow) Init(0) ++Enable strict overflow handling during constant folding of multiply CHRECs. ++ + floop-block + Common Alias(floop-nest-optimize) + Enable loop nest transforms. Same as -floop-nest-optimize. +diff --git a/gcc/testsuite/gcc.dg/pr68317.c b/gcc/testsuite/gcc.dg/pr68317.c +index bd053a752..671a67d95 100644 +--- a/gcc/testsuite/gcc.dg/pr68317.c ++++ b/gcc/testsuite/gcc.dg/pr68317.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fdisable-tree-ethread" } */ ++/* { dg-options "-O2 -fdisable-tree-ethread -fchrec-mul-fold-strict-overflow" } */ + + /* Note: Threader will collapse loop. */ + +@@ -12,8 +12,8 @@ foo () + { + int32_t index = 0; + +- for (index; index <= 10; index--) // expected warning here ++ for (index; index <= 10; index--) /* { dg-warning "iteration \[0-9\]+ invokes undefined behavior" } */ + /* Result of the following multiply will overflow + when converted to signed int32_t. */ +- bar ((0xcafe + index) * 0xdead); /* { dg-warning "iteration \[0-9\]+ invokes undefined behavior" } */ ++ bar ((0xcafe + index) * 0xdead); + } +diff --git a/gcc/testsuite/gcc.dg/torture/pr114074.c b/gcc/testsuite/gcc.dg/torture/pr114074.c +new file mode 100644 +index 000000000..9a383d8fc +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/torture/pr114074.c +@@ -0,0 +1,31 @@ ++/* { dg-do run } */ ++<<<<<<< HEAD ++/* { dg-options "-fchrec-mul-fold-strict-overflow" } */ ++======= ++/* { dg-options "-fchrec-mul-fold-strict-overflow"" } */ ++>>>>>>> 47092575e7696f5a21cf75284fe3d4feb0c813ab ++int a, b, d; ++ ++__attribute__((noipa)) void ++foo (void) ++{ ++ ++d; ++} ++ ++int ++main () ++{ ++ for (a = 0; a > -3; a -= 2) ++ { ++ int c = a; ++ b = __INT_MAX__ - 3000; ++ a = ~c * b; ++ foo (); ++ if (!a) ++ break; ++ a = c; ++ } ++ if (d != 2) ++ __builtin_abort (); ++ return 0; ++} +diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc +index c44cea754..3323901bc 100644 +--- a/gcc/tree-chrec.cc ++++ b/gcc/tree-chrec.cc +@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see + #include "gimple.h" + #include "tree-ssa-loop.h" + #include "dumpfile.h" ++#include "value-range.h" ++#include "value-query.h" + #include "tree-scalar-evolution.h" + + /* Extended folder for chrecs. */ +@@ -404,6 +406,13 @@ chrec_fold_multiply (tree type, + || automatically_generated_chrec_p (op1)) + return chrec_fold_automatically_generated_operands (op0, op1); + ++ if (flag_chrec_mul_fold_strict_overflow) ++ { ++ if (TREE_CODE (op0) != POLYNOMIAL_CHREC ++ && TREE_CODE (op1) == POLYNOMIAL_CHREC) ++ std::swap (op0, op1); ++ } ++ + switch (TREE_CODE (op0)) + { + case POLYNOMIAL_CHREC: +@@ -428,10 +437,53 @@ chrec_fold_multiply (tree type, + if (integer_zerop (op1)) + return build_int_cst (type, 0); + +- return build_polynomial_chrec +- (CHREC_VARIABLE (op0), +- chrec_fold_multiply (type, CHREC_LEFT (op0), op1), +- chrec_fold_multiply (type, CHREC_RIGHT (op0), op1)); ++ if (flag_chrec_mul_fold_strict_overflow) ++ { ++ /* When overflow is undefined and CHREC_LEFT/RIGHT do not have the ++ same sign or CHREC_LEFT is zero then folding the multiply into ++ the addition does not have the same behavior on overflow. Use ++ unsigned arithmetic in that case. */ ++ value_range rl, rr; ++ if (!ANY_INTEGRAL_TYPE_P (type) ++ || TYPE_OVERFLOW_WRAPS (type) ++ || integer_zerop (CHREC_LEFT (op0)) ++ || (TREE_CODE (CHREC_LEFT (op0)) == INTEGER_CST ++ && TREE_CODE (CHREC_RIGHT (op0)) == INTEGER_CST ++ && (tree_int_cst_sgn (CHREC_LEFT (op0)) ++ == tree_int_cst_sgn (CHREC_RIGHT (op0)))) ++ || (get_range_query (cfun)->range_of_expr (rl, CHREC_LEFT (op0)) ++ && !rl.undefined_p () ++ && (rl.nonpositive_p () || rl.nonnegative_p ()) ++ && get_range_query (cfun)->range_of_expr (rr, ++ CHREC_RIGHT (op0)) ++ && !rr.undefined_p () ++ && ((rl.nonpositive_p () && rr.nonpositive_p ()) ++ || (rl.nonnegative_p () && rr.nonnegative_p ())))) ++ { ++ tree left = chrec_fold_multiply (type, CHREC_LEFT (op0), op1); ++ tree right = chrec_fold_multiply (type, CHREC_RIGHT (op0), op1); ++ return build_polynomial_chrec (CHREC_VARIABLE (op0), left, right); ++ } ++ else ++ { ++ tree utype = unsigned_type_for (type); ++ tree uop1 = chrec_convert_rhs (utype, op1); ++ tree uleft0 = chrec_convert_rhs (utype, CHREC_LEFT (op0)); ++ tree uright0 = chrec_convert_rhs (utype, CHREC_RIGHT (op0)); ++ tree left = chrec_fold_multiply (utype, uleft0, uop1); ++ tree right = chrec_fold_multiply (utype, uright0, uop1); ++ tree tem = build_polynomial_chrec (CHREC_VARIABLE (op0), ++ left, right); ++ return chrec_convert_rhs (type, tem); ++ } ++ } ++ else ++ { ++ return build_polynomial_chrec ++ (CHREC_VARIABLE (op0), ++ chrec_fold_multiply (type, CHREC_LEFT (op0), op1), ++ chrec_fold_multiply (type, CHREC_RIGHT (op0), op1)); ++ } + } + + CASE_CONVERT: +@@ -449,13 +501,20 @@ chrec_fold_multiply (tree type, + switch (TREE_CODE (op1)) + { + case POLYNOMIAL_CHREC: +- gcc_checking_assert +- (!chrec_contains_symbols_defined_in_loop (op1, +- CHREC_VARIABLE (op1))); +- return build_polynomial_chrec +- (CHREC_VARIABLE (op1), +- chrec_fold_multiply (type, CHREC_LEFT (op1), op0), +- chrec_fold_multiply (type, CHREC_RIGHT (op1), op0)); ++ if (flag_chrec_mul_fold_strict_overflow) ++ { ++ gcc_unreachable (); ++ } ++ else ++ { ++ gcc_checking_assert ++ (!chrec_contains_symbols_defined_in_loop (op1, ++ CHREC_VARIABLE (op1))); ++ return build_polynomial_chrec ++ (CHREC_VARIABLE (op1), ++ chrec_fold_multiply (type, CHREC_LEFT (op1), op0), ++ chrec_fold_multiply (type, CHREC_RIGHT (op1), op0)); ++ } + + CASE_CONVERT: + if (tree_contains_chrecs (op1, NULL)) +diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h +index fcf41710d..cdc97d5d9 100644 +--- a/gcc/tree-chrec.h ++++ b/gcc/tree-chrec.h +@@ -63,7 +63,7 @@ extern tree chrec_fold_plus (tree, tree, tree); + extern tree chrec_fold_minus (tree, tree, tree); + extern tree chrec_fold_multiply (tree, tree, tree); + extern tree chrec_convert (tree, tree, gimple *, bool = true, tree = NULL); +-extern tree chrec_convert_rhs (tree, tree, gimple *); ++extern tree chrec_convert_rhs (tree, tree, gimple * = NULL); + extern tree chrec_convert_aggressive (tree, tree, bool *); + + /* Operations. */ +diff --git a/gcc/value-range.cc b/gcc/value-range.cc +index 000bbcf89..a1dc10a24 100644 +--- a/gcc/value-range.cc ++++ b/gcc/value-range.cc +@@ -656,6 +656,18 @@ irange::contains_p (tree cst) const + + return false; + } ++bool ++irange::nonnegative_p () const ++{ ++ return wi::ge_p (lower_bound (), 0, TYPE_SIGN (type ())); ++} ++ ++bool ++irange::nonpositive_p () const ++{ ++ return wi::le_p (upper_bound (), 0, TYPE_SIGN (type ())); ++} ++ + + + /* Normalize addresses into constants. */ +diff --git a/gcc/value-range.h b/gcc/value-range.h +index d4cba22d5..2dc0907de 100644 +--- a/gcc/value-range.h ++++ b/gcc/value-range.h +@@ -69,6 +69,8 @@ public: + bool varying_p () const; + bool singleton_p (tree *result = NULL) const; + bool contains_p (tree) const; ++ bool nonnegative_p () const; ++ bool nonpositive_p () const; + + // In-place operators. + void union_ (const irange &); +-- +2.33.0 + diff --git a/0099-Enable-Transposed-SLP.patch b/0099-Enable-Transposed-SLP.patch new file mode 100644 index 0000000000000000000000000000000000000000..b4e8b24b669790890da83fa4966a18efb18f90ae --- /dev/null +++ b/0099-Enable-Transposed-SLP.patch @@ -0,0 +1,5624 @@ +From 0dd3b8532f35486bd5db2c71342c8dfed4c0893a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Thu, 25 Jul 2024 17:25:23 +0800 +Subject: [PATCH] Enable Transposed SLP. + +--- + gcc/common.opt | 4 + + gcc/testsuite/gcc.dg/vect/transpose-1.c | 53 + + gcc/testsuite/gcc.dg/vect/transpose-2.c | 50 + + gcc/testsuite/gcc.dg/vect/transpose-3.c | 54 + + gcc/testsuite/gcc.dg/vect/transpose-4.c | 53 + + gcc/testsuite/gcc.dg/vect/transpose-5.c | 74 ++ + gcc/testsuite/gcc.dg/vect/transpose-6.c | 67 + + gcc/testsuite/gcc.dg/vect/transpose-7.c | 53 + + gcc/testsuite/gcc.dg/vect/transpose-8.c | 53 + + gcc/testsuite/gcc.dg/vect/vect.exp | 7 + + gcc/tree-loop-distribution.cc | 1464 ++++++++++++++++++++- + gcc/tree-vect-data-refs.cc | 237 ++++ + gcc/tree-vect-loop.cc | 42 +- + gcc/tree-vect-patterns.cc | 4 +- + gcc/tree-vect-slp.cc | 1553 ++++++++++++++++++++--- + gcc/tree-vect-stmts.cc | 973 +++++++++++++- + gcc/tree-vectorizer.h | 96 +- + 17 files changed, 4648 insertions(+), 189 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-1.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-2.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-3.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-4.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-5.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-6.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-7.c + create mode 100644 gcc/testsuite/gcc.dg/vect/transpose-8.c + +diff --git a/gcc/common.opt b/gcc/common.opt +index b18f0b944..5958c4e0b 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -3221,6 +3221,10 @@ ftree-slp-vectorize + Common Var(flag_tree_slp_vectorize) Optimization EnabledBy(ftree-vectorize) + Enable basic block vectorization (SLP) on trees. + ++ftree-slp-transpose-vectorize ++Common Var(flag_tree_slp_transpose_vectorize) Optimization Init(0) ++Enable basic block vectorization (SLP) for transposed stores and loads on trees. ++ + fvect-cost-model= + Common Joined RejectNegative Enum(vect_cost_model) Var(flag_vect_cost_model) Init(VECT_COST_MODEL_DEFAULT) Optimization + -fvect-cost-model=[unlimited|dynamic|cheap|very-cheap] Specifies the cost model for vectorization. +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-1.c b/gcc/testsuite/gcc.dg/vect/transpose-1.c +new file mode 100644 +index 000000000..8237a8b9e +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-1.c +@@ -0,0 +1,53 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 4 ++#define M 256 ++ ++int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) ++{ ++ int i = 0; ++ int sum = 0; ++ unsigned c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; ++ for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ c2[i] = pix1[2] - pix2[2]; ++ c3[i] = pix1[3] - pix2[3]; ++ c4[i] = pix1[4] - pix2[4]; ++ c5[i] = pix1[5] - pix2[5]; ++ c6[i] = pix1[6] - pix2[6]; ++ c7[i] = pix1[7] - pix2[7]; ++ } ++ for (int i = 0; i < N; i++) ++ { ++ sum += c0[i] + c1[i] + c2[i] + c3[i] + c4[i] + c5[i] + c6[i] + c7[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned char input1[M]; ++ unsigned char input2[M]; ++ int i1 = 16; ++ int i2 = 8; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 2; ++ input2[i] = i; ++ } ++ int sum = foo (input1, i1, input2, i2); ++ if (sum != 1264) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-2.c b/gcc/testsuite/gcc.dg/vect/transpose-2.c +new file mode 100644 +index 000000000..fdf4dbd96 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-2.c +@@ -0,0 +1,50 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-additional-options "-fno-tree-loop-vectorize -fno-tree-dse" } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 8 ++#define M 256 ++ ++int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) ++{ ++ int i = 0; ++ int sum = 0; ++ unsigned short c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; ++ for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ c2[i] = pix1[2] - pix2[2]; ++ c3[i] = pix1[3] - pix2[3]; ++ } ++ for (int i = 0; i < N; i++) ++ { ++ sum += c0[i] + c1[i] + c2[i] + c3[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned char input1[M]; ++ unsigned char input2[M]; ++ int i1 = 5; ++ int i2 = 4; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 4; ++ input2[i] = i * 2; ++ } ++ int sum = foo (input1, i1, input2, i2); ++ if (sum != 1440) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-3.c b/gcc/testsuite/gcc.dg/vect/transpose-3.c +new file mode 100644 +index 000000000..e492e3717 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-3.c +@@ -0,0 +1,54 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-additional-options "-fno-tree-loop-vectorize -fno-tree-dse -fno-tree-fre" } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 4 ++#define M 256 ++ ++int foo (unsigned short *pix1, int i_pix1, unsigned short *pix2, int i_pix2) ++{ ++ int i = 0; ++ int sum = 0; ++ unsigned c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; ++ for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ c2[i] = pix1[2] - pix2[2]; ++ c3[i] = pix1[3] - pix2[3]; ++ c4[i] = pix1[4] - pix2[4]; ++ c5[i] = pix1[5] - pix2[5]; ++ c6[i] = pix1[6] - pix2[6]; ++ c7[i] = pix1[7] - pix2[7]; ++ } ++ for (int i = 0; i < N; i++) ++ { ++ sum += c0[i] + c1[i] + c2[i] + c3[i] + c4[i] + c5[i] + c6[i] + c7[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned short input1[M]; ++ unsigned short input2[M]; ++ int i1 = 8; ++ int i2 = 4; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 4; ++ input2[i] = i; ++ } ++ int sum = foo (input1, i1, input2, i2); ++ if (sum != 1680) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-4.c b/gcc/testsuite/gcc.dg/vect/transpose-4.c +new file mode 100644 +index 000000000..0b4adea9b +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-4.c +@@ -0,0 +1,53 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 4 ++#define M 256 ++ ++int foo (unsigned *pix1, int i_pix1, unsigned *pix2, int i_pix2) ++{ ++ int i = 0; ++ int sum = 0; ++ unsigned c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; ++ for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ c2[i] = pix1[2] - pix2[2]; ++ c3[i] = pix1[3] - pix2[3]; ++ c4[i] = pix1[4] - pix2[4]; ++ c5[i] = pix1[5] - pix2[5]; ++ c6[i] = pix1[6] - pix2[6]; ++ c7[i] = pix1[7] - pix2[7]; ++ } ++ for (int i = 0; i < N; i++) ++ { ++ sum += c0[i] + c1[i] + c2[i] + c3[i] + c4[i] + c5[i] + c6[i] + c7[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned input1[M]; ++ unsigned input2[M]; ++ int i1 = 12; ++ int i2 = 6; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 7; ++ input2[i] = i * 3; ++ } ++ int sum = foo (input1, i1, input2, i2); ++ if (sum != 3616) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-5.c b/gcc/testsuite/gcc.dg/vect/transpose-5.c +new file mode 100644 +index 000000000..040dedf1b +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-5.c +@@ -0,0 +1,74 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-additional-options "-fno-tree-dse -fno-tree-fre" } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 4 ++#define M 256 ++#define eps 1e-8 ++ ++double foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) ++{ ++ unsigned a0[N]; ++ unsigned a1[N]; ++ unsigned a2[N]; ++ unsigned a3[N]; ++ ++ int b0[N]; ++ int b1[N]; ++ int b2[N]; ++ int b3[N]; ++ ++ for (int i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ a0[i] = (pix1[0] - pix2[0]) + ((pix1[4] + pix2[4]) << 16); ++ a1[i] = (pix1[1] - pix2[1]) + ((pix1[5] + pix2[5]) << 16); ++ a2[i] = (pix1[2] - pix2[2]) + ((pix1[6] + pix2[6]) << 16); ++ a3[i] = (pix1[3] - pix2[3]) + ((pix1[7] + pix2[7]) << 16); ++ } ++ ++ for (int i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ b0[i] = (pix1[0] - pix2[0]) + (pix1[4] + pix2[4]); ++ b1[i] = (pix1[1] - pix2[1]) + (pix1[5] + pix2[5]); ++ b2[i] = (pix1[2] - pix2[2]) + (pix1[6] + pix2[6]); ++ b3[i] = (pix1[3] - pix2[3]) + (pix1[7] + pix2[7]); ++ } ++ ++ double sum = 0; ++ for (int i = 0; i < N; i++) ++ { ++ sum += a0[i] + a1[i] + a2[i] + a3[i] + b0[i] + b1[i] + b2[i] + b3[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned char input1[M]; ++ unsigned char input2[M]; ++ int i1 = 8; ++ int i2 = 3; ++ unsigned char m = 2; ++ unsigned short n = 12; ++ float t = 3.0; ++ double k = 4.2; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 6; ++ input2[i] = i * 3; ++ } ++ double sum = foo (input1, i1, input2, i2); ++ if (fabs (sum - 78648144) > eps) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ ++/* { dg-final { scan-tree-dump-times "vectorizable_store for slp transpose" 2 "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-6.c b/gcc/testsuite/gcc.dg/vect/transpose-6.c +new file mode 100644 +index 000000000..3e134ac02 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-6.c +@@ -0,0 +1,67 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-require-effective-target vect_int } */ ++/* { dg-require-effective-target vect_float } */ ++#include ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 4 ++#define M 256 ++#define eps 1e-8 ++ ++float foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) ++{ ++ unsigned a0[N]; ++ unsigned a1[N]; ++ unsigned a2[N]; ++ unsigned a3[N]; ++ ++ float c0[N]; ++ float c1[N]; ++ float c2[N]; ++ float c3[N]; ++ ++ for (int i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ a0[i] = (pix1[0] - pix2[0]) + ((pix1[4] - pix2[4]) << 16); ++ a1[i] = (pix1[1] - pix2[1]) + ((pix1[5] - pix2[5]) << 16); ++ a2[i] = (pix1[2] - pix2[2]) + ((pix1[6] - pix2[6]) << 16); ++ a3[i] = (pix1[3] - pix2[3]) + ((pix1[7] - pix2[7]) << 16); ++ ++ c0[i] = (pix1[0] * pix2[0]) + (pix1[4] * pix2[4]); ++ c1[i] = (pix1[1] * pix2[1]) + (pix1[5] * pix2[5]); ++ c2[i] = (pix1[2] * pix2[2]) + (pix1[6] * pix2[6]); ++ c3[i] = (pix1[3] * pix2[3]) + (pix1[7] * pix2[7]); ++ } ++ ++ float sum = 0; ++ for (int i = 0; i < N; i++) ++ { ++ sum += a0[i] + a1[i] + a2[i] + a3[i] + c0[i] + c1[i] + c2[i] + c3[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned char input1[M]; ++ unsigned char input2[M]; ++ int i1 = 18; ++ int i2 = 6; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 4; ++ input2[i] = i * 2; ++ } ++ float sum = foo (input1, i1, input2, i2); ++ if (fabs (sum - 106041168) > eps) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ ++/* { dg-final { scan-tree-dump-times "vectorizable_store for slp transpose" 2 "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-7.c b/gcc/testsuite/gcc.dg/vect/transpose-7.c +new file mode 100644 +index 000000000..8ba1b1b6d +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-7.c +@@ -0,0 +1,53 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-additional-options "-fno-tree-loop-vectorize -fno-tree-dse" } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 16 ++#define M 256 ++ ++int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) ++{ ++ int i = 0; ++ int sum = 0; ++ unsigned char c0[N], c1[N]; ++ for (int i = 0; i < N/2; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ } ++ for (int i = N/2; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ } ++ for (int i = 0; i < N; i++) ++ { ++ sum += c0[i] + c1[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned char input1[M]; ++ unsigned char input2[M]; ++ int i1 = 6; ++ int i2 = 4; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 5; ++ input2[i] = i * 2; ++ } ++ int sum = foo (input1, i1, input2, i2); ++ if (sum != 3280) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/transpose-8.c b/gcc/testsuite/gcc.dg/vect/transpose-8.c +new file mode 100644 +index 000000000..a154f012a +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/transpose-8.c +@@ -0,0 +1,53 @@ ++/* { dg-do compile { target { aarch64*-*-linux* } } } */ ++/* { dg-additional-options "-fno-tree-loop-vectorize" } */ ++/* { dg-require-effective-target vect_int } */ ++#include ++#include ++#include "tree-vect.h" ++ ++#define N 32 ++#define M 256 ++ ++int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) ++{ ++ int i = 0; ++ int sum = 0; ++ unsigned char c0[N], c1[N]; ++ for (int i = 0; i < N/2; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ } ++ for (int i = N/2; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) ++ { ++ c0[i] = pix1[0] - pix2[0]; ++ c1[i] = pix1[1] - pix2[1]; ++ } ++ for (int i = 0; i < N; i++) ++ { ++ sum += c0[i] + c1[i]; ++ } ++ return sum; ++} ++ ++int main (int argc, const char* argv[]) ++{ ++ unsigned char input1[M]; ++ unsigned char input2[M]; ++ int i1 = 6; ++ int i2 = 4; ++ check_vect (); ++ for (int i = 0; i < M; i++) ++ { ++ input1[i] = i * 5; ++ input2[i] = i * 2; ++ } ++ int sum = foo (input1, i1, input2, i2); ++ if (sum != 7584) ++ { ++ abort (); ++ } ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp +index dcaef1e0a..ae5212411 100644 +--- a/gcc/testsuite/gcc.dg/vect/vect.exp ++++ b/gcc/testsuite/gcc.dg/vect/vect.exp +@@ -117,6 +117,13 @@ et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + ++# -ftree-slp-transpose-vectorize SLP tests ++set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS ++lappend VECT_SLP_CFLAGS "-ftree-slp-transpose-vectorize" ++et-dg-runtest dg-runtest [lsort \ ++ [glob -nocomplain $srcdir/$subdir/transpose-*.\[cS\]]] \ ++ "" "-ftree-slp-transpose-vectorize -fdump-tree-slp-details -O3" ++ + # -ffast-math tests + set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS + lappend DEFAULT_VECTCFLAGS "-ffast-math" +diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc +index 606eb05e6..8d118e987 100644 +--- a/gcc/tree-loop-distribution.cc ++++ b/gcc/tree-loop-distribution.cc +@@ -36,6 +36,47 @@ along with GCC; see the file COPYING3. If not see + | D(I) = A(I-1)*E + |ENDDO + ++ If an unvectorizable loop has grouped loads, and calculations from grouped ++ loads are isomorphic, build temp arrays using stmts where isomorphic ++ calculations end. Afer distribution, the partition built from temp ++ arrays can be vectorized in pass SLP after loop unrolling. For example, ++ ++ |DO I = 1, N ++ | A = FOO (ARG_1); ++ | B = FOO (ARG_2); ++ | C = BAR_0 (A); ++ | D = BAR_1 (B); ++ |ENDDO ++ ++ is transformed to ++ ++ |DO I = 1, N ++ | J = FOO (ARG_1); ++ | K = FOO (ARG_2); ++ | X[I] = J; ++ | Y[I] = K; ++ | A = X[I]; ++ | B = Y[I]; ++ | C = BAR_0 (A); ++ | D = BAR_1 (B); ++ |ENDDO ++ ++ and is then distributed to ++ ++ |DO I = 1, N ++ | J = FOO (ARG_1); ++ | K = FOO (ARG_2); ++ | X[I] = J; ++ | Y[I] = K; ++ |ENDDO ++ ++ |DO I = 1, N ++ | A = X[I]; ++ | B = Y[I]; ++ | C = BAR_0 (A); ++ | D = BAR_1 (B); ++ |ENDDO ++ + Loop distribution is the dual of loop fusion. It separates statements + of a loop (or loop nest) into multiple loops (or loop nests) with the + same loop header. The major goal is to separate statements which may +@@ -44,7 +85,9 @@ along with GCC; see the file COPYING3. If not see + + 1) Seed partitions with specific type statements. For now we support + two types seed statements: statement defining variable used outside +- of loop; statement storing to memory. ++ of loop; statement storing to memory. Moreover, for unvectorizable ++ loops, we try to find isomorphic stmts from grouped load and build ++ temp arrays as new seed statements. + 2) Build reduced dependence graph (RDG) for loop to be distributed. + The vertices (RDG:V) model all statements in the loop and the edges + (RDG:E) model flow and control dependencies between statements. +@@ -90,6 +133,8 @@ along with GCC; see the file COPYING3. If not see + data reuse. */ + + #include "config.h" ++#define INCLUDE_MAP ++#define INCLUDE_ALGORITHM + #include "system.h" + #include "coretypes.h" + #include "backend.h" +@@ -115,6 +160,7 @@ along with GCC; see the file COPYING3. If not see + #include "tree-vectorizer.h" + #include "tree-eh.h" + #include "gimple-fold.h" ++#include "optabs-tree.h" + #include "tree-affine.h" + #include "intl.h" + #include "rtl.h" +@@ -188,6 +234,52 @@ struct rdg_vertex + #define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I])) + #define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I])) + ++/* Results of isomorphic group analysis. */ ++#define UNINITIALIZED (0) ++#define ISOMORPHIC (1) ++#define HETEROGENEOUS (1 << 1) ++#define UNCERTAIN (1 << 2) ++ ++/* Information of a stmt while analyzing isomorphic use in group. */ ++ ++typedef struct _group_info ++{ ++ gimple *stmt; ++ ++ /* True if stmt can be a cut point. */ ++ bool cut_point; ++ ++ /* For use_stmt with two rhses, one of which is the lhs of stmt. ++ If the other is unknown to be isomorphic, mark it uncertain. */ ++ bool uncertain; ++ ++ /* Searching of isomorphic stmt reaches heterogeneous groups or reaches ++ MEM stmts. */ ++ bool done; ++ ++ _group_info () ++ { ++ stmt = NULL; ++ cut_point = false; ++ uncertain = false; ++ done = false; ++ } ++} *group_info; ++ ++/* PAIR of cut points and corresponding profit. */ ++typedef std::pair *, int> stmts_profit; ++ ++/* MAP of vector factor VF and corresponding stmts_profit PAIR. */ ++typedef std::map vf_stmts_profit_map; ++ ++/* PAIR of group_num and iteration_num. We consider rhses from the same ++ group and interation are isomorphic. */ ++typedef std::pair group_iteration; ++ ++/* An isomorphic stmt is detetmined by lhs of use_stmt, group_num and ++ the iteration_num when we insert this stmt to this map. */ ++typedef std::map isomer_stmt_lhs; ++ + /* Data dependence type. */ + + enum rdg_dep_type +@@ -600,13 +692,14 @@ class loop_distribution + /* Returns true when PARTITION1 and PARTITION2 access the same memory + object in RDG. */ + bool share_memory_accesses (struct graph *rdg, +- partition *partition1, partition *partition2); ++ partition *partition1, partition *partition2, ++ hash_set *excluded_arrays); + + /* For each seed statement in STARTING_STMTS, this function builds + partition for it by adding depended statements according to RDG. + All partitions are recorded in PARTITIONS. */ + void rdg_build_partitions (struct graph *rdg, +- vec starting_stmts, ++ vec *starting_stmts, + vec *partitions); + + /* Compute partition dependence created by the data references in DRS1 +@@ -643,15 +736,50 @@ class loop_distribution + + /* Fuse PARTITIONS of LOOP if necessary before finalizing distribution. + ALIAS_DDRS contains ddrs which need runtime alias check. */ +- void finalize_partitions (class loop *loop, vec +- *partitions, vec *alias_ddrs); ++ void finalize_partitions (class loop *loop, ++ vec *partitions, ++ vec *alias_ddrs, bitmap producers); ++ ++ /* Analyze loop form and if it's vectorizable to decide if we need to ++ insert temp arrays to distribute it. */ ++ bool may_insert_temp_arrays (loop_p loop, struct graph *&rdg, ++ control_dependences *cd); ++ ++ /* Reset gimple_uid of GIMPLE_DEBUG and GIMPLE_LABEL to -1. */ ++ void reset_gimple_uid (loop_p loop); ++ ++ bool check_loop_vectorizable (loop_p loop); ++ ++ inline void rebuild_rdg (loop_p loop, struct graph *&rdg, ++ control_dependences *cd); ++ ++ /* If loop is not distributed, remove inserted temp arrays. */ ++ void remove_insertion (loop_p loop, struct graph *flow_only_rdg, ++ bitmap producers, struct partition *partition); ++ ++ /* Insert temp arrays if isomorphic computation exists. Temp arrays will be ++ regarded as SEED_STMTS for building partitions in succeeding processes. */ ++ bool insert_temp_arrays (loop_p loop, vec seed_stmts, ++ hash_set *tmp_array_vars, bitmap producers); ++ ++ void build_producers (loop_p loop, bitmap producers, ++ vec &transformed); ++ ++ void do_insertion (loop_p loop, struct graph *flow_only_rdg, tree iv, ++ bitmap cut_points, hash_set *tmp_array_vars, ++ bitmap producers); ++ ++ /* Fuse PARTITIONS built from inserted temp arrays into one partition, ++ fuse the rest into another. */ ++ void merge_remaining_partitions (vec *partitions, ++ bitmap producers); + + /* Distributes the code from LOOP in such a way that producer statements + are placed before consumer statements. Tries to separate only the + statements from STMTS into separate loops. Returns the number of + distributed loops. Set NB_CALLS to number of generated builtin calls. + Set *DESTROY_P to whether LOOP needs to be destroyed. */ +- int distribute_loop (class loop *loop, const vec &stmts, ++ int distribute_loop (class loop *loop, vec &stmts, + control_dependences *cd, int *nb_calls, bool *destroy_p, + bool only_patterns_p); + +@@ -1893,7 +2021,8 @@ loop_distribution::classify_partition (loop_p loop, + + bool + loop_distribution::share_memory_accesses (struct graph *rdg, +- partition *partition1, partition *partition2) ++ partition *partition1, partition *partition2, ++ hash_set *excluded_arrays) + { + unsigned i, j; + bitmap_iterator bi, bj; +@@ -1927,7 +2056,10 @@ loop_distribution::share_memory_accesses (struct graph *rdg, + if (operand_equal_p (DR_BASE_ADDRESS (dr1), DR_BASE_ADDRESS (dr2), 0) + && operand_equal_p (DR_OFFSET (dr1), DR_OFFSET (dr2), 0) + && operand_equal_p (DR_INIT (dr1), DR_INIT (dr2), 0) +- && operand_equal_p (DR_STEP (dr1), DR_STEP (dr2), 0)) ++ && operand_equal_p (DR_STEP (dr1), DR_STEP (dr2), 0) ++ /* An exception, if PARTITION1 and PARTITION2 contain the ++ temp array we inserted, do not merge them. */ ++ && !excluded_arrays->contains (DR_REF (dr1))) + return true; + } + } +@@ -1941,14 +2073,14 @@ loop_distribution::share_memory_accesses (struct graph *rdg, + + void + loop_distribution::rdg_build_partitions (struct graph *rdg, +- vec starting_stmts, ++ vec *starting_stmts, + vec *partitions) + { + auto_bitmap processed; + int i; + gimple *stmt; + +- FOR_EACH_VEC_ELT (starting_stmts, i, stmt) ++ FOR_EACH_VEC_ELT (*starting_stmts, i, stmt) + { + int v = rdg_vertex_for_stmt (rdg, stmt); + +@@ -2912,13 +3044,47 @@ fuse_memset_builtins (vec *partitions) + } + } + ++void ++loop_distribution::merge_remaining_partitions ++ (vec *partitions, ++ bitmap producers) ++{ ++ struct partition *partition = NULL; ++ struct partition *p1 = NULL, *p2 = NULL; ++ for (unsigned i = 0; partitions->iterate (i, &partition); i++) ++ { ++ if (bitmap_intersect_p (producers, partition->stmts)) ++ { ++ if (p1 == NULL) ++ { ++ p1 = partition; ++ continue; ++ } ++ partition_merge_into (NULL, p1, partition, FUSE_FINALIZE); ++ } ++ else ++ { ++ if (p2 == NULL) ++ { ++ p2 = partition; ++ continue; ++ } ++ partition_merge_into (NULL, p2, partition, FUSE_FINALIZE); ++ } ++ partitions->unordered_remove (i); ++ partition_free (partition); ++ i--; ++ } ++} ++ + void + loop_distribution::finalize_partitions (class loop *loop, + vec *partitions, +- vec *alias_ddrs) ++ vec *alias_ddrs, ++ bitmap producers) + { + unsigned i; +- struct partition *partition, *a; ++ struct partition *partition; + + if (partitions->length () == 1 + || alias_ddrs->length () > 0) +@@ -2950,13 +3116,7 @@ loop_distribution::finalize_partitions (class loop *loop, + || (loop->inner == NULL + && i >= NUM_PARTITION_THRESHOLD && num_normal > num_builtin)) + { +- a = (*partitions)[0]; +- for (i = 1; partitions->iterate (i, &partition); ++i) +- { +- partition_merge_into (NULL, a, partition, FUSE_FINALIZE); +- partition_free (partition); +- } +- partitions->truncate (1); ++ merge_remaining_partitions (partitions, producers); + } + + /* Fuse memset builtins if possible. */ +@@ -2964,6 +3124,1216 @@ loop_distribution::finalize_partitions (class loop *loop, + fuse_memset_builtins (partitions); + } + ++/* Gimple uids of GIMPLE_DEBUG and GIMPLE_LABEL were changed during function ++ vect_analyze_loop, reset them to -1. */ ++ ++void ++loop_distribution::reset_gimple_uid (loop_p loop) ++{ ++ basic_block *bbs = get_loop_body_in_custom_order (loop, this, ++ bb_top_order_cmp_r); ++ for (int i = 0; i < int (loop->num_nodes); i++) ++ { ++ basic_block bb = bbs[i]; ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ++ gsi_next (&gsi)) ++ { ++ gimple *stmt = gsi_stmt (gsi); ++ if (is_gimple_debug (stmt) || gimple_code (stmt) == GIMPLE_LABEL) ++ gimple_set_uid (stmt, -1); ++ } ++ } ++ free (bbs); ++} ++ ++bool ++loop_distribution::check_loop_vectorizable (loop_p loop) ++{ ++ vec_info_shared shared; ++ vect_analyze_loop (loop, &shared, true); ++ loop_vec_info vinfo = loop_vec_info_for_loop (loop); ++ reset_gimple_uid (loop); ++ if (vinfo == NULL) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, ++ "Loop %d no temp array insertion: bad data access pattern," ++ " unable to generate loop_vinfo.\n", loop->num); ++ return false; ++ } ++ if (vinfo->vectorizable) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Loop %d no temp array insertion: original loop" ++ " can be vectorized without distribution.\n", ++ loop->num); ++ delete vinfo; ++ loop->aux = NULL; ++ return false; ++ } ++ if (vinfo->grouped_loads.length () == 0) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Loop %d no temp array insertion: original loop" ++ " has no grouped loads.\n" , loop->num); ++ delete vinfo; ++ loop->aux = NULL; ++ return false; ++ } ++ return true; ++} ++ ++inline void ++loop_distribution::rebuild_rdg (loop_p loop, struct graph *&rdg, ++ control_dependences *cd) ++{ ++ free_rdg (rdg); ++ rdg = build_rdg (loop, cd); ++ gcc_checking_assert (rdg != NULL); ++} ++ ++bool ++loop_distribution::may_insert_temp_arrays (loop_p loop, struct graph *&rdg, ++ control_dependences *cd) ++{ ++ if (!(flag_tree_slp_transpose_vectorize && flag_tree_loop_vectorize)) ++ return false; ++ ++ /* Only loops with two basic blocks HEADER and LATCH are supported. HEADER ++ is the main body of a LOOP and LATCH is the basic block that controls the ++ LOOP execution. Size of temp array is determined by loop execution time, ++ so it must be a const. */ ++ tree loop_extent = number_of_latch_executions (loop); ++ if (loop->inner != NULL || loop->num_nodes > 2 ++ || TREE_CODE (loop_extent) != INTEGER_CST) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Loop %d: no temp array insertion: bad loop" ++ " form.\n", loop->num); ++ return false; ++ } ++ ++ if (loop->dont_vectorize) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Loop %d: no temp array insertion: this loop" ++ " should never be vectorized.\n", ++ loop->num); ++ return false; ++ } ++ ++ /* Do not distribute a LOOP that is able to be vectorized without ++ distribution. */ ++ if (!check_loop_vectorizable (loop)) ++ { ++ rebuild_rdg (loop, rdg, cd); ++ return false; ++ } ++ ++ rebuild_rdg (loop, rdg, cd); ++ return true; ++} ++ ++/* Return max grouped loads' length if all groupes length satisfy len = 2 ^ n. ++ Otherwise, return 0. */ ++ ++static unsigned ++get_max_vf (loop_vec_info vinfo) ++{ ++ unsigned size = 0; ++ unsigned max = 0; ++ stmt_vec_info stmt_info; ++ unsigned i = 0; ++ FOR_EACH_VEC_ELT (vinfo->grouped_loads, i, stmt_info) ++ { ++ size = stmt_info->size; ++ if (!pow2p_hwi (size)) ++ return 0; ++ max = size > max ? size : max; ++ } ++ return max; ++} ++ ++/* Convert grouped_loads from linked list to vector with length vf. Init ++ group_info of each stmt in the same group and put then into a vector. And ++ these vectors consist WORKLISTS. We will re-analyze a group if it is ++ uncertain, so we regard WORKLISTS as a circular queue. */ ++ ++static unsigned ++build_queue (loop_vec_info vinfo, unsigned vf, ++ vec *> &worklists) ++{ ++ stmt_vec_info stmt_info; ++ unsigned i = 0; ++ group_info ginfo = NULL; ++ vec *worklist = NULL; ++ FOR_EACH_VEC_ELT (vinfo->grouped_loads, i, stmt_info) ++ { ++ unsigned group_size = stmt_info->size; ++ stmt_vec_info c_stmt_info = stmt_info; ++ bool succ = true; ++ while (group_size >= vf) ++ { ++ vec_alloc (worklist, vf); ++ for (unsigned j = 0; j < vf; ++j) ++ { ++ if (c_stmt_info == NULL) ++ { ++ succ = false; ++ break; ++ } ++ ginfo = new _group_info (); ++ ginfo->stmt = c_stmt_info->stmt; ++ worklist->safe_push (ginfo); ++ c_stmt_info = c_stmt_info->next_element; ++ } ++ if (!succ) ++ { ++ unsigned k = 0; ++ ginfo = NULL; ++ FOR_EACH_VEC_ELT (*worklist, k, ginfo) ++ delete ginfo; ++ vec_free (worklist); ++ break; ++ } ++ worklists.safe_push (worklist); ++ group_size -= vf; ++ } ++ } ++ return worklists.length (); ++} ++ ++static bool ++check_same_oprand_type (tree op1, tree op2) ++{ ++ tree type1 = TREE_TYPE (op1); ++ tree type2 = TREE_TYPE (op2); ++ if (TREE_CODE (type1) != INTEGER_TYPE && TREE_CODE (type1) != REAL_TYPE) ++ return false; ++ ++ return (TREE_CODE (type1) == TREE_CODE (type2) ++ && TYPE_UNSIGNED (type1) == TYPE_UNSIGNED (type2) ++ && TYPE_PRECISION (type1) == TYPE_PRECISION (type2)); ++} ++ ++static bool ++bit_field_p (gimple *stmt) ++{ ++ unsigned i = 0; ++ auto_vec datarefs_vec; ++ data_reference_p dr; ++ if (!find_data_references_in_stmt (NULL, stmt, &datarefs_vec)) ++ return true; ++ ++ FOR_EACH_VEC_ELT (datarefs_vec, i, dr) ++ { ++ if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF ++ && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1))) ++ return true; ++ } ++ return false; ++} ++ ++static inline bool ++shift_operation (enum tree_code op) ++{ ++ return op == LSHIFT_EXPR || op == RSHIFT_EXPR || op == LROTATE_EXPR ++ || op == RROTATE_EXPR; ++} ++ ++/* Return relationship between USE_STMT and the first use_stmt of the group. ++ RHS1 is the lhs of stmt recorded in group_info. If another rhs of use_stmt ++ is not a constant, return UNCERTAIN and re-check it later. */ ++ ++static unsigned ++check_isomorphic (gimple *use_stmt, gimple *first, ++ tree rhs1, vec &hetero_lhs) ++{ ++ /* Check same operation. */ ++ enum tree_code rhs_code_first = gimple_assign_rhs_code (first); ++ enum tree_code rhs_code_current = gimple_assign_rhs_code (use_stmt); ++ if (rhs_code_first != rhs_code_current) ++ return HETEROGENEOUS; ++ ++ /* For shift operations, oprands should be equal. */ ++ if (shift_operation (rhs_code_current)) ++ { ++ tree shift_op_first = gimple_assign_rhs2 (first); ++ tree shift_op_current = gimple_assign_rhs2 (use_stmt); ++ if (!operand_equal_p (shift_op_first, shift_op_current, 0) ++ || !TREE_CONSTANT (shift_op_first)) ++ return HETEROGENEOUS; ++ ++ return ISOMORPHIC; ++ } ++ /* Type convertion expr or assignment. */ ++ if (gimple_num_ops (first) == 2) ++ return (rhs_code_first == NOP_EXPR || rhs_code_first == CONVERT_EXPR ++ || rhs_code_first == SSA_NAME) ? ISOMORPHIC : HETEROGENEOUS; ++ ++ /* We find USE_STMT from lhs of a stmt, denote it as rhs1 of USE_STMT and ++ the other one as rhs2. Check if define-stmt of current rhs2 is isomorphic ++ with define-stmt of rhs2 in the first USE_STMT at this group. */ ++ tree rhs2_first = gimple_assign_rhs1 (use_stmt) == rhs1 ++ ? gimple_assign_rhs2 (first) : gimple_assign_rhs1 (first); ++ tree rhs2_curr = gimple_assign_rhs1 (use_stmt) == rhs1 ++ ? gimple_assign_rhs2 (use_stmt) : gimple_assign_rhs1 (use_stmt); ++ ++ if (check_same_oprand_type (rhs2_first, rhs2_curr)) ++ { ++ if (TREE_CONSTANT (rhs2_curr)) ++ return ISOMORPHIC; ++ else if (hetero_lhs.contains (rhs2_curr)) ++ return HETEROGENEOUS; ++ ++ /* Provisionally set the stmt as uncertain and analyze the whole group ++ in function CHECK_UNCERTAIN later if all use_stmts are uncertain. */ ++ return UNCERTAIN; ++ } ++ return HETEROGENEOUS; ++} ++ ++static bool ++unsupported_operations (gimple *stmt) ++{ ++ enum tree_code code = gimple_assign_rhs_code (stmt); ++ return code == COND_EXPR; ++} ++ ++/* Check if the single use_stmt of STMT is isomorphic with the first one's ++ use_stmt in current group. */ ++ ++static unsigned ++check_use_stmt (group_info elmt, gimple *&first, ++ vec &tmp_stmts, vec &hetero_lhs) ++{ ++ if (gimple_code (elmt->stmt) != GIMPLE_ASSIGN) ++ return HETEROGENEOUS; ++ use_operand_p dummy; ++ tree lhs = gimple_assign_lhs (elmt->stmt); ++ gimple *use_stmt = NULL; ++ single_imm_use (lhs, &dummy, &use_stmt); ++ /* STMTs with three rhs are not supported, e.g., GIMPLE_COND. */ ++ if (use_stmt == NULL || gimple_code (use_stmt) != GIMPLE_ASSIGN ++ || unsupported_operations (use_stmt) || bit_field_p (use_stmt)) ++ return HETEROGENEOUS; ++ tmp_stmts.safe_push (use_stmt); ++ if (first == NULL) ++ { ++ first = use_stmt; ++ return UNINITIALIZED; ++ } ++ /* Check if current use_stmt and the first menber's use_stmt in the group ++ are of the same type. */ ++ tree first_lhs = gimple_assign_lhs (first); ++ tree curr_lhs = gimple_assign_lhs (use_stmt); ++ if (!check_same_oprand_type (first_lhs, curr_lhs)) ++ return HETEROGENEOUS; ++ return check_isomorphic (use_stmt, first, lhs, hetero_lhs); ++} ++ ++/* Replace stmt field in group with stmts in TMP_STMTS, and insert their ++ lhs_info to ISOMER_LHS. */ ++ ++static void ++update_isomer_lhs (vec *group, unsigned group_num, ++ unsigned iteration, isomer_stmt_lhs &isomer_lhs, ++ vec &tmp_stmts, int &profit, ++ vec &merged_groups) ++{ ++ group_info elmt = NULL; ++ /* Do not insert temp array if isomorphic stmts from grouped load have ++ only casting operations. Once isomorphic calculation has 3 oprands, ++ such as plus operation, this group can be regarded as cut point. */ ++ bool operated = (gimple_num_ops (tmp_stmts[0]) == 3); ++ /* Do not insert temp arrays if search of iosomophic stmts reaches ++ MEM stmts. */ ++ bool has_vdef = gimple_vdef (tmp_stmts[0]) != NULL; ++ bool merge = false; ++ for (unsigned i = 0; i < group->length (); i++) ++ { ++ elmt = (*group)[i]; ++ elmt->stmt = has_vdef ? NULL : tmp_stmts[i]; ++ elmt->cut_point = has_vdef ? false : (elmt->cut_point || operated); ++ elmt->uncertain = false; ++ elmt->done = has_vdef; ++ tree lhs = gimple_assign_lhs (tmp_stmts[i]); ++ if (isomer_lhs.find (lhs) != isomer_lhs.end ()) ++ { ++ merge = true; ++ continue; ++ } ++ isomer_lhs[lhs] = std::make_pair (group_num, iteration); ++ } ++ if (merge) ++ { ++ merged_groups.safe_push (group_num); ++ profit = 0; ++ return; ++ } ++ enum vect_cost_for_stmt kind = scalar_stmt; ++ int scalar_cost = builtin_vectorization_cost (kind, NULL_TREE, 0); ++ profit = (tmp_stmts.length () - 1) * scalar_cost; ++} ++ ++/* Try to find rhs2 in ISOMER_LHS, if all rhs2 were found and their group_num ++ and iteration are same, GROUP is isomorphic. */ ++ ++static unsigned ++check_isomorphic_rhs (vec *group, vec &tmp_stmts, ++ isomer_stmt_lhs &isomer_lhs) ++{ ++ group_info elmt = NULL; ++ gimple *stmt = NULL; ++ unsigned j = 0; ++ unsigned group_num = -1u; ++ unsigned iteration = -1u; ++ tree rhs1 = NULL; ++ tree rhs2 = NULL; ++ unsigned status = UNINITIALIZED; ++ FOR_EACH_VEC_ELT (*group, j, elmt) ++ { ++ rhs1 = gimple_assign_lhs (elmt->stmt); ++ stmt = tmp_stmts[j]; ++ rhs2 = (rhs1 == gimple_assign_rhs1 (stmt)) ++ ? gimple_assign_rhs2 (stmt) : gimple_assign_rhs1 (stmt); ++ isomer_stmt_lhs::iterator iter = isomer_lhs.find (rhs2); ++ if (iter != isomer_lhs.end ()) ++ { ++ if (group_num == -1u) ++ { ++ group_num = iter->second.first; ++ iteration = iter->second.second; ++ status |= ISOMORPHIC; ++ continue; ++ } ++ if (iter->second.first == group_num ++ && iter->second.second == iteration) ++ { ++ status |= ISOMORPHIC; ++ continue; ++ } ++ return HETEROGENEOUS; ++ } ++ else ++ status |= UNCERTAIN; ++ } ++ return status; ++} ++ ++/* Update group_info for uncertain groups. */ ++ ++static void ++update_uncertain_stmts (vec *group, unsigned group_num, ++ unsigned iteration, vec &tmp_stmts) ++{ ++ unsigned j = 0; ++ group_info elmt = NULL; ++ FOR_EACH_VEC_ELT (*group, j, elmt) ++ { ++ elmt->uncertain = true; ++ elmt->done = false; ++ } ++} ++ ++/* Push stmts in TMP_STMTS into HETERO_LHS. */ ++ ++static void ++set_hetero (vec *group, vec &hetero_lhs, ++ vec &tmp_stmts) ++{ ++ group_info elmt = NULL; ++ unsigned i = 0; ++ for (i = 0; i < group->length (); i++) ++ { ++ elmt = (*group)[i]; ++ elmt->uncertain = false; ++ elmt->done = true; ++ } ++ gimple *stmt = NULL; ++ FOR_EACH_VEC_ELT (tmp_stmts, i, stmt) ++ if (stmt != NULL) ++ hetero_lhs.safe_push (gimple_assign_lhs (stmt)); ++} ++ ++/* Given an uncertain group, TMP_STMTS are use_stmts of stmts in GROUP. ++ Rhs1 is the lhs of stmt in GROUP, rhs2 is the other rhs of USE_STMT. ++ ++ Try to find rhs2 in ISOMER_LHS, if all found rhs2 have same group_num ++ and iteration, this uncertain group is isomorphic. ++ ++ If no rhs matched, this GROUP remains uncertain and update group_info. ++ ++ Otherwise, this GROUP is heterogeneous and return true to end analysis ++ for this group. */ ++ ++static bool ++check_uncertain (vec *group, unsigned group_num, ++ unsigned iteration, int &profit, ++ vec &tmp_stmts, isomer_stmt_lhs &isomer_lhs, ++ vec &hetero_lhs, vec &merged_groups) ++{ ++ unsigned status = check_isomorphic_rhs (group, tmp_stmts, isomer_lhs); ++ bool done = false; ++ switch (status) ++ { ++ case UNCERTAIN: ++ update_uncertain_stmts (group, group_num, iteration, tmp_stmts); ++ break; ++ case ISOMORPHIC: ++ update_isomer_lhs (group, group_num, iteration, isomer_lhs, ++ tmp_stmts, profit, merged_groups); ++ break; ++ default: ++ set_hetero (group, hetero_lhs, tmp_stmts); ++ done = true; ++ } ++ return done; ++} ++ ++/* Return false if analysis of this group is not finished, e.g., isomorphic or ++ uncertain. Calculate the profit if vectorized. */ ++ ++static bool ++check_group (vec *group, unsigned group_num, unsigned iteration, ++ int &profit, vec &merged_groups, ++ isomer_stmt_lhs &isomer_lhs, vec &hetero_lhs) ++{ ++ unsigned j = 0; ++ group_info elmt = NULL; ++ gimple *first = NULL; ++ unsigned res = 0; ++ /* Record single use stmts in TMP_STMTS and decide whether replace stmts in ++ ginfo in succeeding processes. */ ++ auto_vec tmp_stmts; ++ FOR_EACH_VEC_ELT (*group, j, elmt) ++ { ++ if (merged_groups.contains (group_num)) ++ return true; ++ res |= check_use_stmt (elmt, first, tmp_stmts, hetero_lhs); ++ } ++ ++ /* Update each group member according to RES. */ ++ switch (res) ++ { ++ case ISOMORPHIC: ++ update_isomer_lhs (group, group_num, iteration, isomer_lhs, ++ tmp_stmts, profit, merged_groups); ++ return false; ++ case UNCERTAIN: ++ return check_uncertain (group, group_num, iteration, profit, ++ tmp_stmts, isomer_lhs, hetero_lhs, ++ merged_groups); ++ default: ++ set_hetero (group, hetero_lhs, tmp_stmts); ++ return true; ++ } ++} ++ ++/* Return true if all analysises are done except uncertain groups. */ ++ ++static bool ++end_of_search (vec *> &circular_queue, ++ vec &merged_groups) ++{ ++ unsigned i = 0; ++ vec *group = NULL; ++ group_info elmt = NULL; ++ FOR_EACH_VEC_ELT (circular_queue, i, group) ++ { ++ if (merged_groups.contains (i)) ++ continue; ++ elmt = (*group)[0]; ++ /* If there is any isomorphic use_stmts, continue analysis of isomorphic ++ use_stmts. */ ++ if (!elmt->done && !elmt->uncertain) ++ return false; ++ } ++ return true; ++} ++ ++/* Push valid stmts to STMTS as cutpoints. */ ++ ++static bool ++check_any_cutpoints (vec *> &circular_queue, ++ vec *&stmts, vec &merged_groups) ++{ ++ unsigned front = 0; ++ vec *group = NULL; ++ group_info elmt = NULL; ++ unsigned max = circular_queue.length () * circular_queue[0]->length (); ++ vec_alloc (stmts, max); ++ while (front < circular_queue.length ()) ++ { ++ unsigned i = 0; ++ if (merged_groups.contains (front)) ++ { ++ front++; ++ continue; ++ } ++ group = circular_queue[front++]; ++ FOR_EACH_VEC_ELT (*group, i, elmt) ++ if (elmt->stmt != NULL && elmt->done && elmt->cut_point) ++ stmts->safe_push (elmt->stmt); ++ } ++ return stmts->length () != 0; ++} ++ ++/* Grouped loads are isomorphic. Make pair for group number and iteration, ++ map load stmt to this pair. We set iteration 0 here. */ ++ ++static void ++init_isomer_lhs (vec *> &groups, isomer_stmt_lhs &isomer_lhs) ++{ ++ vec *group = NULL; ++ group_info elmt = NULL; ++ unsigned i = 0; ++ FOR_EACH_VEC_ELT (groups, i, group) ++ { ++ unsigned j = 0; ++ FOR_EACH_VEC_ELT (*group, j, elmt) ++ isomer_lhs[gimple_assign_lhs (elmt->stmt)] = std::make_pair (i, 0); ++ } ++} ++ ++/* It's not a strict analysis of load/store profit. Assume scalar and vector ++ load/store are of the same cost. The result PROFIT equals profit form ++ vectorizing of scalar loads/stores minus cost of a vectorized load/store. */ ++ ++static int ++load_store_profit (unsigned scalar_mem_ops, unsigned vf, unsigned new_mem_ops) ++{ ++ int profit = 0; ++ enum vect_cost_for_stmt kind = scalar_load; ++ int scalar_cost = builtin_vectorization_cost (kind, NULL_TREE, 0); ++ profit += (scalar_mem_ops - (scalar_mem_ops / vf)) * scalar_cost; ++ profit -= new_mem_ops / vf * scalar_cost; ++ kind = scalar_store; ++ scalar_cost = builtin_vectorization_cost (kind, NULL_TREE, 0); ++ profit -= new_mem_ops / vf * scalar_cost; ++ return profit; ++} ++ ++/* Breadth first search the graph consisting of define-use chain starting from ++ the circular queue initialized by function BUILD_QUEUE. Find single use of ++ each stmt in group and check if they are isomorphic. Isomorphic is defined ++ as same rhs type, same operator, and isomorphic calculation of each rhs ++ starting from load. If another rhs is uncertain to be isomorphic, put it ++ at the end of circular queue and re-analyze it during the next iteration. ++ If a group shares the same use_stmt with another group, skip one of them in ++ succeedor prcoesses as merged. Iterate the circular queue until all ++ remianing groups heterogeneous or reaches MEN stmts. If all other groups ++ have finishes the analysis, and the remaining groups are uncertain, ++ return false to avoid endless loop. */ ++ ++bool ++bfs_find_isomer_stmts (vec *> &circular_queue, ++ stmts_profit &profit_pair, unsigned vf, ++ bool &reach_vdef) ++{ ++ isomer_stmt_lhs isomer_lhs; ++ auto_vec hetero_lhs; ++ auto_vec merged_groups; ++ vec *group = NULL; ++ /* True if analysis finishes. */ ++ bool done = false; ++ int profit_sum = 0; ++ vec *stmts = NULL; ++ init_isomer_lhs (circular_queue, isomer_lhs); ++ for (unsigned i = 1; !done; ++i) ++ { ++ unsigned front = 0; ++ /* Re-initialize DONE to TRUE while a new iteration begins. */ ++ done = true; ++ while (front < circular_queue.length ()) ++ { ++ int profit = 0; ++ group = circular_queue[front]; ++ done &= check_group (group, front, i, profit, merged_groups, ++ isomer_lhs, hetero_lhs); ++ profit_sum += profit; ++ if (profit != 0 && (*group)[0]->stmt == NULL) ++ { ++ reach_vdef = true; ++ return false; ++ } ++ ++front; ++ } ++ /* Uncertain result, return. */ ++ if (!done && end_of_search (circular_queue, merged_groups)) ++ return false; ++ } ++ if (check_any_cutpoints (circular_queue, stmts, merged_groups)) ++ { ++ profit_pair.first = stmts; ++ unsigned loads = circular_queue.length () * circular_queue[0]->length (); ++ profit_pair.second = profit_sum + load_store_profit (loads, vf, ++ stmts->length ()); ++ if (profit_pair.second > 0) ++ return true; ++ } ++ return false; ++} ++ ++/* Free memory allocated by ginfo. */ ++ ++static void ++free_ginfos (vec *> &worklists) ++{ ++ vec *worklist; ++ unsigned i = 0; ++ while (i < worklists.length ()) ++ { ++ worklist = worklists[i++]; ++ group_info ginfo; ++ unsigned j = 0; ++ FOR_EACH_VEC_ELT (*worklist, j, ginfo) ++ delete ginfo; ++ vec_free (worklist); ++ } ++} ++ ++static void ++release_tmp_stmts (vf_stmts_profit_map &candi_stmts) ++{ ++ vf_stmts_profit_map::iterator iter; ++ for (iter = candi_stmts.begin (); iter != candi_stmts.end (); ++iter) ++ iter->second.first->release (); ++} ++ ++/* Choose the group of stmt with maximun profit. */ ++ ++static bool ++decide_stmts_by_profit (vf_stmts_profit_map &candi_stmts, vec &stmts) ++{ ++ vf_stmts_profit_map::iterator iter; ++ int profit = 0; ++ int max = 0; ++ vec *tmp = NULL; ++ for (iter = candi_stmts.begin (); iter != candi_stmts.end (); ++iter) ++ { ++ profit = iter->second.second; ++ if (profit > max) ++ { ++ tmp = iter->second.first; ++ max = profit; ++ } ++ } ++ if (max == 0) ++ { ++ release_tmp_stmts (candi_stmts); ++ return false; ++ } ++ unsigned i = 0; ++ gimple *stmt = NULL; ++ FOR_EACH_VEC_ELT (*tmp, i, stmt) ++ stmts.safe_push (stmt); ++ release_tmp_stmts (candi_stmts); ++ return stmts.length () != 0; ++} ++ ++/* Find isomorphic stmts from grouped loads with vector factor VF. ++ ++ Given source code as follows and ignore casting. ++ ++ a0 = (a[0] + b[0]) + ((a[4] - b[4]) << 16); ++ a1 = (a[1] + b[1]) + ((a[5] - b[5]) << 16); ++ a2 = (a[2] + b[2]) + ((a[6] - b[6]) << 16); ++ a3 = (a[3] + b[3]) + ((a[7] - b[7]) << 16); ++ ++ We get grouped loads in VINFO as ++ ++ GROUP_1 GROUP_2 ++ _1 = *a _11 = *b ++ _2 = *(a + 1) _12 = *(b + 1) ++ _3 = *(a + 2) _13 = *(b + 2) ++ _4 = *(a + 3) _14 = *(b + 3) ++ _5 = *(a + 4) _15 = *(b + 4) ++ _6 = *(a + 5) _16 = *(b + 5) ++ _7 = *(a + 6) _17 = *(b + 6) ++ _8 = *(a + 7) _18 = *(b + 7) ++ ++ First we try VF = 8, we get two worklists ++ ++ WORKLIST_1 WORKLIST_2 ++ _1 = *a _11 = *b ++ _2 = *(a + 1) _12 = *(b + 1) ++ _3 = *(a + 2) _13 = *(b + 2) ++ _4 = *(a + 3) _14 = *(b + 3) ++ _5 = *(a + 4) _15 = *(b + 4) ++ _6 = *(a + 5) _16 = *(b + 5) ++ _7 = *(a + 6) _17 = *(b + 6) ++ _8 = *(a + 7) _18 = *(b + 7) ++ ++ We find _111 = _1 + _11 and _115 = _5 - _15 are not isomorphic, ++ so we try VF = VF / 2. ++ ++ GROUP_1 GROUP_2 ++ _1 = *a _5 = *(a + 4) ++ _2 = *(a + 1) _6 = *(a + 5) ++ _3 = *(a + 2) _7 = *(a + 6) ++ _4 = *(a + 3) _8 = *(a + 7) ++ ++ GROUP_3 GROUP_4 ++ _11 = *b _15 = *(b + 4) ++ _12 = *(b + 1) _16 = *(b + 5) ++ _13 = *(b + 2) _17 = *(b + 6) ++ _14 = *(b + 3) _18 = *(b + 7) ++ ++ We first analyze group_1, and find all operations are isomorphic, then ++ replace stmts in group_1 with their use_stmts. Group_2 as well. ++ ++ GROUP_1 GROUP_2 ++ _111 = _1 + _11 _115 = _5 - _15 ++ _112 = _2 + _12 _116 = _6 - _16 ++ _113 = _3 + _13 _117 = _7 - _17 ++ _114 = _4 + _14 _118 = _8 - _18 ++ ++ When analyzing group_3 and group_4, we find their use_stmts are the same ++ as group_1 and group_2. So group_3 is regarded as being merged to group_1 ++ and group_4 being merged to group_2. In future procedures, we will skip ++ group_3 and group_4. ++ ++ We repeat such processing until opreations are not isomorphic or searching ++ reaches MEM stmts. In our given case, searching end up at a0, a1, a2 and ++ a3. */ ++ ++static bool ++find_isomorphic_stmts (loop_vec_info vinfo, vec &stmts) ++{ ++ unsigned vf = get_max_vf (vinfo); ++ if (vf == 0) ++ return false; ++ auto_vec *> circular_queue; ++ /* Map of vector factor and corresponding vectorizing profit. */ ++ stmts_profit profit_map; ++ /* Map of cut_points and vector factor. */ ++ vf_stmts_profit_map candi_stmts; ++ bool reach_vdef = false; ++ while (vf > 2) ++ { ++ if (build_queue (vinfo, vf, circular_queue) == 0) ++ return false; ++ if (!bfs_find_isomer_stmts (circular_queue, profit_map, vf, reach_vdef)) ++ { ++ if (reach_vdef) ++ { ++ release_tmp_stmts (candi_stmts); ++ free_ginfos (circular_queue); ++ circular_queue.release (); ++ return false; ++ } ++ vf /= 2; ++ free_ginfos (circular_queue); ++ circular_queue.release (); ++ continue; ++ } ++ candi_stmts[vf] = profit_map; ++ free_ginfos (circular_queue); ++ vf /= 2; ++ circular_queue.release (); ++ } ++ return decide_stmts_by_profit (candi_stmts, stmts); ++} ++ ++/* Get iv from SEED_STMTS and make sure each seed_stmt has only one iv as index ++ and all indices are the same. */ ++ ++static tree ++find_index (vec seed_stmts) ++{ ++ if (seed_stmts.length () == 0) ++ return NULL; ++ bool found_index = false; ++ tree index = NULL; ++ unsigned ui = 0; ++ for (ui = 0; ui < seed_stmts.length (); ui++) ++ { ++ if (!gimple_vdef (seed_stmts[ui])) ++ return NULL; ++ tree lhs = gimple_assign_lhs (seed_stmts[ui]); ++ unsigned num_index = 0; ++ while (TREE_CODE (lhs) == ARRAY_REF) ++ { ++ if (TREE_CODE (TREE_OPERAND (lhs, 1)) == SSA_NAME) ++ { ++ num_index++; ++ if (num_index > 1) ++ return NULL; ++ if (index == NULL) ++ { ++ index = TREE_OPERAND (lhs, 1); ++ found_index = true; ++ } ++ else if (index != TREE_OPERAND (lhs, 1)) ++ return NULL; ++ } ++ lhs = TREE_OPERAND (lhs, 0); ++ } ++ if (!found_index) ++ return NULL; ++ } ++ return index; ++} ++ ++/* Check if expression of phi is an increament of a const. */ ++ ++static void ++check_phi_inc (struct vertex *v_phi, struct graph *rdg, bool &found_inc) ++{ ++ struct graph_edge *e_phi; ++ for (e_phi = v_phi->succ; e_phi; e_phi = e_phi->succ_next) ++ { ++ struct vertex *v_inc = &(rdg->vertices[e_phi->dest]); ++ if (!is_gimple_assign (RDGV_STMT (v_inc)) ++ || gimple_expr_code (RDGV_STMT (v_inc)) != PLUS_EXPR) ++ continue; ++ tree rhs1 = gimple_assign_rhs1 (RDGV_STMT (v_inc)); ++ tree rhs2 = gimple_assign_rhs2 (RDGV_STMT (v_inc)); ++ if (!(integer_onep (rhs1) || integer_onep (rhs2))) ++ continue; ++ struct graph_edge *e_inc; ++ /* find cycle with only two vertices inc and phi: inc <--> phi. */ ++ bool found_cycle = false; ++ for (e_inc = v_inc->succ; e_inc; e_inc = e_inc->succ_next) ++ { ++ if (e_inc->dest == e_phi->src) ++ { ++ found_cycle = true; ++ break; ++ } ++ } ++ if (!found_cycle) ++ continue; ++ found_inc = true; ++ } ++} ++ ++/* Check if phi satisfies form like PHI <0, i>. */ ++ ++static inline bool ++iv_check_phi_stmt (gimple *phi_stmt) ++{ ++ return gimple_phi_num_args (phi_stmt) == 2 ++ && (integer_zerop (gimple_phi_arg_def (phi_stmt, 0)) ++ || integer_zerop (gimple_phi_arg_def (phi_stmt, 1))); ++} ++ ++/* Make sure the iteration varible is a phi. */ ++ ++static tree ++get_iv_from_seed (struct graph *flow_only_rdg, vec seed_stmts) ++{ ++ tree index = find_index (seed_stmts); ++ if (index == NULL) ++ return NULL; ++ for (int i = 0; i < flow_only_rdg->n_vertices; i++) ++ { ++ struct vertex *v = &(flow_only_rdg->vertices[i]); ++ if (RDGV_STMT (v) != seed_stmts[0]) ++ continue; ++ struct graph_edge *e; ++ bool found_phi = false; ++ for (e = v->pred; e; e = e->pred_next) ++ { ++ struct vertex *v_phi = &(flow_only_rdg->vertices[e->src]); ++ gimple *phi_stmt = RDGV_STMT (v_phi); ++ if (gimple_code (phi_stmt) != GIMPLE_PHI ++ || gimple_phi_result (phi_stmt) != index) ++ continue; ++ if (!iv_check_phi_stmt (phi_stmt)) ++ return NULL; ++ /* find inc expr in succ of phi. */ ++ bool found_inc = false; ++ check_phi_inc (v_phi, flow_only_rdg, found_inc); ++ if (!found_inc) ++ return NULL; ++ found_phi = true; ++ break; ++ } ++ if (!found_phi) ++ return NULL; ++ break; ++ } ++ return index; ++} ++ ++/* Do not distribute loop if vertexes in ROOT_MAP have antidependence with in ++ FLOW_ONLY_RDG. */ ++ ++static bool ++check_no_dependency (struct graph *flow_only_rdg, bitmap root_map) ++{ ++ bitmap_iterator bi; ++ unsigned ui; ++ auto_vec visited_nodes; ++ auto_bitmap visited_map; ++ EXECUTE_IF_SET_IN_BITMAP (root_map, 0, ui, bi) ++ visited_nodes.safe_push (ui); ++ for (ui = 0; ui < visited_nodes.length (); ui++) ++ { ++ struct vertex *v = &(flow_only_rdg->vertices[visited_nodes[ui]]); ++ struct graph_edge *e; ++ for (e = v->succ; e; e = e->succ_next) ++ { ++ if (bitmap_bit_p (root_map, e->dest)) ++ return false; ++ if (bitmap_bit_p (visited_map, e->dest)) ++ continue; ++ visited_nodes.safe_push (e->dest); ++ bitmap_set_bit (visited_map, e->dest); ++ } ++ } ++ return true; ++} ++ ++/* Find isomorphic stmts from GROUPED_LOADS in VINFO and make sure ++ there is no dependency among those STMT we found. */ ++ ++static unsigned ++get_cut_points (struct graph *flow_only_rdg, bitmap cut_points, ++ loop_vec_info vinfo) ++{ ++ unsigned n_stmts = 0; ++ ++ /* STMTS that may be CUT_POINTS. */ ++ auto_vec stmts; ++ if (!find_isomorphic_stmts (vinfo, stmts)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "No temp array insertion: no isomorphic stmts" ++ " were found.\n"); ++ return 0; ++ } ++ ++ for (int i = 0; i < flow_only_rdg->n_vertices; i++) ++ { ++ if (stmts.contains (RDG_STMT (flow_only_rdg, i))) ++ bitmap_set_bit (cut_points, i); ++ } ++ n_stmts = bitmap_count_bits (cut_points); ++ ++ bool succ = check_no_dependency (flow_only_rdg, cut_points); ++ if (!succ) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "No temp array inserted: data dependency" ++ " among isomorphic stmts.\n"); ++ return 0; ++ } ++ return n_stmts; ++} ++ ++static void ++build_temp_array (struct vertex *v, gimple_stmt_iterator &gsi, ++ poly_uint64 array_extent, tree iv, ++ hash_set *tmp_array_vars, vec *transformed) ++{ ++ gimple *stmt = RDGV_STMT (v); ++ tree lhs = gimple_assign_lhs (stmt); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "original stmt:\t"); ++ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS|TDF_MEMSYMS); ++ } ++ tree var_ssa = duplicate_ssa_name (lhs, stmt); ++ gimple_assign_set_lhs (stmt, var_ssa); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "changed to:\t"); ++ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS); ++ } ++ gimple_set_uid (gsi_stmt (gsi), -1); ++ tree vect_elt_type = TREE_TYPE (lhs); ++ tree array_type = build_array_type_nelts (vect_elt_type, array_extent); ++ tree array = create_tmp_var (array_type); ++ tree array_ssa = build4 (ARRAY_REF, vect_elt_type, array, iv, NULL, NULL); ++ tmp_array_vars->add (array_ssa); ++ gimple *store = gimple_build_assign (array_ssa, var_ssa); ++ tree new_vdef = make_ssa_name (gimple_vop (cfun), store); ++ gsi_insert_after (&gsi, store, GSI_NEW_STMT); ++ gimple_set_vdef (store, new_vdef); ++ transformed->safe_push (store); ++ gimple_set_uid (gsi_stmt (gsi), -1); ++ tree array_ssa2 = build4 (ARRAY_REF, vect_elt_type, array, iv, NULL, NULL); ++ tmp_array_vars->add (array_ssa2); ++ gimple *load = gimple_build_assign (lhs, array_ssa2); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "insert stmt:\t"); ++ print_gimple_stmt (dump_file, store, 0, TDF_VOPS|TDF_MEMSYMS); ++ fprintf (dump_file, " and stmt:\t"); ++ print_gimple_stmt (dump_file, load, 0, TDF_VOPS|TDF_MEMSYMS); ++ } ++ gimple_set_vuse (load, new_vdef); ++ gsi_insert_after (&gsi, load, GSI_NEW_STMT); ++ gimple_set_uid (gsi_stmt (gsi), -1); ++} ++ ++/* Set bitmap PRODUCERS based on vec TRANSFORMED. */ ++ ++void ++loop_distribution::build_producers (loop_p loop, bitmap producers, ++ vec &transformed) ++{ ++ auto_vec stmts; ++ stmts_from_loop (loop, &stmts); ++ int i = 0; ++ gimple *stmt = NULL; ++ ++ FOR_EACH_VEC_ELT (stmts, i, stmt) ++ gimple_set_uid (stmt, i); ++ i = 0; ++ FOR_EACH_VEC_ELT (transformed, i, stmt) ++ bitmap_set_bit (producers, stmt->uid); ++} ++ ++/* Transform stmt ++ ++ A = FOO (ARG_1); ++ ++ to ++ ++ STMT_1: A1 = FOO (ARG_1); ++ STMT_2: X[I] = A1; ++ STMT_3: A = X[I]; ++ ++ Producer is STMT_2 who defines the temp array and consumer is ++ STMT_3 who uses the temp array. */ ++ ++void ++loop_distribution::do_insertion (loop_p loop, struct graph *flow_only_rdg, ++ tree iv, bitmap cut_points, ++ hash_set *tmp_array_vars, ++ bitmap producers) ++{ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "=== do insertion ===\n"); ++ ++ auto_vec transformed; ++ ++ /* Execution times of loop. */ ++ poly_uint64 array_extent ++ = tree_to_poly_uint64 (number_of_latch_executions (loop)) + 1; ++ ++ basic_block *bbs = get_loop_body_in_custom_order (loop, this, ++ bb_top_order_cmp_r); ++ ++ for (int i = 0; i < int (loop->num_nodes); i++) ++ { ++ basic_block bb = bbs[i]; ++ ++ /* Find all cut points in bb and transform them. */ ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ++ gsi_next (&gsi)) ++ { ++ unsigned j = gimple_uid (gsi_stmt (gsi)); ++ if (bitmap_bit_p (cut_points, j)) ++ { ++ struct vertex *v = &(flow_only_rdg->vertices[j]); ++ build_temp_array (v, gsi, array_extent, iv, tmp_array_vars, ++ &transformed); ++ } ++ } ++ } ++ build_producers (loop, producers, transformed); ++ update_ssa (TODO_update_ssa); ++ free (bbs); ++} ++ ++/* After temp array insertion, given stmts ++ STMT_1: M = FOO (ARG_1); ++ STMT_2: X[I] = M; ++ STMT_3: A = X[I]; ++ STMT_2 is the producer, STMT_1 is its prev and STMT_3 is its next. ++ Replace M with A, and remove STMT_2 and STMT_3. */ ++ ++static void ++reset_gimple_assign (struct graph *flow_only_rdg, struct partition *partition, ++ gimple_stmt_iterator &gsi, int j) ++{ ++ struct vertex *v = &(flow_only_rdg->vertices[j]); ++ gimple *stmt = RDGV_STMT (v); ++ gimple *prev = stmt->prev; ++ gimple *next = stmt->next; ++ tree n_lhs = gimple_assign_lhs (next); ++ gimple_assign_set_lhs (prev, n_lhs); ++ unlink_stmt_vdef (stmt); ++ if (partition) ++ bitmap_clear_bit (partition->stmts, gimple_uid (gsi_stmt (gsi))); ++ gsi_remove (&gsi, true); ++ release_defs (stmt); ++ if (partition) ++ bitmap_clear_bit (partition->stmts, gimple_uid (gsi_stmt (gsi))); ++ gsi_remove (&gsi, true); ++} ++ ++void ++loop_distribution::remove_insertion (loop_p loop, struct graph *flow_only_rdg, ++ bitmap producers, struct partition *partition) ++{ ++ basic_block *bbs = get_loop_body_in_custom_order (loop, this, ++ bb_top_order_cmp_r); ++ for (int i = 0; i < int (loop->num_nodes); i++) ++ { ++ basic_block bb = bbs[i]; ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ++ gsi_next (&gsi)) ++ { ++ unsigned j = gimple_uid (gsi_stmt (gsi)); ++ if (bitmap_bit_p (producers, j)) ++ reset_gimple_assign (flow_only_rdg, partition, gsi, j); ++ } ++ } ++ update_ssa (TODO_update_ssa); ++ free (bbs); ++} ++ ++/* Insert temp arrays if isomorphic computation exists. Temp arrays will be ++ regarded as SEED_STMTS for building partitions in succeeding processes. */ ++ ++bool ++loop_distribution::insert_temp_arrays (loop_p loop, vec seed_stmts, ++ hash_set *tmp_array_vars, bitmap producers) ++{ ++ struct graph *flow_only_rdg = build_rdg (loop, NULL); ++ gcc_checking_assert (flow_only_rdg != NULL); ++ tree iv = get_iv_from_seed (flow_only_rdg, seed_stmts); ++ if (iv == NULL) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Loop %d no temp array insertion: failed to get" ++ " iteration variable.\n", loop->num); ++ free_rdg (flow_only_rdg); ++ return false; ++ } ++ auto_bitmap cut_points; ++ loop_vec_info vinfo = loop_vec_info_for_loop (loop); ++ unsigned n_cut_points = get_cut_points (flow_only_rdg, cut_points, vinfo); ++ delete vinfo; ++ loop->aux = NULL; ++ if (n_cut_points == 0) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Loop %d no temp array insertion: no cut points" ++ " found.\n", loop->num); ++ free_rdg (flow_only_rdg); ++ return false; ++ } ++ do_insertion (loop, flow_only_rdg, iv, cut_points, tmp_array_vars, producers); ++ if (dump_enabled_p ()) ++ { ++ dump_user_location_t loc = find_loop_location (loop); ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, "Insertion done:" ++ " %d temp arrays inserted in Loop %d.\n", ++ n_cut_points, loop->num); ++ } ++ free_rdg (flow_only_rdg); ++ return true; ++} ++ ++static bool find_seed_stmts_for_distribution (class loop *, vec *); ++ + /* Distributes the code from LOOP in such a way that producer statements + are placed before consumer statements. Tries to separate only the + statements from STMTS into separate loops. Returns the number of +@@ -2972,7 +4342,7 @@ loop_distribution::finalize_partitions (class loop *loop, + + int + loop_distribution::distribute_loop (class loop *loop, +- const vec &stmts, ++ vec &stmts, + control_dependences *cd, int *nb_calls, bool *destroy_p, + bool only_patterns_p) + { +@@ -3021,6 +4391,33 @@ loop_distribution::distribute_loop (class loop *loop, + return 0; + } + ++ /* Try to distribute LOOP if LOOP is simple enough and unable to vectorize. ++ If LOOP has grouped loads, recursively find isomorphic stmts and insert ++ temp arrays, rebuild RDG and call find_seed_stmts_for_distribution ++ to replace STMTS. */ ++ ++ hash_set tmp_array_vars; ++ ++ /* STMTs that define those inserted TMP_ARRAYs. */ ++ auto_bitmap producers; ++ ++ /* New SEED_STMTS after insertion. */ ++ auto_vec work_list; ++ bool insert_success = false; ++ if (may_insert_temp_arrays (loop, rdg, cd)) ++ { ++ if (insert_temp_arrays (loop, stmts, &tmp_array_vars, producers)) ++ { ++ if (find_seed_stmts_for_distribution (loop, &work_list)) ++ { ++ insert_success = true; ++ } ++ else ++ remove_insertion (loop, rdg, producers, NULL); ++ rebuild_rdg (loop, rdg, cd); ++ } ++ } ++ + data_reference_p dref; + for (i = 0; datarefs_vec.iterate (i, &dref); ++i) + dref->aux = (void *) (uintptr_t) i; +@@ -3029,7 +4426,10 @@ loop_distribution::distribute_loop (class loop *loop, + dump_rdg (dump_file, rdg); + + auto_vec partitions; +- rdg_build_partitions (rdg, stmts, &partitions); ++ if (work_list.length() > stmts.length()) ++ rdg_build_partitions (rdg, &work_list, &partitions); ++ else ++ rdg_build_partitions (rdg, &stmts, &partitions); + + auto_vec alias_ddrs; + +@@ -3101,7 +4501,7 @@ loop_distribution::distribute_loop (class loop *loop, + for (int j = i + 1; + partitions.iterate (j, &partition); ++j) + { +- if (share_memory_accesses (rdg, into, partition)) ++ if (share_memory_accesses (rdg, into, partition, &tmp_array_vars)) + { + partition_merge_into (rdg, into, partition, FUSE_SHARE_REF); + partitions.unordered_remove (j); +@@ -3151,7 +4551,7 @@ loop_distribution::distribute_loop (class loop *loop, + } + } + +- finalize_partitions (loop, &partitions, &alias_ddrs); ++ finalize_partitions (loop, &partitions, &alias_ddrs, producers); + + /* If there is a reduction in all partitions make sure the last one + is not classified for builtin code generation. */ +@@ -3169,6 +4569,24 @@ loop_distribution::distribute_loop (class loop *loop, + } + + nbp = partitions.length (); ++ ++ /* If we have inserted TMP_ARRAYs but there is only one partition left in ++ the succeeding processes, remove those inserted TMP_ARRAYs back to the ++ original version. */ ++ ++ if (nbp == 1 && insert_success) ++ { ++ struct partition *partition = NULL; ++ partitions.iterate (0, &partition); ++ remove_insertion (loop, rdg, producers, partition); ++ if (dump_enabled_p ()) ++ { ++ dump_user_location_t loc = find_loop_location (loop); ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, "Insertion removed:" ++ " unable to distribute loop %d.\n", loop->num); ++ } ++ } ++ + if (nbp == 0 + || (nbp == 1 && !partition_builtin_p (partitions[0])) + || (nbp > 1 && partition_contains_all_rw (rdg, partitions))) +diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc +index 04e68f621..aae7f62f3 100644 +--- a/gcc/tree-vect-data-refs.cc ++++ b/gcc/tree-vect-data-refs.cc +@@ -2791,6 +2791,9 @@ vect_analyze_group_access_1 (vec_info *vinfo, dr_vec_info *dr_info) + DR_GROUP_GAP (stmt_info) = groupsize - last_accessed_element; + + DR_GROUP_SIZE (stmt_info) = groupsize; ++ ++ DR_GROUP_SLP_TRANSPOSE (stmt_info) = false; ++ + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, +@@ -2820,6 +2823,20 @@ vect_analyze_group_access_1 (vec_info *vinfo, dr_vec_info *dr_info) + DR_GROUP_GAP (stmt_info)); + } + ++ /* SLP: create an SLP data structure for every interleaving group of ++ loads for further analysis in vect_analyse_slp. */ ++ if (DR_IS_READ (dr) && !slp_impossible) ++ { ++ if (loop_vinfo) ++ { ++ LOOP_VINFO_GROUPED_LOADS (loop_vinfo).safe_push (stmt_info); ++ } ++ if (bb_vinfo) ++ { ++ BB_VINFO_GROUPED_LOADS (bb_vinfo).safe_push (stmt_info); ++ } ++ } ++ + /* SLP: create an SLP data structure for every interleaving group of + stores for further analysis in vect_analyse_slp. */ + if (DR_IS_WRITE (dr) && !slp_impossible) +@@ -5636,6 +5653,226 @@ vect_permute_store_chain (vec_info *vinfo, vec &dr_chain, + } + } + ++/* Encoding the PERM_MASK_FIRST. */ ++ ++static void ++vect_indices_encoding_first (tree vectype, unsigned int array_num, ++ tree &perm_mask_high_first, ++ tree &perm_mask_low_first) ++{ ++ unsigned int nelt = TYPE_VECTOR_SUBPARTS (vectype).to_constant (); ++ vec_perm_builder sel (nelt, nelt, 1); ++ sel.quick_grow (nelt); ++ unsigned int group_num = nelt / array_num; ++ unsigned int index = 0; ++ unsigned int array = 0; ++ unsigned int group = 0; ++ ++ /* The encoding has 1 pattern in the fisrt stage. */ ++ for (array = 0; array < array_num / 2; array++) ++ { ++ for (group = 0; group < group_num * 2; group++) ++ { ++ sel[index++] = array + array_num * group; ++ } ++ } ++ vec_perm_indices indices (sel, 2, nelt); ++ perm_mask_high_first = vect_gen_perm_mask_checked (vectype, indices); ++ ++ index = 0; ++ for (array = array_num / 2; array < array_num; array++) ++ { ++ for (group = 0; group < group_num * 2; group++) ++ { ++ sel[index++] = array + array_num * group; ++ } ++ } ++ indices.new_vector (sel, 2, nelt); ++ perm_mask_low_first = vect_gen_perm_mask_checked (vectype, indices); ++} ++ ++/* Encoding the PERM_MASK. */ ++ ++static void ++vect_indices_encoding (tree vectype, unsigned int array_num, ++ tree &perm_mask_high, tree &perm_mask_low) ++{ ++ unsigned int nelt = TYPE_VECTOR_SUBPARTS (vectype).to_constant (); ++ vec_perm_builder sel (nelt, nelt, 1); ++ sel.quick_grow (nelt); ++ unsigned int group_num = nelt / array_num; ++ unsigned int index = 0; ++ unsigned int array = 0; ++ unsigned int group = 0; ++ ++ /* The encoding has 2 patterns in the folllowing stages. */ ++ for (array = 0; array < array_num / 2; array++) ++ { ++ for (group = 0; group < group_num; group++) ++ { ++ sel[index++] = group + group_num * array; ++ } ++ for (group = 0; group < group_num; group++) ++ { ++ sel[index++] = nelt + group + group_num * array; ++ } ++ } ++ vec_perm_indices indices (sel, 2, nelt); ++ perm_mask_high = vect_gen_perm_mask_checked (vectype, indices); ++ ++ index = 0; ++ for (array = array_num / 2; array < array_num; array++) ++ { ++ for (group = 0; group < group_num; group++) ++ { ++ sel[index++] = group + group_num * array; ++ } ++ for (group = 0; group < group_num; group++) ++ { ++ sel[index++] = nelt + group + group_num * array; ++ } ++ } ++ indices.new_vector (sel, 2, nelt); ++ perm_mask_low = vect_gen_perm_mask_checked (vectype, indices); ++} ++ ++/* Function vect_transpose_store_chain. ++ ++ Given a chain of interleaved stores in DR_CHAIN of LENGTH and ARRAY_NUM that ++ must be a power of 2. Generate interleave_high/low stmts to reorder ++ the data correctly for the stores. Return the final references for stores ++ in RESULT_CHAIN. This function is similar to vect_permute_store_chain (), ++ we interleave the contents of the vectors in their order. ++ ++ E.g., LENGTH is 4, the scalar type is short (i.e., VF is 8) and ARRAY_NUM ++ is 4. That is, the input is 4 vectors each containing 8 elements. ++ And 2 (VF / ARRAY_NUM) of 8 elements come from the same array. we interleave ++ the contents of the four vectors in their order. We assign a number to each ++ element, the input sequence is: ++ ++ 1st vec: 0 1 2 3 4 5 6 7 ++ 2nd vec: 8 9 10 11 12 13 14 15 ++ 3rd vec: 16 17 18 19 20 21 22 23 ++ 4th vec: 24 25 26 27 28 29 30 31 ++ ++ The output sequence should be: ++ ++ 1st vec: 0 4 8 12 16 20 24 28 ++ 2nd vec: 1 5 9 13 17 21 25 29 ++ 3rd vec: 2 6 10 14 18 22 26 30 ++ 4th vec: 3 7 11 15 19 23 27 31 ++ ++ In our example, ++ We get 2 (VF / ARRAY_NUM) elements together in every vector. ++ ++ I1: 0 4 1 5 2 6 3 7 ++ I2: 8 12 9 13 10 14 11 15 ++ I3: 16 20 17 21 18 22 19 23 ++ I4: 24 28 25 29 26 30 27 31 ++ ++ Then, we use interleave_high/low instructions to create such output. ++ Every 2 (VF / ARRAY_NUM) elements are regarded as a whole. The permutation ++ is done in log LENGTH stages. ++ ++ I1: interleave_high (1st vec, 3rd vec) ++ I2: interleave_low (1st vec, 3rd vec) ++ I3: interleave_high (2nd vec, 4th vec) ++ I4: interleave_low (2nd vec, 4th vec) ++ ++ The first stage of the sequence should be: ++ ++ I1: 0 4 16 20 1 5 17 21 ++ I2: 2 6 18 22 3 7 19 23 ++ I3: 8 12 24 28 9 13 25 29 ++ I4: 10 14 26 30 11 15 27 31 ++ ++ The following stage sequence should be, i.e. the final result is: ++ ++ I1: 0 4 8 12 16 20 24 28 ++ I2: 1 5 9 13 17 21 25 29 ++ I3: 2 6 10 14 18 22 26 30 ++ I4: 3 7 11 15 19 23 27 31. */ ++ ++void ++vect_transpose_store_chain (vec_info *vinfo, vec dr_chain, ++ unsigned int length, unsigned int array_num, ++ stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ++ vec *result_chain) ++{ ++ gimple *perm_stmt = NULL; ++ tree vectype = STMT_VINFO_VECTYPE (stmt_info); ++ tree perm_mask_low_first = NULL; ++ tree perm_mask_high_first = NULL; ++ tree perm_mask_low = NULL; ++ tree perm_mask_high = NULL; ++ unsigned int log_length = exact_log2 (length); ++ ++ /* Only power of 2 is supported. */ ++ gcc_assert (pow2p_hwi (length)); ++ ++ /* The encoding has 2 types, one for the grouped pattern in the fisrt stage, ++ another for the interleaved patterns in the following stages. */ ++ gcc_assert (array_num != 0); ++ ++ /* Create grouped stmt (in the first stage): ++ group = nelt / array_num; ++ high_first = VEC_PERM_EXPR ++ low_first = VEC_PERM_EXPR */ ++ vect_indices_encoding_first (vectype, array_num, perm_mask_high_first, ++ perm_mask_low_first); ++ ++ /* Create interleaving stmt (in the following stages): ++ high = VEC_PERM_EXPR ++ low = VEC_PERM_EXPR */ ++ vect_indices_encoding (vectype, array_num, perm_mask_high, perm_mask_low); ++ ++ for (unsigned int perm_time = 0; perm_time < log_length; perm_time++) ++ { ++ for (unsigned int index = 0; index < length / 2; index++) ++ { ++ tree vect1 = dr_chain[index]; ++ tree vect2 = dr_chain[index + length / 2]; ++ ++ tree high = make_temp_ssa_name (vectype, NULL, "vect_inter_high"); ++ perm_stmt = gimple_build_assign (high, VEC_PERM_EXPR, vect1, vect2, ++ perm_time == 0 ? perm_mask_high_first ++ : perm_mask_high); ++ vect_finish_stmt_generation (vinfo, stmt_info, perm_stmt, gsi); ++ (*result_chain)[2 * index] = high; ++ ++ tree low = make_temp_ssa_name (vectype, NULL, "vect_inter_low"); ++ perm_stmt = gimple_build_assign (low, VEC_PERM_EXPR, vect1, vect2, ++ perm_time == 0 ? perm_mask_low_first ++ : perm_mask_low); ++ vect_finish_stmt_generation (vinfo, stmt_info, perm_stmt, gsi); ++ (*result_chain)[2 * index+1] = low; ++ } ++ memcpy (dr_chain.address (), result_chain->address (), ++ length * sizeof (tree)); ++ } ++} ++ + /* Function vect_setup_realignment + + This function is called when vectorizing an unaligned load using +diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc +index 3435f9378..f296e9415 100644 +--- a/gcc/tree-vect-loop.cc ++++ b/gcc/tree-vect-loop.cc +@@ -2856,7 +2856,7 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, + loop_vec_info main_loop_vinfo, + const vector_modes &vector_modes, unsigned &mode_i, + machine_mode &autodetected_vector_mode, +- bool &fatal) ++ bool &fatal, bool result_only_p) + { + loop_vec_info loop_vinfo + = vect_create_loop_vinfo (loop, shared, loop_form_info, main_loop_vinfo); +@@ -2865,6 +2865,8 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, + loop_vinfo->vector_mode = vector_mode; + unsigned int suggested_unroll_factor = 1; + ++ /* Loop_vinfo for loop-distribution pass. */ ++ opt_loop_vec_info fail_loop_vinfo = opt_loop_vec_info::success (NULL); + /* Run the main analysis. */ + opt_result res = vect_analyze_loop_2 (loop_vinfo, fatal, + &suggested_unroll_factor); +@@ -2933,7 +2935,21 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, + + if (!res) + { +- delete loop_vinfo; ++ ++ /* If current analysis shows LOOP is unable to vectorize, loop_vinfo ++ will be deleted. If LOOP is under ldist analysis, backup it before ++ it is deleted and return it if all modes are analyzed and still ++ fail to vectorize. */ ++ if (result_only_p && (mode_i == vector_modes.length () ++ || autodetected_vector_mode == VOIDmode)) ++ { ++ fail_loop_vinfo = opt_loop_vec_info::success (loop_vinfo); ++ loop->aux = (loop_vec_info) fail_loop_vinfo; ++ } ++ else ++ { ++ delete loop_vinfo; ++ } + if (fatal) + gcc_checking_assert (main_loop_vinfo == NULL); + return opt_loop_vec_info::propagate_failure (res); +@@ -2946,9 +2962,11 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared, + + Apply a set of analyses on LOOP, and create a loop_vec_info struct + for it. The different analyses will record information in the +- loop_vec_info struct. */ ++ loop_vec_info struct. When RESULT_ONLY_P is true, quit analysis ++ if loop is vectorizable, otherwise, do not delete vinfo. */ + opt_loop_vec_info +-vect_analyze_loop (class loop *loop, vec_info_shared *shared) ++vect_analyze_loop (class loop *loop, vec_info_shared *shared, ++ bool result_only_p) + { + DUMP_VECT_SCOPE ("analyze_loop_nest"); + +@@ -2996,6 +3014,12 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) + && !unlimited_cost_model (loop)); + machine_mode autodetected_vector_mode = VOIDmode; + opt_loop_vec_info first_loop_vinfo = opt_loop_vec_info::success (NULL); ++ /* Loop_vinfo for loop-distribution pass. */ ++ opt_loop_vec_info fail_loop_vinfo = opt_loop_vec_info::success (NULL); ++ if (result_only_p) ++ { ++ vect_slp_init (); ++ } + unsigned int mode_i = 0; + unsigned HOST_WIDE_INT simdlen = loop->simdlen; + +@@ -3019,10 +3043,16 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) + opt_loop_vec_info loop_vinfo + = vect_analyze_loop_1 (loop, shared, &loop_form_info, + NULL, vector_modes, mode_i, +- autodetected_vector_mode, fatal); ++ autodetected_vector_mode, fatal, result_only_p); + if (fatal) + break; + ++ if (result_only_p && (mode_i == vector_modes.length () ++ || autodetected_vector_mode == VOIDmode)) ++ { ++ return loop_vinfo; ++ } ++ + if (loop_vinfo) + { + /* Analyzis has been successful so update the VF value. The +@@ -3132,7 +3162,7 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) + = vect_analyze_loop_1 (loop, shared, &loop_form_info, + first_loop_vinfo, + vector_modes, mode_i, +- autodetected_vector_mode, fatal); ++ autodetected_vector_mode, fatal, result_only_p); + if (fatal) + break; + +diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc +index e1bcab0f7..c0c15773d 100644 +--- a/gcc/tree-vect-patterns.cc ++++ b/gcc/tree-vect-patterns.cc +@@ -5632,8 +5632,8 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = { + internal functions. */ + { vect_recog_gather_scatter_pattern, "gather_scatter" }, + { vect_recog_mask_conversion_pattern, "mask_conversion" }, +- { vect_recog_widen_plus_pattern, "widen_plus" }, +- { vect_recog_widen_minus_pattern, "widen_minus" }, ++ // { vect_recog_widen_plus_pattern, "widen_plus" }, ++ // { vect_recog_widen_minus_pattern, "widen_minus" }, + }; + + const unsigned int NUM_PATTERNS = ARRAY_SIZE (vect_vect_recog_func_ptrs); +diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc +index af477c31a..6cbf8085f 100644 +--- a/gcc/tree-vect-slp.cc ++++ b/gcc/tree-vect-slp.cc +@@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see + #include "tree-eh.h" + #include "tree-cfg.h" + #include "alloc-pool.h" ++#include "print-tree.h" ++#include "gimple-pretty-print.h" + + static bool vectorizable_slp_permutation (vec_info *, gimple_stmt_iterator *, + slp_tree, stmt_vector_for_cost *); +@@ -994,6 +996,21 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, + } + + gcc_assert (vectype); ++ if (!STMT_VINFO_VECTYPE (stmt_info)) ++ STMT_VINFO_VECTYPE (stmt_info) = vectype; ++ if (dump_file) ++ { ++ fprintf (dump_file, "vect_build_slp_tree_1: %p\n", stmt_info); ++ print_gimple_stmt (dump_file, stmt, 0); ++ fprintf (dump_file, "vect_build_slp_tree_1: vectype="); ++ if (vectype) ++ print_generic_expr (dump_file, vectype); ++ fprintf (dump_file, "\n"); ++ fprintf (dump_file, "internal vectype="); ++ if (STMT_VINFO_VECTYPE (stmt_info)) ++ print_generic_expr (dump_file, STMT_VINFO_VECTYPE (stmt_info)); ++ fprintf (dump_file, "\n"); ++ } + + gcall *call_stmt = dyn_cast (stmt); + if (call_stmt) +@@ -1575,10 +1592,10 @@ vect_build_slp_tree (vec_info *vinfo, + dump_printf_loc (MSG_NOTE, vect_location, + "SLP discovery for node %p succeeded\n", res); + gcc_assert (res_ == res); +- res->max_nunits = this_max_nunits; ++ res_->max_nunits = this_max_nunits; + vect_update_max_nunits (max_nunits, this_max_nunits); + /* Keep a reference for the bst_map use. */ +- SLP_TREE_REF_COUNT (res)++; ++ SLP_TREE_REF_COUNT (res_)++; + } + return res_; + } +@@ -3190,8 +3207,10 @@ vect_build_slp_instance (vec_info *vinfo, + + /* For basic block SLP, try to break the group up into multiples of + a vector size. */ ++ bb_vec_info bb_vinfo = dyn_cast (vinfo); + if (is_a (vinfo) +- && (i > 1 && i < group_size)) ++ && (i > 1 && i < group_size) ++ && !bb_vinfo->transposed) + { + tree scalar_type + = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info))); +@@ -3301,84 +3320,1034 @@ vect_analyze_slp_instance (vec_info *vinfo, + scalar_stmts.create (DR_GROUP_SIZE (stmt_info)); + while (next_info) + { +- scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info)); +- next_info = DR_GROUP_NEXT_ELEMENT (next_info); ++ scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info)); ++ next_info = DR_GROUP_NEXT_ELEMENT (next_info); ++ } ++ } ++ else if (kind == slp_inst_kind_reduc_chain) ++ { ++ /* Collect the reduction stmts and store them in scalar_stmts. */ ++ scalar_stmts.create (REDUC_GROUP_SIZE (stmt_info)); ++ while (next_info) ++ { ++ scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info)); ++ next_info = REDUC_GROUP_NEXT_ELEMENT (next_info); ++ } ++ /* Mark the first element of the reduction chain as reduction to properly ++ transform the node. In the reduction analysis phase only the last ++ element of the chain is marked as reduction. */ ++ STMT_VINFO_DEF_TYPE (stmt_info) ++ = STMT_VINFO_DEF_TYPE (scalar_stmts.last ()); ++ STMT_VINFO_REDUC_DEF (vect_orig_stmt (stmt_info)) ++ = STMT_VINFO_REDUC_DEF (vect_orig_stmt (scalar_stmts.last ())); ++ } ++ else if (kind == slp_inst_kind_ctor) ++ { ++ tree rhs = gimple_assign_rhs1 (stmt_info->stmt); ++ tree val; ++ scalar_stmts.create (CONSTRUCTOR_NELTS (rhs)); ++ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val) ++ { ++ stmt_vec_info def_info = vinfo->lookup_def (val); ++ def_info = vect_stmt_to_vectorize (def_info); ++ scalar_stmts.quick_push (def_info); ++ } ++ if (dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Analyzing vectorizable constructor: %G\n", ++ stmt_info->stmt); ++ } ++ else if (kind == slp_inst_kind_reduc_group) ++ { ++ /* Collect reduction statements. */ ++ const vec &reductions ++ = as_a (vinfo)->reductions; ++ scalar_stmts.create (reductions.length ()); ++ for (i = 0; reductions.iterate (i, &next_info); i++) ++ if ((STMT_VINFO_RELEVANT_P (next_info) ++ || STMT_VINFO_LIVE_P (next_info)) ++ /* ??? Make sure we didn't skip a conversion around a reduction ++ path. In that case we'd have to reverse engineer that conversion ++ stmt following the chain using reduc_idx and from the PHI ++ using reduc_def. */ ++ && STMT_VINFO_DEF_TYPE (next_info) == vect_reduction_def) ++ scalar_stmts.quick_push (next_info); ++ /* If less than two were relevant/live there's nothing to SLP. */ ++ if (scalar_stmts.length () < 2) ++ return false; ++ } ++ else ++ gcc_unreachable (); ++ ++ vec roots = vNULL; ++ if (kind == slp_inst_kind_ctor) ++ { ++ roots.create (1); ++ roots.quick_push (stmt_info); ++ } ++ /* Build the tree for the SLP instance. */ ++ bool res = vect_build_slp_instance (vinfo, kind, scalar_stmts, ++ roots, ++ max_tree_size, limit, bst_map, ++ kind == slp_inst_kind_store ++ ? stmt_info : NULL); ++ if (!res) ++ roots.release (); ++ ++ /* ??? If this is slp_inst_kind_store and the above succeeded here's ++ where we should do store group splitting. */ ++ ++ return res; ++} ++ ++static inline bool ++is_const_assign (stmt_vec_info store_elem) ++{ ++ if (store_elem == NULL) ++ { ++ gcc_unreachable (); ++ } ++ gimple *stmt = store_elem->stmt; ++ gimple_rhs_class rhs_class = gimple_assign_rhs_class (stmt); ++ return rhs_class == GIMPLE_SINGLE_RHS ++ && TREE_CONSTANT (gimple_assign_rhs1 (store_elem->stmt)); ++} ++ ++/* Push inits to INNERMOST_INITS and check const assign. */ ++ ++static bool ++record_innermost (vec &innermost_inits, ++ vec &innermost_offsets, ++ stmt_vec_info stmt_vinfo) ++{ ++ if (!stmt_vinfo) ++ { ++ return false; ++ } ++ stmt_vec_info next_info = stmt_vinfo; ++ while (next_info) ++ { ++ /* No need to vectorize constant assign in a transposed version. */ ++ if (is_const_assign (next_info)) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "no need to vectorize, store is const assign: %G", ++ next_info->stmt); ++ } ++ return false; ++ } ++ innermost_inits.safe_push (STMT_VINFO_DR_INIT (next_info)); ++ innermost_offsets.safe_push (STMT_VINFO_DR_OFFSET (next_info)); ++ next_info = DR_GROUP_NEXT_ELEMENT (next_info); ++ } ++ return true; ++} ++ ++/* Compare inits to INNERMOST_INITS, return FALSE if inits do not match ++ the first grouped_store. And check const assign meanwhile. */ ++ ++static bool ++compare_innermost (const vec &innermost_inits, ++ const vec &innermost_offsets, ++ stmt_vec_info stmt_vinfo) ++{ ++ if (!stmt_vinfo || innermost_inits.length () != stmt_vinfo->size) ++ { ++ return false; ++ } ++ stmt_vec_info next_info = stmt_vinfo; ++ unsigned int i = 0; ++ while (next_info) ++ { ++ if (is_const_assign (next_info)) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "no need to vectorize, store is const " ++ "assign: %G", next_info->stmt); ++ } ++ return false; ++ } ++ if (innermost_inits[i] != STMT_VINFO_DR_INIT (next_info) ++ || innermost_offsets[i] != STMT_VINFO_DR_OFFSET (next_info)) ++ { ++ return false; ++ } ++ next_info = DR_GROUP_NEXT_ELEMENT (next_info); ++ i++; ++ } ++ return true; ++} ++ ++static bool ++check_same_bb (stmt_vec_info grp1, stmt_vec_info grp2) ++{ ++ if (grp1->stmt->bb->index == grp2->stmt->bb->index) ++ { ++ return true; ++ } ++ return false; ++} ++ ++/* Check if grouped stores are of same type. ++ input: t1/t2 = TREE_TYPE (gimple_assign_lhs (first_element->stmt)) ++ output: 0 if same, 1 or -1 else. */ ++ ++static int ++tree_type_cmp (const tree t1, const tree t2) ++{ ++ gcc_checking_assert (t1 != NULL && t2 != NULL); ++ if (t1 != t2) ++ { ++ if (TREE_CODE (t1) != TREE_CODE (t2)) ++ { ++ return TREE_CODE (t1) > TREE_CODE (t2) ? 1 : -1; ++ } ++ if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) ++ { ++ return TYPE_UNSIGNED (t1) > TYPE_UNSIGNED (t2) ? 1 : -1; ++ } ++ if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2)) ++ { ++ return TYPE_PRECISION (t1) > TYPE_PRECISION (t2) ? 1 : -1; ++ } ++ } ++ return 0; ++} ++ ++/* Check it if 2 grouped stores are of same type that ++ we can analyze them in a transpose group. */ ++static int ++check_same_store_type (stmt_vec_info grp1, stmt_vec_info grp2) ++{ ++ if (grp1 == grp2) ++ { ++ return 0; ++ } ++ if (grp1->size != grp2->size) ++ { ++ return grp1->size > grp2->size ? 1 : -1; ++ } ++ tree lhs1 = gimple_assign_lhs (grp1->stmt); ++ tree lhs2 = gimple_assign_lhs (grp2->stmt); ++ if (TREE_CODE (lhs1) != TREE_CODE (lhs2)) ++ { ++ return TREE_CODE (lhs1) > TREE_CODE (lhs2) ? 1 : -1; ++ } ++ tree grp_type1 = TREE_TYPE (gimple_assign_lhs (grp1->stmt)); ++ tree grp_type2 = TREE_TYPE (gimple_assign_lhs (grp2->stmt)); ++ int cmp = tree_type_cmp (grp_type1, grp_type2); ++ return cmp; ++} ++ ++/* Sort grouped stores according to group_size and store_type. ++ output: 0 if same, 1 if grp1 > grp2, -1 otherwise. */ ++ ++static int ++grouped_store_cmp (const void *grp1_, const void *grp2_) ++{ ++ stmt_vec_info grp1 = *(stmt_vec_info *)const_cast(grp1_); ++ stmt_vec_info grp2 = *(stmt_vec_info *)const_cast(grp2_); ++ return check_same_store_type (grp1, grp2); ++} ++ ++/* Transposing is based on permutation in registers. Permutation requires ++ vector length being power of 2 and satisfying the vector mode. */ ++ ++static inline bool ++check_filling_reg (stmt_vec_info current_element) ++{ ++ if (current_element->size == 0) ++ { ++ return false; ++ } ++ /* If the gimple STMT was already vectorized in vect pass, it's unable to ++ conduct transpose analysis, skip it. */ ++ bool lhs_vectorized ++ = TREE_CODE (TREE_TYPE (gimple_get_lhs (current_element->stmt))) ++ == VECTOR_TYPE; ++ bool rhs_vectorized ++ = TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (current_element->stmt))) ++ == VECTOR_TYPE; ++ if (lhs_vectorized || rhs_vectorized) ++ { ++ return false; ++ } ++ unsigned int store_precision ++ = TYPE_PRECISION (TREE_TYPE (gimple_get_lhs (current_element->stmt))); ++ auto_vector_modes vector_modes; ++ targetm.vectorize.autovectorize_vector_modes (&vector_modes, false); ++ unsigned min_mode_size = -1u; ++ for (unsigned i = 0; i < vector_modes.length (); i++) ++ { ++ unsigned mode_bit_size = (GET_MODE_BITSIZE (vector_modes[i])).coeffs[0]; ++ min_mode_size = mode_bit_size < min_mode_size ++ ? mode_bit_size : min_mode_size; ++ } ++ return store_precision != 0 ++ && pow2p_hwi (current_element->size) ++ && (current_element->size * store_precision % min_mode_size == 0); ++} ++ ++/* Check if previous groups are suitable to transpose, if not, set their ++ group number to -1, reduce grp_num and clear current_groups. ++ Otherwise, just clear current_groups. */ ++ ++static void ++check_and_clear_groups (vec ¤t_groups, ++ unsigned int &grp_num) ++{ ++ stmt_vec_info first_element; ++ if (current_groups.length () == 1 ++ || (current_groups.length () != 0 ++ && !pow2p_hwi (current_groups.length ()))) ++ { ++ while (current_groups.length () != 0) ++ { ++ first_element = current_groups.pop (); ++ first_element->group_number = -1; ++ } ++ grp_num--; ++ } ++ else ++ { ++ while (current_groups.length ()) ++ { ++ current_groups.pop (); ++ } ++ } ++} ++ ++ ++/* Make sure that transpose slp vectorization is conducted only if grouped ++ stores are one dimension array ref. */ ++ ++static bool ++is_store_one_dim_array (gimple *stmt) ++{ ++ tree op = gimple_get_lhs (stmt); ++ if (TREE_CODE (op) != ARRAY_REF) ++ return false; ++ return TREE_OPERAND_LENGTH (op) > 0 ++ && TREE_OPERAND_LENGTH (TREE_OPERAND (op, 0)) == 0; ++} ++ ++/* Set grouped_stores with similar MEM_REF to the same group and mark their ++ grp_num. Groups with same grp_num consist the minimum unit to analyze ++ transpose. Return num of such units. */ ++ ++static unsigned ++vect_prepare_transpose (bb_vec_info bb_vinfo) ++{ ++ stmt_vec_info current_element = NULL; ++ stmt_vec_info first_element = NULL; ++ unsigned int i = 0; ++ unsigned int grp_num = 0; ++ /* Use arrays to record MEM_REF data in different GROUPED_STORES. */ ++ auto_vec innermost_inits; ++ auto_vec innermost_offsets; ++ ++ /* A set of stmt_vec_info with same store type. Analyze them if their size ++ is suitable to transpose. */ ++ auto_vec current_groups; ++ ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_stores, i, current_element) ++ { ++ /* Compare current grouped_store to the first one if first_element exists, ++ push current_element to current_groups if they are similar on innermost ++ behavior of MEM_REF. */ ++ if (first_element != NULL ++ && !check_same_store_type (first_element, current_element) ++ && compare_innermost (innermost_inits, innermost_offsets, ++ current_element) ++ && check_same_bb (first_element, current_element)) ++ { ++ current_groups.safe_push (current_element); ++ current_element->group_number = grp_num; ++ /* If current_element is the last element in grouped_stores, continue ++ will exit the loop and leave the last group unanalyzed. */ ++ if (i == bb_vinfo->grouped_stores.length () - 1) ++ { ++ check_and_clear_groups (current_groups, grp_num); ++ } ++ continue; ++ } ++ check_and_clear_groups (current_groups, grp_num); ++ innermost_inits.release (); ++ innermost_offsets.release (); ++ /* Beginning of a new group to analyze whether they are able to consist ++ a unit to conduct transpose analysis. */ ++ first_element = NULL; ++ if (is_store_one_dim_array (current_element->stmt) ++ && check_filling_reg (current_element) ++ && record_innermost (innermost_inits, innermost_offsets, ++ current_element)) ++ { ++ first_element = current_element; ++ current_groups.safe_push (current_element); ++ current_element->group_number = ++grp_num; ++ if (i == bb_vinfo->grouped_stores.length () - 1) ++ { ++ check_and_clear_groups (current_groups, grp_num); ++ } ++ continue; ++ } ++ current_element->group_number = -1; ++ } ++ return grp_num; ++} ++ ++/* Return a flag to transpose grouped stores before building slp tree. ++ Add bool may_transpose in class vec_info. */ ++ ++static bool ++vect_may_transpose (bb_vec_info bb_vinfo) ++{ ++ if (targetm.vectorize.vec_perm_const == NULL) ++ { ++ return false; ++ } ++ ++ if (bb_vinfo->grouped_stores.length () < 2) ++ { ++ return false; ++ } ++ ++ DUMP_VECT_SCOPE ("analyze if grouped stores may transpose to slp"); ++ /* Sort grouped_stores according to size and type for function ++ vect_prepare_transpose (). */ ++ bb_vinfo->grouped_stores.qsort (grouped_store_cmp); ++ ++ int groups = vect_prepare_transpose (bb_vinfo); ++ BB_VINFO_TRANS_GROUPS (bb_vinfo) = groups; ++ if (dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "%d groups to analyze transposed slp.\n", groups); ++ return groups != 0; ++} ++ ++/* Get the base address of STMT_INFO. */ ++ ++static tree ++get_op_base_address (stmt_vec_info stmt_info) ++{ ++ struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); ++ tree op = DR_BASE_ADDRESS (dr); ++ while (TREE_OPERAND_LENGTH (op) > 0) ++ { ++ op = TREE_OPERAND (op, 0); ++ } ++ return op; ++} ++ ++/* Compare the UID of the two stmt_info STMTINFO_A and STMTINFO_B. ++ Sorting them in ascending order. */ ++ ++static int ++dr_group_cmp (const void *stmtinfo_a_, const void *stmtinfo_b_) ++{ ++ stmt_vec_info stmtinfo_a ++ = *(stmt_vec_info *) const_cast (stmtinfo_a_); ++ stmt_vec_info stmtinfo_b ++ = *(stmt_vec_info *) const_cast (stmtinfo_b_); ++ ++ /* Stabilize sort. */ ++ if (stmtinfo_a == stmtinfo_b) ++ { ++ return 0; ++ } ++ return gimple_uid (stmtinfo_a->stmt) < gimple_uid (stmtinfo_b->stmt) ? -1 : 1; ++} ++ ++/* Find the first elements of the grouped loads which are required to merge. */ ++ ++static void ++vect_slp_grouped_load_find (bb_vec_info bb_vinfo, vec &visited, ++ vec &res) ++{ ++ unsigned int i = 0; ++ stmt_vec_info merge_first_element = NULL; ++ stmt_vec_info first_element = NULL; ++ tree opa = NULL; ++ unsigned int grp_size_a = 0; ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_loads, i, first_element) ++ { ++ if (visited[i]) ++ { ++ continue; ++ } ++ if (!STMT_VINFO_GROUPED_ACCESS (first_element) ++ || !pow2p_hwi (DR_GROUP_SIZE (first_element))) ++ { ++ /* Non-conforming grouped load should be grouped separately. */ ++ if (merge_first_element == NULL) ++ { ++ visited[i] = true; ++ res.safe_push (first_element); ++ return; ++ } ++ } ++ if (merge_first_element == NULL) ++ { ++ merge_first_element = first_element; ++ opa = get_op_base_address (first_element); ++ grp_size_a = DR_GROUP_SIZE (first_element); ++ res.safe_push (first_element); ++ visited[i] = true; ++ continue; ++ } ++ ++ /* If the two first elements are of the same base address and group size, ++ these two grouped loads need to be merged. */ ++ tree opb = get_op_base_address (first_element); ++ unsigned int grp_size_b = DR_GROUP_SIZE (first_element); ++ if (opa == opb && grp_size_a == grp_size_b) ++ { ++ res.safe_push (first_element); ++ visited[i] = true; ++ } ++ } ++} ++ ++/* Merge the grouped loads that are found from ++ vect_slp_grouped_load_find (). */ ++ ++static stmt_vec_info ++vect_slp_grouped_load_merge (vec &res) ++{ ++ stmt_vec_info stmt_info = res[0]; ++ if (res.length () == 1) ++ { ++ return stmt_info; ++ } ++ unsigned int i = 0; ++ unsigned int size = DR_GROUP_SIZE (res[0]); ++ unsigned int new_group_size = size * res.length (); ++ stmt_vec_info first_element = NULL; ++ stmt_vec_info merge_first_element = NULL; ++ stmt_vec_info last_element = NULL; ++ FOR_EACH_VEC_ELT (res, i, first_element) ++ { ++ if (merge_first_element == NULL) ++ { ++ merge_first_element = first_element; ++ last_element = merge_first_element; ++ size = DR_GROUP_SIZE (merge_first_element); ++ } ++ ++ if (last_element != first_element ++ && !DR_GROUP_NEXT_ELEMENT (last_element)) ++ { ++ DR_GROUP_NEXT_ELEMENT (last_element) = first_element; ++ /* Store the gap from the previous member of the group. If there is ++ no gap in the access, DR_GROUP_GAP is always 1. */ ++ DR_GROUP_GAP_TRANS (first_element) = DR_GROUP_GAP (first_element); ++ DR_GROUP_GAP (first_element) = 1; ++ } ++ for (stmt_info = first_element; stmt_info; ++ stmt_info = DR_GROUP_NEXT_ELEMENT (stmt_info)) ++ { ++ DR_GROUP_FIRST_ELEMENT (stmt_info) = merge_first_element; ++ DR_GROUP_SIZE_TRANS (stmt_info) = DR_GROUP_SIZE (stmt_info); ++ DR_GROUP_SIZE (stmt_info) = new_group_size; ++ last_element = stmt_info; ++ } ++ } ++ DR_GROUP_SIZE (merge_first_element) = new_group_size; ++ DR_GROUP_SLP_TRANSPOSE (merge_first_element) = true; ++ DR_GROUP_NEXT_ELEMENT (last_element) = NULL; ++ return merge_first_element; ++} ++ ++/* Merge the grouped loads which have the same base address and group size. ++ For example, for grouped loads (opa_1, opa_2, opb_1, opb_2): ++ opa_1: a0->a1->a2->a3 ++ opa_2: a8->a9->a10->a11 ++ opb_1: b0->b1 ++ opb_2: b16->b17 ++ we can probably get two merged grouped loads: ++ opa: a0->a1->a2->a3->a8->a9->a10->a11 ++ opb: b0->b1->b16->b17. */ ++ ++static bool ++vect_merge_slp_grouped_loads (bb_vec_info bb_vinfo) ++{ ++ if (bb_vinfo->grouped_loads.length () <= 0) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "The number of grouped loads is 0.\n"); ++ } ++ return false; ++ } ++ bb_vinfo->grouped_loads.qsort (dr_group_cmp); ++ auto_vec visited (bb_vinfo->grouped_loads.length ()); ++ auto_vec grouped_loads_merge; ++ for (unsigned int i = 0; i < bb_vinfo->grouped_loads.length (); i++) ++ { ++ visited.safe_push (false); ++ } ++ while (1) ++ { ++ /* Find grouped loads which are required to merge. */ ++ auto_vec res; ++ vect_slp_grouped_load_find (bb_vinfo, visited, res); ++ if (res.is_empty ()) ++ { ++ break; ++ } ++ /* Merge the required grouped loads into one group. */ ++ grouped_loads_merge.safe_push (vect_slp_grouped_load_merge (res)); ++ } ++ if (grouped_loads_merge.length () == bb_vinfo->grouped_loads.length ()) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "No grouped loads need to be merged.\n"); ++ } ++ return false; ++ } ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Merging grouped loads successfully.\n"); ++ } ++ BB_VINFO_GROUPED_LOADS (bb_vinfo).release (); ++ for (unsigned int i = 0; i < grouped_loads_merge.length (); i++) ++ { ++ BB_VINFO_GROUPED_LOADS (bb_vinfo).safe_push (grouped_loads_merge[i]); ++ } ++ return true; ++} ++ ++/* Find the first elements of the grouped stores ++ which are required to transpose and merge. */ ++ ++static void ++vect_slp_grouped_store_find (bb_vec_info bb_vinfo, vec &visited, ++ vec &res) ++{ ++ stmt_vec_info first_element = NULL; ++ stmt_vec_info merge_first_element = NULL; ++ unsigned int k = 0; ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_stores, k, first_element) ++ { ++ if (visited[k]) ++ { ++ continue; ++ } ++ /* Non-conforming grouped store should be grouped separately. */ ++ if (!STMT_VINFO_GROUPED_ACCESS (first_element) ++ || first_element->group_number == -1) ++ { ++ if (merge_first_element == NULL) ++ { ++ visited[k] = true; ++ res.safe_push (first_element); ++ return; ++ } ++ } ++ if (first_element->group_number != -1 ++ && merge_first_element == NULL) ++ { ++ merge_first_element = first_element; ++ } ++ if (merge_first_element->group_number == first_element->group_number) ++ { ++ visited[k] = true; ++ res.safe_push (first_element); ++ } ++ } ++} ++ ++/* Transpose and merge the grouped stores that are found from ++ vect_slp_grouped_store_find (). */ ++ ++static stmt_vec_info ++vect_slp_grouped_store_transform (vec &res) ++{ ++ stmt_vec_info stmt_info = res[0]; ++ if (res.length () == 1) ++ { ++ return stmt_info; ++ } ++ stmt_vec_info rearrange_first_element = stmt_info; ++ stmt_vec_info last_element = rearrange_first_element; ++ ++ unsigned int size = DR_GROUP_SIZE (rearrange_first_element); ++ unsigned int new_group_size = size * res.length (); ++ for (unsigned int i = 1; i < res.length (); i++) ++ { ++ /* Store the gap from the previous member of the group. If there is no ++ gap in the access, DR_GROUP_GAP is always 1. */ ++ DR_GROUP_GAP_TRANS (res[i]) = DR_GROUP_GAP (res[i]); ++ DR_GROUP_GAP (res[i]) = 1; ++ } ++ while (!res.is_empty ()) ++ { ++ stmt_info = res[0]; ++ res.ordered_remove (0); ++ if (DR_GROUP_NEXT_ELEMENT (stmt_info)) ++ { ++ res.safe_push (DR_GROUP_NEXT_ELEMENT (stmt_info)); ++ } ++ DR_GROUP_FIRST_ELEMENT (stmt_info) = rearrange_first_element; ++ DR_GROUP_NEXT_ELEMENT (last_element) = stmt_info; ++ DR_GROUP_SIZE_TRANS (stmt_info) = DR_GROUP_SIZE (stmt_info); ++ DR_GROUP_SIZE (stmt_info) = new_group_size; ++ last_element = stmt_info; ++ } ++ ++ DR_GROUP_SIZE (rearrange_first_element) = new_group_size; ++ DR_GROUP_SLP_TRANSPOSE (rearrange_first_element) = true; ++ DR_GROUP_NEXT_ELEMENT (last_element) = NULL; ++ return rearrange_first_element; ++} ++ ++/* Save the STMT_INFO in the grouped stores to BB_VINFO_SCALAR_STORES for ++ transposing back grouped stores. */ ++ ++static void ++get_scalar_stores (bb_vec_info bb_vinfo) ++{ ++ unsigned int k = 0; ++ stmt_vec_info first_element = NULL; ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_stores, k, first_element) ++ { ++ /* Filter the grouped store which is unnecessary for transposing. */ ++ if (!STMT_VINFO_GROUPED_ACCESS (first_element) ++ || first_element->group_number == -1) ++ { ++ continue; ++ } ++ vec tmp_scalar_store; ++ tmp_scalar_store.create (DR_GROUP_SIZE (first_element)); ++ for (stmt_vec_info stmt_info = first_element; stmt_info; ++ stmt_info = DR_GROUP_NEXT_ELEMENT (stmt_info)) ++ { ++ tmp_scalar_store.safe_push (stmt_info); ++ } ++ BB_VINFO_SCALAR_STORES (bb_vinfo).safe_push (tmp_scalar_store); ++ } ++} ++ ++/* Transpose and merge the grouped stores which have the same group number. ++ For example, for grouped stores (opa_0, opa_1, opa_2, opa_3): ++ opa_0: a00->a01->a02->a03 ++ opa_1: a10->a11->a12->a13 ++ opa_2: a20->a21->a22->a23 ++ opa_2: a30->a31->a32->a33 ++ we can probably get the merged grouped store: ++ opa: a00->a10->a20->a30 ++ ->a01->a11->a21->a31 ++ ->a02->a12->a22->a32 ++ ->a03->a13->a23->a33. */ ++ ++static bool ++vect_transform_slp_grouped_stores (bb_vec_info bb_vinfo) ++{ ++ if (bb_vinfo->grouped_stores.length () <= 0) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "The number of grouped stores is 0.\n"); ++ } ++ return false; ++ } ++ ++ bb_vinfo->grouped_stores.qsort (dr_group_cmp); ++ auto_vec grouped_stores_merge; ++ auto_vec visited (bb_vinfo->grouped_stores.length ()); ++ unsigned int i = 0; ++ for (i = 0; i < bb_vinfo->grouped_stores.length (); i++) ++ { ++ visited.safe_push (false); ++ } ++ ++ /* Get scalar stores for the following transposition recovery. */ ++ get_scalar_stores (bb_vinfo); ++ ++ while (1) ++ { ++ /* Find grouped stores which are required to transpose and merge. */ ++ auto_vec res; ++ vect_slp_grouped_store_find (bb_vinfo, visited, res); ++ if (res.is_empty ()) ++ { ++ break; ++ } ++ /* Transpose and merge the required grouped stores into one group. */ ++ grouped_stores_merge.safe_push (vect_slp_grouped_store_transform (res)); ++ } ++ ++ BB_VINFO_GROUPED_STORES (bb_vinfo).release (); ++ for (i = 0; i < grouped_stores_merge.length (); i++) ++ { ++ BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (grouped_stores_merge[i]); ++ } ++ ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Transposing grouped stores successfully.\n"); ++ } ++ return true; ++} ++ ++/* A helpful function of vect_transform_back_slp_grouped_stores (). */ ++ ++static auto_vec ++vect_transform_back_slp_grouped_store (bb_vec_info bb_vinfo, ++ stmt_vec_info first_stmt_info) ++{ ++ auto_vec grouped_stores_split; ++ for (unsigned int i = 0; i < bb_vinfo->scalar_stores.length (); i++) ++ { ++ vec scalar_tmp = bb_vinfo->scalar_stores[i]; ++ if (scalar_tmp.length () > 1 ++ && scalar_tmp[0]->group_number != first_stmt_info->group_number) ++ { ++ continue; ++ } ++ stmt_vec_info cur_stmt_info = NULL; ++ stmt_vec_info cur_first_stmt_info = NULL; ++ stmt_vec_info last_stmt_info = NULL; ++ unsigned int k = 0; ++ FOR_EACH_VEC_ELT (scalar_tmp, k, cur_stmt_info) ++ { ++ if (k == 0) ++ { ++ cur_first_stmt_info = cur_stmt_info; ++ last_stmt_info = cur_stmt_info; ++ } ++ DR_GROUP_FIRST_ELEMENT (cur_stmt_info) = cur_first_stmt_info; ++ DR_GROUP_NEXT_ELEMENT (last_stmt_info) = cur_stmt_info; ++ last_stmt_info = cur_stmt_info; ++ } ++ DR_GROUP_SIZE (cur_first_stmt_info) = k; ++ DR_GROUP_NEXT_ELEMENT (last_stmt_info) = NULL; ++ if (first_stmt_info != cur_first_stmt_info) ++ { ++ DR_GROUP_GAP (cur_first_stmt_info) ++ = DR_GROUP_GAP_TRANS (cur_first_stmt_info); ++ DR_GROUP_SLP_TRANSPOSE (cur_first_stmt_info) = false; ++ DR_GROUP_NUMBER (cur_first_stmt_info) = -1; ++ } ++ grouped_stores_split.safe_push (cur_first_stmt_info); ++ } ++ return grouped_stores_split; ++} ++ ++/* Transform the grouped store back. */ ++ ++void ++vect_transform_back_slp_grouped_stores (bb_vec_info bb_vinfo, ++ stmt_vec_info first_stmt_info) ++{ ++ if (first_stmt_info->group_number == -1) ++ { ++ return; ++ } ++ /* Transform back. */ ++ auto_vec grouped_stores_split ++ = vect_transform_back_slp_grouped_store (bb_vinfo, first_stmt_info); ++ ++ /* Add the remaining grouped stores to grouped_stores_split. */ ++ stmt_vec_info first_element = NULL; ++ unsigned int i = 0; ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_stores, i, first_element) ++ { ++ if (first_element->group_number != first_stmt_info->group_number) ++ { ++ grouped_stores_split.safe_push (first_element); ++ } ++ } ++ DR_GROUP_SLP_TRANSPOSE (first_stmt_info) = false; ++ DR_GROUP_NUMBER (first_stmt_info) = -1; ++ BB_VINFO_GROUPED_STORES (bb_vinfo).release (); ++ for (i = 0; i < grouped_stores_split.length (); i++) ++ { ++ BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (grouped_stores_split[i]); ++ } ++} ++ ++/* Function check_for_slp_vectype ++ ++ Restriction for grouped stores by checking their vectype. ++ If the vectype of the grouped store is changed, it need transform back. ++ If all grouped stores need to be transformed back, return FALSE. */ ++ ++static bool ++check_for_slp_vectype (bb_vec_info bb_vinfo) ++{ ++ if (dump_file) ++ fprintf (dump_file, "check_for_slp_vectype: enter\n"); ++ stmt_vec_info first_element = NULL; ++ unsigned int i = 0; ++ int count = 0; ++ auto_vec grouped_stores_check; ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_stores, i, first_element) ++ { ++ grouped_stores_check.safe_push (first_element); ++ } ++ FOR_EACH_VEC_ELT (grouped_stores_check, i, first_element) ++ { ++ if (STMT_VINFO_GROUPED_ACCESS (first_element) ++ && first_element->group_number != -1) ++ { ++ unsigned int group_size_b ++ = DR_GROUP_SIZE_TRANS (first_element); ++ tree vectype = STMT_VINFO_VECTYPE (first_element); ++ gimple *stmt = STMT_VINFO_STMT (first_element); ++ tree lhs = gimple_get_lhs (stmt); ++ tree type = TREE_TYPE (lhs); ++#if 0 ++ if (!vectype && !type) ++ { ++ if (dump_file) ++ fprintf (dump_file, "check_for_slp_vectype: no vectype/stmt type\n"); ++ continue; ++ } ++ ++ if (!vectype) ++ vectype = type; ++#endif ++ if (dump_file) ++ { ++ fprintf (dump_file, "check_for_slp_vectype: %p\n", first_element); ++ print_gimple_stmt (dump_file, stmt, 0); ++ fprintf (dump_file, "check_for_slp_vectype: vectype="); ++ if (vectype) ++ print_generic_expr (dump_file, vectype); ++ fprintf (dump_file, "\n"); ++ } ++#if 0 ++ if (!vectype || !VECTOR_TYPE_P (vectype)) ++ continue; ++#endif ++ poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); ++ if (nunits.to_constant () > group_size_b) ++ { ++ count++; ++ /* If the vectype is changed, this grouped store need ++ to be transformed back. */ ++ vect_transform_back_slp_grouped_stores (bb_vinfo, first_element); ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "No supported: only supported for" ++ " group_size geq than nunits.\n"); ++ } ++ } ++ } ++ } ++ if (count == BB_VINFO_TRANS_GROUPS (bb_vinfo)) ++ { ++ return false; ++ } ++ if (dump_file) ++ fprintf (dump_file, "check_for_slp_vectype: True\n"); ++ return true; ++} ++ ++/* Function check_for_dr_alignment ++ ++ Check the alignment of the slp instance loads. ++ Return FALSE if a load cannot be vectorized. */ ++ ++static bool ++check_for_dr_alignment (bb_vec_info bb_vinfo, slp_instance instance) ++{ ++ slp_tree node = NULL; ++ unsigned int i = 0; ++ FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, node) ++ { ++ stmt_vec_info first_stmt_info = SLP_TREE_SCALAR_STMTS (node)[0]; ++ dr_vec_info *first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info); ++ if (dump_file) ++ { ++ fprintf (dump_file, "check_for_dr_alignment: %p\n", first_stmt_info); ++ ++ gimple *stmt = STMT_VINFO_STMT (first_stmt_info); ++ tree lhs = gimple_get_lhs (stmt); ++ tree type = TREE_TYPE (lhs); ++ print_gimple_stmt (dump_file, stmt, 0); ++ } ++ ++ tree vectype = STMT_VINFO_VECTYPE (first_stmt_info); ++ int malign = dr_misalignment (first_dr_info, vectype); ++ enum dr_alignment_support supportable_dr_alignment ++ = vect_supportable_dr_alignment (bb_vinfo, first_dr_info, ++ vectype, malign); ++ if (supportable_dr_alignment == dr_explicit_realign_optimized ++ || supportable_dr_alignment == dr_explicit_realign) ++ { ++ return false; + } + } +- else if (kind == slp_inst_kind_reduc_chain) ++ return true; ++} ++ ++/* Initialize slp_transpose flag before transposing. */ ++ ++static void ++init_stmt_info_slp_transpose (bb_vec_info bb_vinfo) ++{ ++ stmt_vec_info first_element = NULL; ++ unsigned int k = 0; ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_stores, k, first_element) + { +- /* Collect the reduction stmts and store them in scalar_stmts. */ +- scalar_stmts.create (REDUC_GROUP_SIZE (stmt_info)); +- while (next_info) ++ if (STMT_VINFO_GROUPED_ACCESS (first_element)) + { +- scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info)); +- next_info = REDUC_GROUP_NEXT_ELEMENT (next_info); ++ DR_GROUP_SLP_TRANSPOSE (first_element) = false; + } +- /* Mark the first element of the reduction chain as reduction to properly +- transform the node. In the reduction analysis phase only the last +- element of the chain is marked as reduction. */ +- STMT_VINFO_DEF_TYPE (stmt_info) +- = STMT_VINFO_DEF_TYPE (scalar_stmts.last ()); +- STMT_VINFO_REDUC_DEF (vect_orig_stmt (stmt_info)) +- = STMT_VINFO_REDUC_DEF (vect_orig_stmt (scalar_stmts.last ())); + } +- else if (kind == slp_inst_kind_ctor) ++ FOR_EACH_VEC_ELT (bb_vinfo->grouped_loads, k, first_element) + { +- tree rhs = gimple_assign_rhs1 (stmt_info->stmt); +- tree val; +- scalar_stmts.create (CONSTRUCTOR_NELTS (rhs)); +- FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val) ++ if (STMT_VINFO_GROUPED_ACCESS (first_element)) + { +- stmt_vec_info def_info = vinfo->lookup_def (val); +- def_info = vect_stmt_to_vectorize (def_info); +- scalar_stmts.quick_push (def_info); ++ DR_GROUP_SLP_TRANSPOSE (first_element) = false; + } +- if (dump_enabled_p ()) +- dump_printf_loc (MSG_NOTE, vect_location, +- "Analyzing vectorizable constructor: %G\n", +- stmt_info->stmt); + } +- else if (kind == slp_inst_kind_reduc_group) ++} ++ ++/* Analyze and transpose the stmts before building the SLP tree. */ ++ ++static bool ++vect_analyze_transpose (bb_vec_info bb_vinfo) ++{ ++ DUMP_VECT_SCOPE ("vect_analyze_transpose"); ++ ++ if (!vect_may_transpose (bb_vinfo)) + { +- /* Collect reduction statements. */ +- const vec &reductions +- = as_a (vinfo)->reductions; +- scalar_stmts.create (reductions.length ()); +- for (i = 0; reductions.iterate (i, &next_info); i++) +- if ((STMT_VINFO_RELEVANT_P (next_info) +- || STMT_VINFO_LIVE_P (next_info)) +- /* ??? Make sure we didn't skip a conversion around a reduction +- path. In that case we'd have to reverse engineer that conversion +- stmt following the chain using reduc_idx and from the PHI +- using reduc_def. */ +- && STMT_VINFO_DEF_TYPE (next_info) == vect_reduction_def) +- scalar_stmts.quick_push (next_info); +- /* If less than two were relevant/live there's nothing to SLP. */ +- if (scalar_stmts.length () < 2) +- return false; ++ return false; + } +- else +- gcc_unreachable (); + +- vec roots = vNULL; +- if (kind == slp_inst_kind_ctor) ++ /* For basic block SLP, try to merge the grouped stores and loads ++ into one group. */ ++ init_stmt_info_slp_transpose (bb_vinfo); ++ if (vect_transform_slp_grouped_stores (bb_vinfo) ++ && vect_merge_slp_grouped_loads (bb_vinfo)) + { +- roots.create (1); +- roots.quick_push (stmt_info); ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Analysis succeeded with SLP transposed.\n"); ++ } ++ return true; + } +- /* Build the tree for the SLP instance. */ +- bool res = vect_build_slp_instance (vinfo, kind, scalar_stmts, +- roots, +- max_tree_size, limit, bst_map, +- kind == slp_inst_kind_store +- ? stmt_info : NULL); +- if (!res) +- roots.release (); +- +- /* ??? If this is slp_inst_kind_store and the above succeeded here's +- where we should do store group splitting. */ +- +- return res; ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Analysis failed with SLP transposed.\n"); ++ } ++ return false; + } + + /* Check if there are stmts in the loop can be vectorized using SLP. Build SLP +@@ -4963,7 +5932,7 @@ vect_slp_analyze_operations (vec_info *vinfo) + /* Check we can vectorize the reduction. */ + || (SLP_INSTANCE_KIND (instance) == slp_inst_kind_bb_reduc + && !vectorizable_bb_reduc_epilogue (instance, &cost_vec))) +- { ++ { + slp_tree node = SLP_INSTANCE_TREE (instance); + stmt_vec_info stmt_info; + if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ()) +@@ -4975,7 +5944,7 @@ vect_slp_analyze_operations (vec_info *vinfo) + "removing SLP instance operations starting from: %G", + stmt_info->stmt); + vect_free_slp_instance (instance); +- vinfo->slp_instances.ordered_remove (i); ++ vinfo->slp_instances.ordered_remove (i); + cost_vec.release (); + while (!visited_vec.is_empty ()) + visited.remove (visited_vec.pop ()); +@@ -5204,7 +6173,7 @@ vect_bb_slp_scalar_cost (vec_info *vinfo, + gimple *orig_stmt = orig_stmt_info->stmt; + + /* If there is a non-vectorized use of the defs then the scalar +- stmt is kept live in which case we do not account it or any ++ stmt is kept live in which case we do not account it or any + required defs in the SLP children in the scalar cost. This + way we make the vectorization more costly when compared to + the scalar cost. */ +@@ -5481,7 +6450,11 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo, + + vec_outside_cost = vec_prologue_cost + vec_epilogue_cost; + +- if (dump_enabled_p ()) ++ BB_VINFO_VEC_INSIDE_COST (bb_vinfo) = vec_inside_cost; ++ BB_VINFO_VEC_OUTSIDE_COST (bb_vinfo) = vec_outside_cost; ++ BB_VINFO_SCALAR_COST (bb_vinfo) = scalar_cost; ++ ++ if (!unlimited_cost_model (NULL) && dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, + "Cost model analysis for part in loop %d:\n", sl); +@@ -5819,7 +6792,7 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, + if (!vect_analyze_data_refs (bb_vinfo, &min_vf, NULL)) + { + if (dump_enabled_p ()) +- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: unhandled data-ref in basic " + "block.\n"); + return false; +@@ -5854,6 +6827,22 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, + + vect_pattern_recog (bb_vinfo); + ++ /* Transpose grouped stores and loads for better vectorizable version. */ ++ if (bb_vinfo->transposed) ++ { ++ if (!vect_analyze_transpose (bb_vinfo)) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "not vectorized: unhandled slp transposed in " ++ "basic block.\n"); ++ } ++ return false; ++ } ++ } ++ bb_vinfo->before_slp = true; ++ + /* Update store groups from pattern processing. */ + vect_fixup_store_groups_with_patterns (bb_vinfo); + +@@ -5872,6 +6861,20 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, + return false; + } + ++ /* Check if the vectype is suitable for SLP transposed. */ ++ if (bb_vinfo->transposed && !check_for_slp_vectype (bb_vinfo)) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "Failed to SLP transposed in the basic block.\n"); ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "not vectorized: vectype is not suitable for " ++ "SLP transposed in basic block.\n"); ++ } ++ return false; ++ } ++ + /* Optimize permutations. */ + vect_optimize_slp (bb_vinfo); + +@@ -5914,6 +6917,27 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, + if (! BB_VINFO_SLP_INSTANCES (bb_vinfo).length ()) + return false; + ++ /* Check if the alignment is suitable for SLP transposed. */ ++ if (bb_vinfo->transposed) ++ { ++ for (i = 0; BB_VINFO_SLP_INSTANCES (bb_vinfo).iterate (i, &instance); i++) ++ { ++ if (!check_for_dr_alignment (bb_vinfo, instance)) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "Failed to SLP transposed in the basic " ++ "block.\n"); ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "not vectorized: alignment is not suitable " ++ "for SLP transposed in basic block.\n"); ++ } ++ return false; ++ } ++ } ++ } ++ + if (!vect_slp_analyze_operations (bb_vinfo)) + { + if (dump_enabled_p ()) +@@ -5923,7 +6947,88 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal, + } + + vect_bb_partition_graph (bb_vinfo); ++ return true; ++} ++ ++static bool ++may_new_transpose_bbvinfo (bb_vec_info bb_vinfo_ori, bool res_ori, ++ loop_p orig_loop) ++{ ++ /* If the flag is false or the slp analysis is broken before ++ vect_analyze_slp, we don't try to analyze the transposed SLP version. */ ++ if (!flag_tree_slp_transpose_vectorize ++ || !BB_VINFO_BEFORE_SLP (bb_vinfo_ori)) ++ { ++ return false; ++ } ++ ++ /* If the original bb_vinfo can't be vectorized, try to new a bb_vinfo ++ of the transposed version. */ ++ if (!res_ori) ++ { ++ return true; ++ } ++ ++ /* Caculate the cost of the original bb_vinfo. */ ++ if (unlimited_cost_model (NULL)) ++ { ++ vec &instances = BB_VINFO_SLP_INSTANCES (bb_vinfo_ori); ++ vect_bb_vectorization_profitable_p (bb_vinfo_ori, instances, orig_loop); ++ } ++ /* If the vec cost and scalar cost are not much difference (here we set the ++ threshold to 4), we try to new a bb_vinfo of the transposed version. */ ++ if (BB_VINFO_SCALAR_COST (bb_vinfo_ori) ++ < 4 * (BB_VINFO_VEC_INSIDE_COST (bb_vinfo_ori) ++ + BB_VINFO_VEC_OUTSIDE_COST (bb_vinfo_ori))) ++ { ++ return true; ++ } ++ return false; ++} + ++static bool ++may_choose_transpose_bbvinfo (bb_vec_info bb_vinfo_trans, bool res_trans, ++ bb_vec_info bb_vinfo_ori, bool res_ori, ++ loop_p orig_loop) ++{ ++ /* The original bb_vinfo is chosen if the transposed bb_vinfo ++ can't be vectorized. */ ++ if (!res_trans) ++ { ++ return false; ++ } ++ /* Caculate the cost of the transposed bb_vinfo. */ ++ if (unlimited_cost_model (NULL)) ++ { ++ vec &instances = BB_VINFO_SLP_INSTANCES (bb_vinfo_trans); ++ vect_bb_vectorization_profitable_p (bb_vinfo_trans, instances, ++ orig_loop); ++ } ++ int diff_bb_cost = -1; ++ int diff_bb_cost_trans = -1; ++ if (res_ori) ++ { ++ diff_bb_cost = BB_VINFO_SCALAR_COST (bb_vinfo_ori) ++ - BB_VINFO_VEC_INSIDE_COST (bb_vinfo_ori) ++ - BB_VINFO_VEC_OUTSIDE_COST (bb_vinfo_ori); ++ } ++ if (res_trans) ++ { ++ diff_bb_cost_trans = BB_VINFO_SCALAR_COST (bb_vinfo_trans) ++ - BB_VINFO_VEC_INSIDE_COST (bb_vinfo_trans) ++ - BB_VINFO_VEC_OUTSIDE_COST (bb_vinfo_trans); ++ } ++ /* The original bb_vinfo is chosen when one of the following conditions ++ is satisfied as follows: ++ 1) The cost of original version is better transposed version. ++ 2) The vec cost is similar to scalar cost in the transposed version. */ ++ if ((res_ori && res_trans && diff_bb_cost >= diff_bb_cost_trans) ++ || (res_trans && BB_VINFO_SCALAR_COST (bb_vinfo_trans) ++ <= (BB_VINFO_VEC_INSIDE_COST (bb_vinfo_trans) ++ + BB_VINFO_VEC_OUTSIDE_COST (bb_vinfo_trans)))) ++ { ++ return false; ++ } + return true; + } + +@@ -5937,6 +7042,7 @@ vect_slp_region (vec bbs, vec datarefs, + loop_p orig_loop) + { + bb_vec_info bb_vinfo; ++ bb_vec_info bb_vinfo_trans = NULL; + auto_vector_modes vector_modes; + + /* Autodetect first vector size we try. */ +@@ -5951,6 +7057,10 @@ vect_slp_region (vec bbs, vec datarefs, + { + bool vectorized = false; + bool fatal = false; ++ bool res_bb_vinfo_ori = false; ++ bool res_bb_vinfo_trans = false; ++ ++ /* New a bb_vinfo of the original version. */ + bb_vinfo = new _bb_vec_info (bbs, &shared); + + bool first_time_p = shared.datarefs.is_empty (); +@@ -5960,8 +7070,113 @@ vect_slp_region (vec bbs, vec datarefs, + else + bb_vinfo->shared->check_datarefs (); + bb_vinfo->vector_mode = next_vector_mode; ++ bb_vinfo->transposed = false; ++ bb_vinfo->before_slp = false; ++ ++ res_bb_vinfo_ori = vect_slp_analyze_bb_1 (bb_vinfo, n_stmts, fatal, ++ dataref_groups); ++ auto_vec profitable_subgraphs; ++ auto_vec profitable_subgraphs_trans; ++ for (slp_instance instance : BB_VINFO_SLP_INSTANCES (bb_vinfo)) ++ { ++ if (instance->subgraph_entries.is_empty ()) ++ continue; ++ ++ vect_location = instance->location (); ++ if (!unlimited_cost_model (NULL) ++ && !vect_bb_vectorization_profitable_p ++ (bb_vinfo, instance->subgraph_entries, orig_loop)) ++ { ++ if (dump_enabled_p ()) ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "not vectorized: vectorization is not " ++ "profitable.\n"); ++ continue; ++ } ++ if (res_bb_vinfo_ori) ++ { ++ if (!dbg_cnt (vect_slp)) ++ continue; ++ profitable_subgraphs.safe_push (instance); ++ } ++ } ++ ++ /* Analyze and new a transposed bb_vinfo. */ ++ if (may_new_transpose_bbvinfo (bb_vinfo, res_bb_vinfo_ori, orig_loop)) ++ { ++ bool fatal_trans = false; ++ bb_vinfo_trans ++ = new _bb_vec_info (bbs, &shared); ++ bool first_time_p = shared.datarefs.is_empty (); ++ BB_VINFO_DATAREFS (bb_vinfo_trans) = datarefs; ++ if (first_time_p) ++ { ++ bb_vinfo_trans->shared->save_datarefs (); ++ } ++ else ++ { ++ bb_vinfo_trans->shared->check_datarefs (); ++ } ++ bb_vinfo_trans->vector_mode = next_vector_mode; ++ bb_vinfo_trans->transposed = true; ++ bb_vinfo_trans->before_slp = false; ++ ++ res_bb_vinfo_trans ++ = vect_slp_analyze_bb_1 (bb_vinfo_trans, n_stmts, fatal_trans, ++ dataref_groups); ++ if (res_bb_vinfo_trans) ++ { ++ for (slp_instance instance : BB_VINFO_SLP_INSTANCES (bb_vinfo_trans)) ++ { ++ if (instance->subgraph_entries.is_empty ()) ++ continue; ++ ++ vect_location = instance->location (); ++ if (!unlimited_cost_model (NULL) ++ && !vect_bb_vectorization_profitable_p ++ (bb_vinfo_trans, instance->subgraph_entries, orig_loop)) ++ { ++ if (dump_enabled_p ()) ++ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ++ "not vectorized: transpose vectorization is not " ++ "profitable.\n"); ++ res_bb_vinfo_trans = false; ++ continue; ++ } ++ if (res_bb_vinfo_trans) ++ { ++ if (!dbg_cnt (vect_slp)) ++ continue; ++ profitable_subgraphs_trans.safe_push (instance); ++ } ++ } ++ } ++ if (may_choose_transpose_bbvinfo (bb_vinfo_trans, ++ res_bb_vinfo_trans, ++ bb_vinfo, res_bb_vinfo_ori, ++ orig_loop)) ++ { ++ bb_vinfo = bb_vinfo_trans; ++ fatal = fatal_trans; ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Basic block part vectorized " ++ "using transposed version.\n"); ++ } ++ } ++ else ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Basic block part vectorized " ++ "\n"); ++ } ++ } ++ } + +- if (vect_slp_analyze_bb_1 (bb_vinfo, n_stmts, fatal, dataref_groups)) ++ if (res_bb_vinfo_ori || res_bb_vinfo_trans) + { + if (dump_enabled_p ()) + { +@@ -5972,90 +7187,129 @@ vect_slp_region (vec bbs, vec datarefs, + } + + bb_vinfo->shared->check_datarefs (); +- +- auto_vec profitable_subgraphs; +- for (slp_instance instance : BB_VINFO_SLP_INSTANCES (bb_vinfo)) ++ if (!res_bb_vinfo_trans) + { +- if (instance->subgraph_entries.is_empty ()) +- continue; +- +- vect_location = instance->location (); +- if (!unlimited_cost_model (NULL) +- && !vect_bb_vectorization_profitable_p +- (bb_vinfo, instance->subgraph_entries, orig_loop)) ++ /* When we're vectorizing an if-converted loop body make sure ++ we vectorized all if-converted code. */ ++ if (!profitable_subgraphs.is_empty () ++ && orig_loop) + { +- if (dump_enabled_p ()) +- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, +- "not vectorized: vectorization is not " +- "profitable.\n"); +- continue; ++ gcc_assert (bb_vinfo->bbs.length () == 1); ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]); ++ !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ /* The costing above left us with DCEable vectorized scalar ++ stmts having the visited flag set on profitable ++ subgraphs. Do the delayed clearing of the flag here. */ ++ if (gimple_visited_p (gsi_stmt (gsi))) ++ { ++ gimple_set_visited (gsi_stmt (gsi), false); ++ continue; ++ } ++ if (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED) ++ continue; ++ ++ if (gassign *ass = dyn_cast (gsi_stmt (gsi))) ++ if (gimple_assign_rhs_code (ass) == COND_EXPR) ++ { ++ if (!profitable_subgraphs.is_empty () ++ && dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "not profitable because of " ++ "unprofitable if-converted scalar " ++ "code\n"); ++ profitable_subgraphs.truncate (0); ++ } ++ } + } + +- if (!dbg_cnt (vect_slp)) +- continue; ++ /* Finally schedule the profitable subgraphs. */ ++ for (slp_instance instance : profitable_subgraphs) ++ { ++ if (!vectorized && dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Basic block will be vectorized " ++ "using SLP\n"); ++ vectorized = true; + +- profitable_subgraphs.safe_push (instance); +- } ++ vect_schedule_slp (bb_vinfo, instance->subgraph_entries); + +- /* When we're vectorizing an if-converted loop body make sure +- we vectorized all if-converted code. */ +- if (!profitable_subgraphs.is_empty () +- && orig_loop) ++ unsigned HOST_WIDE_INT bytes; ++ if (dump_enabled_p ()) ++ { ++ if (GET_MODE_SIZE ++ (bb_vinfo->vector_mode).is_constant (&bytes)) ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, ++ "basic block part vectorized using %wu " ++ "byte vectors\n", bytes); ++ else ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, ++ "basic block part vectorized using " ++ "variable length vectors\n"); ++ } ++ } ++ } ++ else + { +- gcc_assert (bb_vinfo->bbs.length () == 1); +- for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]); +- !gsi_end_p (gsi); gsi_next (&gsi)) ++ if (!profitable_subgraphs_trans.is_empty () ++ && orig_loop) + { +- /* The costing above left us with DCEable vectorized scalar +- stmts having the visited flag set on profitable +- subgraphs. Do the delayed clearing of the flag here. */ +- if (gimple_visited_p (gsi_stmt (gsi))) ++ gcc_assert (bb_vinfo->bbs.length () == 1); ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb_vinfo->bbs[0]); ++ !gsi_end_p (gsi); gsi_next (&gsi)) + { +- gimple_set_visited (gsi_stmt (gsi), false); +- continue; ++ /* The costing above left us with DCEable vectorized scalar ++ stmts having the visited flag set on profitable ++ subgraphs. Do the delayed clearing of the flag here. */ ++ if (gimple_visited_p (gsi_stmt (gsi))) ++ { ++ gimple_set_visited (gsi_stmt (gsi), false); ++ continue; ++ } ++ if (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED) ++ continue; ++ ++ if (gassign *ass = dyn_cast (gsi_stmt (gsi))) ++ if (gimple_assign_rhs_code (ass) == COND_EXPR) ++ { ++ if (!profitable_subgraphs_trans.is_empty () ++ && dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "not profitable because of " ++ "unprofitable if-converted scalar " ++ "code\n"); ++ profitable_subgraphs_trans.truncate (0); ++ } + } +- if (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED) +- continue; +- +- if (gassign *ass = dyn_cast (gsi_stmt (gsi))) +- if (gimple_assign_rhs_code (ass) == COND_EXPR) +- { +- if (!profitable_subgraphs.is_empty () +- && dump_enabled_p ()) +- dump_printf_loc (MSG_NOTE, vect_location, +- "not profitable because of " +- "unprofitable if-converted scalar " +- "code\n"); +- profitable_subgraphs.truncate (0); +- } + } +- } + +- /* Finally schedule the profitable subgraphs. */ +- for (slp_instance instance : profitable_subgraphs) +- { +- if (!vectorized && dump_enabled_p ()) +- dump_printf_loc (MSG_NOTE, vect_location, +- "Basic block will be vectorized " +- "using SLP\n"); +- vectorized = true; ++ /* Finally schedule the profitable subgraphs. */ ++ for (slp_instance instance : profitable_subgraphs_trans) ++ { ++ if (!vectorized && dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Basic block will be vectorized " ++ "using SLP\n"); ++ vectorized = true; + +- vect_schedule_slp (bb_vinfo, instance->subgraph_entries); ++ vect_schedule_slp (bb_vinfo, instance->subgraph_entries); + +- unsigned HOST_WIDE_INT bytes; +- if (dump_enabled_p ()) +- { +- if (GET_MODE_SIZE +- (bb_vinfo->vector_mode).is_constant (&bytes)) +- dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, +- "basic block part vectorized using %wu " +- "byte vectors\n", bytes); +- else +- dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, +- "basic block part vectorized using " +- "variable length vectors\n"); ++ unsigned HOST_WIDE_INT bytes; ++ if (dump_enabled_p ()) ++ { ++ if (GET_MODE_SIZE ++ (bb_vinfo->vector_mode).is_constant (&bytes)) ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, ++ "basic block part vectorized using %wu " ++ "byte vectors\n", bytes); ++ else ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, ++ "basic block part vectorized using " ++ "variable length vectors\n"); ++ } + } + } ++ + } + else + { +@@ -6081,6 +7335,10 @@ vect_slp_region (vec bbs, vec datarefs, + } + + delete bb_vinfo; ++ if (bb_vinfo_trans) ++ { ++ bb_vinfo_trans = NULL; ++ } + + if (mode_i < vector_modes.length () + && VECTOR_MODE_P (autodetected_vector_mode) +@@ -7244,10 +8502,17 @@ vect_schedule_slp_node (vec_info *vinfo, + ready early, vectorized stores go before the last scalar + stmt which is where all uses are ready. */ + stmt_vec_info last_stmt_info = NULL; +- if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))) +- last_stmt_info = vect_find_first_scalar_stmt_in_slp (node); +- else /* DR_IS_WRITE */ +- last_stmt_info = vect_find_last_scalar_stmt_in_slp (node); ++ ++ if (DR_GROUP_FIRST_ELEMENT (stmt_info) ++ && DR_GROUP_SLP_TRANSPOSE (DR_GROUP_FIRST_ELEMENT (stmt_info))) ++ last_stmt_info = vect_find_last_scalar_stmt_in_slp (node); ++ else ++ { ++ if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))) ++ last_stmt_info = vect_find_first_scalar_stmt_in_slp (node); ++ else /* DR_IS_WRITE */ ++ last_stmt_info = vect_find_last_scalar_stmt_in_slp (node); ++ } + si = gsi_for_stmt (last_stmt_info->stmt); + } + else if ((STMT_VINFO_TYPE (stmt_info) == cycle_phi_info_type +diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc +index 349200411..3099f6743 100644 +--- a/gcc/tree-vect-stmts.cc ++++ b/gcc/tree-vect-stmts.cc +@@ -1369,10 +1369,10 @@ vect_get_load_cost (vec_info *, stmt_vec_info stmt_info, int ncopies, + + static void + vect_init_vector_1 (vec_info *vinfo, stmt_vec_info stmt_vinfo, gimple *new_stmt, +- gimple_stmt_iterator *gsi) ++ gimple_stmt_iterator *gsi, bool transpose=false) + { + if (gsi) +- vect_finish_stmt_generation (vinfo, stmt_vinfo, new_stmt, gsi); ++ vect_finish_stmt_generation (vinfo, stmt_vinfo, new_stmt, gsi, transpose); + else + vinfo->insert_on_entry (stmt_vinfo, new_stmt); + +@@ -1393,7 +1393,7 @@ vect_init_vector_1 (vec_info *vinfo, stmt_vec_info stmt_vinfo, gimple *new_stmt, + + tree + vect_init_vector (vec_info *vinfo, stmt_vec_info stmt_info, tree val, tree type, +- gimple_stmt_iterator *gsi) ++ gimple_stmt_iterator *gsi, bool transpose) + { + gimple *init_stmt; + tree new_temp; +@@ -1418,7 +1418,7 @@ vect_init_vector (vec_info *vinfo, stmt_vec_info stmt_info, tree val, tree type, + new_temp = make_ssa_name (TREE_TYPE (type)); + init_stmt = gimple_build_assign (new_temp, COND_EXPR, + val, true_val, false_val); +- vect_init_vector_1 (vinfo, stmt_info, init_stmt, gsi); ++ vect_init_vector_1 (vinfo, stmt_info, init_stmt, gsi, transpose); + val = new_temp; + } + } +@@ -1437,7 +1437,7 @@ vect_init_vector (vec_info *vinfo, stmt_vec_info stmt_info, tree val, tree type, + { + init_stmt = gsi_stmt (gsi2); + gsi_remove (&gsi2, false); +- vect_init_vector_1 (vinfo, stmt_info, init_stmt, gsi); ++ vect_init_vector_1 (vinfo, stmt_info, init_stmt, gsi, transpose); + } + } + } +@@ -1446,7 +1446,7 @@ vect_init_vector (vec_info *vinfo, stmt_vec_info stmt_info, tree val, tree type, + + new_temp = vect_get_new_ssa_name (type, vect_simple_var, "cst_"); + init_stmt = gimple_build_assign (new_temp, val); +- vect_init_vector_1 (vinfo, stmt_info, init_stmt, gsi); ++ vect_init_vector_1 (vinfo, stmt_info, init_stmt, gsi, transpose); + return new_temp; + } + +@@ -1572,9 +1572,11 @@ vect_get_vec_defs (vec_info *vinfo, stmt_vec_info stmt_info, slp_tree slp_node, + statement and create and return a stmt_vec_info for it. */ + + static void +-vect_finish_stmt_generation_1 (vec_info *, +- stmt_vec_info stmt_info, gimple *vec_stmt) ++vect_finish_stmt_generation_1 (vec_info *vinfo, ++ stmt_vec_info stmt_info, gimple *vec_stmt, bool transpose=false) + { ++ if (transpose) ++ stmt_vec_info vec_stmt_info = vinfo->add_pattern_stmt (vec_stmt, NULL); + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, "add new stmt: %G", vec_stmt); + +@@ -1616,7 +1618,7 @@ vect_finish_replace_stmt (vec_info *vinfo, + void + vect_finish_stmt_generation (vec_info *vinfo, + stmt_vec_info stmt_info, gimple *vec_stmt, +- gimple_stmt_iterator *gsi) ++ gimple_stmt_iterator *gsi, bool transpose) + { + gcc_assert (!stmt_info || gimple_code (stmt_info->stmt) != GIMPLE_LABEL); + +@@ -1648,7 +1650,7 @@ vect_finish_stmt_generation (vec_info *vinfo, + } + } + gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT); +- vect_finish_stmt_generation_1 (vinfo, stmt_info, vec_stmt); ++ vect_finish_stmt_generation_1 (vinfo, stmt_info, vec_stmt, transpose); + } + + /* We want to vectorize a call to combined function CFN with function +@@ -2159,6 +2161,173 @@ vector_vector_composition_type (tree vtype, poly_uint64 nelts, tree *ptype) + return NULL_TREE; + } + ++/* Check succeedor BB, BB without load is regarded as empty BB. Ignore empty ++ BB in DFS. */ ++ ++static unsigned ++mem_refs_in_bb (basic_block bb, vec &stmts) ++{ ++ unsigned num = 0; ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); ++ !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ gimple *stmt = gsi_stmt (gsi); ++ if (is_gimple_debug (stmt)) ++ continue; ++ if (is_gimple_assign (stmt) && gimple_has_mem_ops (stmt) ++ && !gimple_has_volatile_ops (stmt)) ++ { ++ if (gimple_assign_rhs_code (stmt) == MEM_REF ++ || gimple_assign_rhs_code (stmt) == ARRAY_REF) ++ { ++ stmts.safe_push (stmt); ++ num++; ++ } ++ else if (TREE_CODE (gimple_get_lhs (stmt)) == MEM_REF ++ || TREE_CODE (gimple_get_lhs (stmt)) == ARRAY_REF) ++ num++; ++ } ++ } ++ return num; ++} ++ ++static bool ++check_same_base (vec *datarefs, data_reference_p dr) ++{ ++ for (unsigned ui = 0; ui < datarefs->length (); ui++) ++ { ++ tree op1 = TREE_OPERAND (DR_BASE_OBJECT (dr), 0); ++ tree op2 = TREE_OPERAND (DR_BASE_OBJECT ((*datarefs)[ui]), 0); ++ if (TREE_CODE (op1) != TREE_CODE (op2)) ++ continue; ++ if (TREE_CODE (op1) == ADDR_EXPR) ++ { ++ op1 = TREE_OPERAND (op1, 0); ++ op2 = TREE_OPERAND (op2, 0); ++ } ++ enum tree_code code = TREE_CODE (op1); ++ switch (code) ++ { ++ case VAR_DECL: ++ if (DECL_NAME (op1) == DECL_NAME (op2) ++ && DR_IS_READ ((*datarefs)[ui])) ++ return true; ++ break; ++ case SSA_NAME: ++ if (SSA_NAME_VERSION (op1) == SSA_NAME_VERSION (op2) ++ && DR_IS_READ ((*datarefs)[ui])) ++ return true; ++ break; ++ default: ++ break; ++ } ++ } ++ return false; ++} ++ ++/* Iterate all load STMTS, if staisfying same base vectorized stmt, then return, ++ Otherwise, set false to SUCCESS. */ ++ ++static void ++check_vec_use (loop_vec_info loop_vinfo, vec &stmts, ++ stmt_vec_info stmt_info, bool &success) ++{ ++ if (stmt_info == NULL) ++ { ++ success = false; ++ return; ++ } ++ if (DR_IS_READ (stmt_info->dr_aux.dr)) ++ { ++ success = false; ++ return; ++ } ++ unsigned ui = 0; ++ gimple *candidate = NULL; ++ FOR_EACH_VEC_ELT (stmts, ui, candidate) ++ { ++ if (TREE_CODE (TREE_TYPE (gimple_get_lhs (candidate))) != VECTOR_TYPE) ++ continue; ++ ++ if (candidate->bb != candidate->bb->loop_father->header) ++ { ++ success = false; ++ return; ++ } ++ auto_vec datarefs; ++ tree res = find_data_references_in_bb (candidate->bb->loop_father, ++ candidate->bb, &datarefs); ++ if (res == chrec_dont_know) ++ { ++ success = false; ++ return; ++ } ++ if (check_same_base (&datarefs, stmt_info->dr_aux.dr)) ++ return; ++ } ++ success = false; ++} ++ ++/* Deep first search from present BB. If succeedor has load STMTS, ++ stop further searching. */ ++ ++static void ++dfs_check_bb (loop_vec_info loop_vinfo, basic_block bb, stmt_vec_info stmt_info, ++ bool &success, vec &visited_bbs) ++{ ++ if (bb == cfun->cfg->x_exit_block_ptr) ++ { ++ success = false; ++ return; ++ } ++ if (!success || visited_bbs.contains (bb) || bb == loop_vinfo->loop->latch) ++ return; ++ ++ visited_bbs.safe_push (bb); ++ auto_vec stmts; ++ unsigned num = mem_refs_in_bb (bb, stmts); ++ /* Empty BB. */ ++ if (num == 0) ++ { ++ edge e; ++ edge_iterator ei; ++ FOR_EACH_EDGE (e, ei, bb->succs) ++ { ++ dfs_check_bb (loop_vinfo, e->dest, stmt_info, success, visited_bbs); ++ if (!success) ++ return; ++ } ++ return; ++ } ++ /* Non-empty BB. */ ++ check_vec_use (loop_vinfo, stmts, stmt_info, success); ++} ++ ++/* For grouped store, if all succeedors of present BB have vectorized load ++ from same base of store. If so, set memory_access_type using ++ VMAT_CONTIGUOUS_PERMUTE instead of VMAT_LOAD_STORE_LANES. */ ++ ++static bool ++conti_perm (stmt_vec_info stmt_vinfo, loop_vec_info loop_vinfo) ++{ ++ gimple *stmt = stmt_vinfo->stmt; ++ if (gimple_code (stmt) != GIMPLE_ASSIGN) ++ return false; ++ ++ if (DR_IS_READ (stmt_vinfo->dr_aux.dr)) ++ return false; ++ ++ basic_block bb = stmt->bb; ++ bool success = true; ++ auto_vec visited_bbs; ++ visited_bbs.safe_push (bb); ++ edge e; ++ edge_iterator ei; ++ FOR_EACH_EDGE (e, ei, bb->succs) ++ dfs_check_bb (loop_vinfo, e->dest, stmt_vinfo, success, visited_bbs); ++ return success; ++} ++ + /* A subroutine of get_load_store_type, with a subset of the same + arguments. Handle the case where STMT_INFO is part of a grouped load + or store. +@@ -2373,6 +2542,20 @@ get_group_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, + *memory_access_type = VMAT_CONTIGUOUS_PERMUTE; + overrun_p = would_overrun_p; + } ++ ++ if (*memory_access_type == VMAT_LOAD_STORE_LANES ++ && TREE_CODE (loop_vinfo->num_iters) == INTEGER_CST ++ && maybe_eq (tree_to_shwi (loop_vinfo->num_iters), ++ loop_vinfo->vectorization_factor) ++ && conti_perm (stmt_info, loop_vinfo) ++ && (vls_type == VLS_LOAD ++ ? vect_grouped_load_supported (vectype, single_element_p, ++ group_size) ++ : vect_grouped_store_supported (vectype, group_size))) ++ { ++ *memory_access_type = VMAT_CONTIGUOUS_PERMUTE; ++ overrun_p = would_overrun_p; ++ } + } + + /* As a last resort, trying using a gather load or scatter store. +@@ -7456,6 +7639,154 @@ vectorizable_scan_store (vec_info *vinfo, + return true; + } + ++/* Function vect_permute_store_chains ++ ++ Call function vect_permute_store_chain (). ++ Given a chain of interleaved stores in DR_CHAIN, generate ++ interleave_high/low stmts to reorder the data correctly. ++ Return the final references for stores in RESULT_CHAIN. */ ++ ++static void ++vect_permute_store_chains (vec_info *vinfo, vec dr_chain, ++ unsigned int num_each, stmt_vec_info stmt_info, ++ gimple_stmt_iterator *gsi, vec *result_chain, ++ unsigned int group) ++{ ++ unsigned int k = 0; ++ unsigned int t = 0; ++ ++ /* Divide vectors into GROUP parts. And permute every NUM_EACH vectors ++ together. */ ++ for (k = 0; k < group; k++) ++ { ++ auto_vec dr_chain_transposed (num_each); ++ auto_vec result_chain_transposed (num_each); ++ for (t = k; t < dr_chain.length (); t = t + group) ++ { ++ dr_chain_transposed.quick_push (dr_chain[t]); ++ } ++ vect_permute_store_chain (vinfo, dr_chain_transposed, num_each, ++ stmt_info, gsi, &result_chain_transposed); ++ for (t = 0; t < num_each; t++) ++ { ++ result_chain->quick_push (result_chain_transposed[t]); ++ } ++ } ++} ++ ++/* Function transpose_oprnd_store ++ ++ Calculate the transposed results from VEC_OPRNDS (VEC_STMT) ++ for vectorizable_store. */ ++ ++static void ++transpose_oprnd_store (vec_info *vinfo, vecvec_oprnds, ++ vec *result_chain, unsigned int vec_num, ++ unsigned int const_nunits, unsigned int array_num, ++ stmt_vec_info first_stmt_info, ++ gimple_stmt_iterator *gsi) ++{ ++ unsigned int group_for_transform = 0; ++ unsigned int num_each = 0; ++ ++ /* Transpose back for vec_oprnds. */ ++ /* vec = {vec1, vec2, ...} */ ++ if (array_num < const_nunits ++ && const_nunits % array_num == 0) ++ { ++ vect_transpose_store_chain (vinfo, vec_oprnds, ++ vec_num, array_num, ++ first_stmt_info, ++ gsi, result_chain); ++ } ++ /* vec1 = {vec_part1}, vec2 = {vec_part2}, ... */ ++ else if (array_num >= const_nunits ++ && array_num % const_nunits == 0) ++ { ++ group_for_transform = array_num / const_nunits; ++ num_each = vec_oprnds.length () / group_for_transform; ++ vect_permute_store_chains (vinfo, vec_oprnds, ++ num_each, first_stmt_info, ++ gsi, result_chain, ++ group_for_transform); ++ } ++ else ++ { ++ gcc_unreachable (); ++ } ++} ++ ++static dr_vec_info * ++get_dr_info (stmt_vec_info stmt_info) ++{ ++ dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info); ++ if (dr_info->misalignment == DR_MISALIGNMENT_UNINITIALIZED) ++ { ++ SET_DR_MISALIGNMENT (dr_info, DR_MISALIGNMENT_UNKNOWN); ++ } ++ return dr_info; ++} ++ ++static unsigned ++dr_align_vect_store (vec_info *vinfo, dr_vec_info *cur_first_dr_info, ++ tree vectype, unsigned HOST_WIDE_INT &align) ++{ ++ unsigned misalign = 0; ++ align = known_alignment (DR_TARGET_ALIGNMENT (cur_first_dr_info)); ++ if (aligned_access_p (cur_first_dr_info, vectype)) ++ { ++ return misalign; ++ } ++ else if (cur_first_dr_info->misalignment == -1) ++ { ++ align = dr_alignment (vect_dr_behavior (vinfo, cur_first_dr_info)); ++ } ++ else ++ { ++ misalign = cur_first_dr_info->misalignment; ++ } ++ return misalign; ++} ++ ++static void ++add_new_stmt_vect_store (vec_info *vinfo, tree vectype, tree dataref_ptr, ++ tree dataref_offset, tree ref_type, ++ dr_vec_info *cur_first_dr_info, tree vec_oprnd, ++ gimple_stmt_iterator *gsi, stmt_vec_info stmt_info) ++{ ++ /* Data align. */ ++ unsigned HOST_WIDE_INT align; ++ unsigned misalign = dr_align_vect_store (vinfo, cur_first_dr_info, ++ vectype, align); ++ ++ if (dataref_offset == NULL_TREE && TREE_CODE (dataref_ptr) == SSA_NAME) ++ { ++ set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, misalign); ++ } ++ ++ /* Get data_ref. */ ++ tree offset = dataref_offset ? dataref_offset : build_int_cst (ref_type, 0); ++ tree data_ref = fold_build2 (MEM_REF, vectype, dataref_ptr, offset); ++ if (aligned_access_p (cur_first_dr_info, vectype)) ++ { ++ ; ++ } ++ else if (cur_first_dr_info->misalignment == -1) ++ { ++ TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), ++ align * BITS_PER_UNIT); ++ } ++ else ++ { ++ tree elem_type = TREE_TYPE (vectype); ++ TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), ++ TYPE_ALIGN (elem_type)); ++ } ++ /* Add new stmt. */ ++ vect_copy_ref_info (data_ref, DR_REF (cur_first_dr_info->dr)); ++ gassign *new_stmt = gimple_build_assign (data_ref, vec_oprnd); ++ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi, true); ++} + + /* Function vectorizable_store. + +@@ -8333,6 +8664,16 @@ vectorizable_store (vec_info *vinfo, + &vec_offsets); + vec_offset = vec_offsets[0]; + } ++ /* If the stmt_info need to be transposed recovery, dataref_ptr ++ will be caculated later. */ ++ else if (memory_access_type == VMAT_CONTIGUOUS ++ && is_a (vinfo) ++ && STMT_VINFO_GROUPED_ACCESS (stmt_info) ++ && DR_GROUP_SLP_TRANSPOSE ( ++ DR_GROUP_FIRST_ELEMENT (stmt_info))) ++ { ++ dataref_ptr = NULL_TREE; ++ } + else + dataref_ptr + = vect_create_data_ref_ptr (vinfo, first_stmt_info, aggr_type, +@@ -8423,6 +8764,75 @@ vectorizable_store (vec_info *vinfo, + } + else + { ++ /* group_size: the size of group after transposing and merging. ++ group_size_b: the size of group before transposing and merging, ++ and only group_size_b >= const_nunits is supported. ++ array_num: the number of arrays. ++ const_nunits: TYPE_VECTOR_SUBPARTS (vectype). ++ ncontinues: group_size_b / const_nunits, it means the number of ++ times an array is stored in memory. */ ++ if (slp && is_a (vinfo) ++ && STMT_VINFO_GROUPED_ACCESS (stmt_info) ++ && DR_GROUP_SLP_TRANSPOSE (DR_GROUP_FIRST_ELEMENT (stmt_info))) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "vectorizable_store for slp transpose.\n"); ++ } ++ /* Transpose back for grouped stores. */ ++ vect_transform_back_slp_grouped_stores (bb_vinfo, ++ first_stmt_info); ++ ++ result_chain.create (vec_oprnds.length ()); ++ unsigned int const_nunits = nunits.to_constant (); ++ unsigned int group_size_b = DR_GROUP_SIZE_TRANS (first_stmt_info); ++ unsigned int array_num = group_size / group_size_b; ++ transpose_oprnd_store (vinfo, vec_oprnds, &result_chain, vec_num, ++ const_nunits, array_num, ++ first_stmt_info, gsi); ++ ++ /* For every store group, not for every vec, because transposing ++ and merging have changed the data reference access. */ ++ gcc_assert (group_size_b >= const_nunits); ++ unsigned int ncontinues = group_size_b / const_nunits; ++ ++ unsigned int k = 0; ++ for (i = 0; i < array_num; i++) ++ { ++ stmt_vec_info first_stmt_b; ++ BB_VINFO_GROUPED_STORES (vinfo).iterate (i, &first_stmt_b); ++ bool simd_lane_access_p ++ = STMT_VINFO_SIMD_LANE_ACCESS_P (first_stmt_b) != 0; ++ tree ref_type = get_group_alias_ptr_type (first_stmt_b); ++ dataref_ptr = vect_create_data_ref_ptr ( ++ vinfo, first_stmt_b, aggr_type, ++ simd_lane_access_p ? loop : NULL, ++ offset, &dummy, gsi, &ptr_incr, ++ simd_lane_access_p, bump); ++ dr_vec_info *cur_first_dr_info = get_dr_info (first_stmt_b); ++ for (unsigned int t = 0; t < ncontinues; t++) ++ { ++ vec_oprnd = result_chain[k]; ++ k++; ++ if (t > 0) ++ { ++ /* Bump the vector pointer. */ ++ dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ++ ptr_incr, gsi, ++ first_stmt_b, bump); ++ } ++ add_new_stmt_vect_store (vinfo, vectype, dataref_ptr, ++ dataref_offset, ref_type, ++ cur_first_dr_info, vec_oprnd, ++ gsi, first_stmt_b); ++ } ++ } ++ oprnds.release (); ++ result_chain.release (); ++ vec_oprnds.release (); ++ return true; ++ } + new_stmt = NULL; + if (grouped_store) + { +@@ -8719,6 +9129,451 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop) + return true; + } + ++static tree ++calculate_new_type (tree vectype, unsigned int const_nunits, ++ unsigned int group_size_b, unsigned int &nloads, ++ unsigned int &ncontinues, tree &lvectype) ++{ ++ tree ltype = TREE_TYPE (vectype); ++ /* nloads is the number of ARRAYs in a vector. ++ vectemp = {a[], b[], ...} */ ++ if (group_size_b < const_nunits) ++ { ++ tree ptype; ++ tree vtype ++ = vector_vector_composition_type (vectype, ++ const_nunits / group_size_b, ++ &ptype); ++ if (vtype != NULL_TREE) ++ { ++ nloads = const_nunits / group_size_b; ++ lvectype = vtype; ++ ltype = ptype; ++ ncontinues = 1; ++ } ++ } ++ /* ncontinues is the number of vectors from an ARRAY. ++ vectemp1 = {a[0], a[1], ...} ++ ... ++ vectempm = {a[k], a[k+1], ...} */ ++ else ++ { ++ nloads = 1; ++ ltype = vectype; ++ ncontinues = group_size_b / const_nunits; ++ } ++ ltype = build_aligned_type (ltype, TYPE_ALIGN (TREE_TYPE (vectype))); ++ return ltype; ++} ++ ++static void ++generate_old_load_permutations (slp_tree slp_node, unsigned int group_size, ++ vec &old_load_permutation) ++{ ++ /* Generate the old load permutations from the slp_node. */ ++ unsigned i = 0; ++ unsigned k = 0; ++ ++ /* If SLP_NODE has load_permutation, we copy it to old_load_permutation. ++ Otherwise, we generate a permutation sequentially. */ ++ if (SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) ++ { ++ FOR_EACH_VEC_ELT (SLP_TREE_LOAD_PERMUTATION (slp_node), i, k) ++ { ++ old_load_permutation.safe_push (k); ++ } ++ } ++ else ++ { ++ for (unsigned i = 0; i < group_size; i++) ++ { ++ old_load_permutation.safe_push (i); ++ } ++ } ++} ++ ++static void ++generate_new_load_permutation_mapping (unsigned slp_node_length, ++ vec &group_idx, ++ const vec &load_permutation, ++ unsigned int group_size_b, ++ unsigned &new_group_size, ++ vec &group_from) ++{ ++ /* group_num_vec: only stores the group_loads IDs which are caculated from ++ load_permutation. */ ++ auto_vec group_num_vec; ++ ++ /* Caculate which group_loads are the stmts in SLP_NODE from. */ ++ unsigned i = 0; ++ unsigned k = 0; ++ FOR_EACH_VEC_ELT (load_permutation, i, k) ++ { ++ unsigned int t0 = k / group_size_b; ++ if (!group_num_vec.contains (t0)) ++ { ++ group_num_vec.safe_push (t0); ++ } ++ group_from.safe_push (t0); ++ } ++ group_num_vec.qsort (cmp_for_group_num); ++ /* n_groups: the number of group_loads. */ ++ unsigned int n_groups = group_num_vec.length (); ++ new_group_size = n_groups * group_size_b; ++ for (i = 0; i < n_groups; i++) ++ { ++ group_idx.safe_push (group_num_vec[i] * group_size_b); ++ } ++ /* A new mapping from group_ind_vec to group_from. ++ For example: ++ Origin: group_from = {1,1,3,3,5,5,7,7}; ++ After mapping: group_from = {0,0,1,1,2,2,2,2}; */ ++ auto_vec group_ind_vec (n_groups); ++ for (k = 0; k < n_groups; k++) ++ { ++ group_ind_vec.safe_push (k); ++ } ++ for (i = 0; i < slp_node_length; i++) ++ { ++ for (k = 0; k < n_groups; k++) ++ { ++ if (group_from[i] == group_num_vec[k]) ++ { ++ group_from[i] = group_ind_vec[k]; ++ break; ++ } ++ } ++ } ++} ++ ++static void ++generate_new_load_permutation (vec &new_load_permutation, ++ const vec &old_load_permutation, ++ slp_tree slp_node, bool &this_load_permuted, ++ const vec &group_from, ++ unsigned int group_size_b) ++{ ++ unsigned slp_node_length = SLP_TREE_SCALAR_STMTS (slp_node).length (); ++ /* Generate the new load permutation from the new mapping. */ ++ new_load_permutation.create (slp_node_length); ++ unsigned i = 0; ++ unsigned k = 0; ++ FOR_EACH_VEC_ELT (old_load_permutation, i, k) ++ { ++ /* t1 is the new permutation of k in the old permutation. ++ t1 = base_address + offset: ++ base_address = group_from[i] * group_size_b; ++ offset = k % group_size_b. */ ++ unsigned int t1 ++ = group_from[i] * group_size_b + k % group_size_b; ++ new_load_permutation.safe_push (t1); ++ if (t1 != k) ++ { ++ this_load_permuted = true; ++ } ++ } ++} ++ ++static bool ++is_slp_perm (bool slp_perm, bool this_load_permuted, poly_uint64 nunits, ++ unsigned int group_size, stmt_vec_info first_stmt_info) ++{ ++ /* Calculate the unrolling factor based on the smallest type. */ ++ poly_uint64 unrolling_factor ++ = exact_div (common_multiple (nunits, group_size), group_size); ++ /* The load requires permutation when unrolling exposes ++ a gap either because the group is larger than the SLP ++ group-size or because there is a gap between the groups. */ ++ if (!slp_perm && !this_load_permuted ++ && (known_eq (unrolling_factor, 1U) ++ || (group_size == DR_GROUP_SIZE (first_stmt_info) ++ && DR_GROUP_GAP (first_stmt_info) == 0))) ++ { ++ return false; ++ } ++ else ++ { ++ return true; ++ } ++} ++ ++static void ++generate_load_permutation (slp_tree slp_node, unsigned &new_group_size, ++ unsigned int group_size, unsigned int group_size_b, ++ bool &this_load_permuted, vec &group_idx, ++ vec &new_load_permutation) ++{ ++ /* Generate the old load permutations from SLP_NODE. */ ++ vec old_load_permutation; ++ old_load_permutation.create (group_size); ++ generate_old_load_permutations (slp_node, group_size, old_load_permutation); ++ ++ /* Caculate which group_loads are the stmts in SLP_NODE from. */ ++ unsigned slp_node_length = SLP_TREE_SCALAR_STMTS (slp_node).length (); ++ /* group_from: stores the group_loads ID for every stmt in SLP_NODE. */ ++ vec group_from; ++ group_from.create (slp_node_length); ++ generate_new_load_permutation_mapping (slp_node_length, group_idx, ++ old_load_permutation, ++ group_size_b, new_group_size, ++ group_from); ++ ++ /* Generate the new load permutation from the new mapping and caculate ++ this_load_permuted flag. If this_load_permuted is true, we need execute ++ slp permutation by using new load permutation. */ ++ generate_new_load_permutation (new_load_permutation, old_load_permutation, ++ slp_node, this_load_permuted, group_from, ++ group_size_b); ++ old_load_permutation.release (); ++ group_from.release (); ++} ++ ++static unsigned int ++dr_align_vect_load (vec_info *vinfo, dr_vec_info *cur_first_dr_info, ++ tree vectype, unsigned HOST_WIDE_INT &align, ++ enum dr_alignment_support alignment_support_scheme) ++{ ++ unsigned int misalign = 0; ++ ++ align = known_alignment (DR_TARGET_ALIGNMENT (cur_first_dr_info)); ++ if (alignment_support_scheme == dr_aligned) ++ { ++ gcc_assert (aligned_access_p (cur_first_dr_info, vectype)); ++ } ++ else if (cur_first_dr_info->misalignment == -1) ++ { ++ align = dr_alignment (vect_dr_behavior (vinfo, cur_first_dr_info)); ++ } ++ else ++ { ++ misalign = cur_first_dr_info->misalignment; ++ } ++ return misalign; ++} ++ ++static stmt_vec_info ++add_new_stmt_vect_load (vec_info *vinfo, tree vectype, tree dataref_ptr, ++ tree dataref_offset, tree ref_type, tree ltype, ++ gassign *(&new_stmt), dr_vec_info *cur_first_dr_info, ++ gimple_stmt_iterator *gsi, stmt_vec_info stmt_info) ++{ ++ /* Data align. */ ++ int malign = dr_misalignment (cur_first_dr_info, vectype); ++ enum dr_alignment_support alignment_support_scheme ++ = vect_supportable_dr_alignment (vinfo, cur_first_dr_info, ++ vectype, malign); ++ unsigned HOST_WIDE_INT align; ++ unsigned int misalign = dr_align_vect_load (vinfo, cur_first_dr_info, ++ vectype, align, ++ alignment_support_scheme); ++ if (dataref_offset == NULL_TREE && TREE_CODE (dataref_ptr) == SSA_NAME) ++ { ++ set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, misalign); ++ } ++ ++ /* Get data_ref. */ ++ tree offset = dataref_offset ? dataref_offset : build_int_cst (ref_type, 0); ++ tree data_ref = fold_build2 (MEM_REF, ltype, dataref_ptr, offset); ++ if (alignment_support_scheme == dr_aligned) ++ { ++ ; ++ } ++ else if (cur_first_dr_info->misalignment == -1) ++ { ++ TREE_TYPE (data_ref) ++ = build_aligned_type (TREE_TYPE (data_ref), align * BITS_PER_UNIT); ++ } ++ else ++ { ++ tree elem_type = TREE_TYPE (vectype); ++ TREE_TYPE (data_ref) ++ = build_aligned_type (TREE_TYPE (data_ref), TYPE_ALIGN (elem_type)); ++ } ++ ++ /* Add new stmt. */ ++ vect_copy_ref_info (data_ref, DR_REF (cur_first_dr_info->dr)); ++ new_stmt = gimple_build_assign (make_ssa_name (ltype), data_ref); ++ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi, true); ++ stmt_vec_info vec_stmt_info = vinfo->lookup_stmt (new_stmt); ++ return vec_stmt_info; ++} ++ ++static void ++push_new_stmt_to_dr_chain (bool slp_perm, stmt_vec_info new_stmt_info, ++ vec dr_chain, slp_tree slp_node) ++{ ++ if (slp_perm) ++ dr_chain.quick_push (gimple_assign_lhs (new_stmt_info->stmt)); ++ else ++ SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt_info->stmt); ++} ++ ++static stmt_vec_info ++get_first_stmt_info_before_transpose (stmt_vec_info first_stmt_info, ++ unsigned int group_el, ++ unsigned int group_size) ++{ ++ stmt_vec_info last_stmt_info = first_stmt_info; ++ unsigned int count = 0; ++ gcc_assert (group_el < group_size); ++ while (count < group_el) ++ { ++ last_stmt_info = DR_GROUP_NEXT_ELEMENT (last_stmt_info); ++ count++; ++ } ++ return last_stmt_info; ++} ++ ++static stmt_vec_info ++add_new_stmt_for_nloads_greater_than_one (vec_info *vinfo, tree lvectype, ++ tree vectype, ++ vec *v, ++ stmt_vec_info stmt_info, ++ gimple_stmt_iterator *gsi) ++{ ++ tree vec_inv = build_constructor (lvectype, v); ++ tree new_temp = vect_init_vector (vinfo, stmt_info, vec_inv, lvectype, gsi, true); ++ stmt_vec_info new_stmt_info = vinfo->lookup_def (new_temp); ++ if (lvectype != vectype) ++ { ++ gassign *new_stmt = gimple_build_assign (make_ssa_name (vectype), ++ VIEW_CONVERT_EXPR, ++ build1 (VIEW_CONVERT_EXPR, ++ vectype, new_temp)); ++ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi, true); ++ new_stmt_info = vinfo->lookup_stmt (new_stmt); ++ } ++ return new_stmt_info; ++} ++ ++/* Function new_vect_stmt_for_nloads. ++ ++ New a VEC_STMT when nloads Arrays are merged into a vector. ++ ++ ncopies is the number of vectors that need to be loaded from memmory. ++ nloads is the number of ARRAYs in a vector. ++ vectemp = {a[], b[], ...} */ ++ ++static void ++new_vect_stmt_for_nloads (vec_info *vinfo, unsigned int ncopies, ++ unsigned int nloads, const vec &group_idx, ++ stmt_vec_info stmt_info, offset_info *offset_info, ++ vectype_info *vectype_info, ++ vect_memory_access_type memory_access_type, ++ bool slp_perm, vec dr_chain, slp_tree slp_node, ++ gimple_stmt_iterator *gsi) ++{ ++ vec *v = NULL; ++ stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); ++ unsigned int group_size = DR_GROUP_SIZE (first_stmt_info); ++ stmt_vec_info first_stmt_info_b = NULL; ++ stmt_vec_info new_stmt_info = NULL; ++ tree dataref_ptr = NULL_TREE; ++ tree dummy; ++ gimple *ptr_incr = NULL; ++ unsigned int n = 0; ++ for (unsigned int i = 0; i < ncopies; i++) ++ { ++ vec_alloc (v, nloads); ++ for (unsigned int t = 0; t < nloads; t++) ++ { ++ first_stmt_info_b = get_first_stmt_info_before_transpose ( ++ first_stmt_info, group_idx[n++], group_size); ++ dr_vec_info* cur_first_dr_info = get_dr_info (first_stmt_info_b); ++ tree bump = vect_get_data_ptr_increment (vinfo, cur_first_dr_info, ++ vectype_info->ltype, ++ memory_access_type); ++ bool simd_lane_access_p ++ = STMT_VINFO_SIMD_LANE_ACCESS_P (first_stmt_info_b) != 0; ++ ++ /* Create dataref_ptr which is point to init_address. */ ++ dataref_ptr = vect_create_data_ref_ptr ( ++ vinfo, first_stmt_info_b, vectype_info->ltype, NULL, ++ offset_info->offset, &dummy, gsi, &ptr_incr, ++ simd_lane_access_p, bump); ++ ++ gassign *new_stmt = NULL; ++ new_stmt_info = add_new_stmt_vect_load (vinfo, vectype_info->vectype, dataref_ptr, ++ offset_info->dataref_offset, ++ vectype_info->ref_type, vectype_info->ltype, ++ new_stmt, cur_first_dr_info, gsi, ++ first_stmt_info_b); ++ ++ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, gimple_assign_lhs (new_stmt)); ++ } ++ new_stmt_info = add_new_stmt_for_nloads_greater_than_one ( ++ vinfo, vectype_info->lvectype, ++ vectype_info->vectype, v, ++ first_stmt_info_b, gsi); ++ push_new_stmt_to_dr_chain (slp_perm, new_stmt_info, ++ dr_chain, slp_node); ++ } ++} ++ ++/* Function new_vect_stmt_for_ncontinues. ++ ++ New a VEC_STMTs when an Array is divided into several vectors. ++ ++ n_groups is the number of ARRAYs. ++ ncontinues is the number of vectors from an ARRAY. ++ vectemp1 = {a[0], a[1], ...} ++ ... ++ vectempm = {a[k], a[k+1], ...} */ ++ ++static void ++new_vect_stmt_for_ncontinues (vec_info *vinfo, unsigned int ncontinues, ++ const vec &group_idx, ++ stmt_vec_info stmt_info, ++ offset_info* offset_info, ++ vectype_info* vectype_info, ++ vect_memory_access_type memory_access_type, ++ bool slp_perm, vec &dr_chain, ++ slp_tree slp_node, ++ gimple_stmt_iterator *gsi) ++{ ++ stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); ++ unsigned int group_size = DR_GROUP_SIZE (first_stmt_info); ++ stmt_vec_info new_stmt_info = NULL; ++ tree dataref_ptr = NULL_TREE; ++ tree dummy; ++ gimple *ptr_incr = NULL; ++ unsigned int n_groups = group_idx.length (); ++ for (unsigned int i = 0; i < n_groups; i++) ++ { ++ stmt_vec_info first_stmt_info_b = get_first_stmt_info_before_transpose ( ++ first_stmt_info, group_idx[i], group_size); ++ dr_vec_info* cur_first_dr_info = get_dr_info (first_stmt_info_b); ++ tree bump = vect_get_data_ptr_increment (vinfo, cur_first_dr_info, ++ vectype_info->ltype, memory_access_type); ++ bool simd_lane_access_p ++ = STMT_VINFO_SIMD_LANE_ACCESS_P (first_stmt_info_b) != 0; ++ for (unsigned int k = 0; k < ncontinues; k++) ++ { ++ /* Create dataref_ptr which is point to init_address. */ ++ if (k == 0) ++ { ++ dataref_ptr = vect_create_data_ref_ptr ( ++ vinfo, first_stmt_info_b, vectype_info->ltype, NULL, ++ offset_info->offset, &dummy, gsi, &ptr_incr, ++ simd_lane_access_p, bump); ++ } ++ else ++ { ++ dataref_ptr = bump_vector_ptr (vinfo, dataref_ptr, ptr_incr, ++ gsi, first_stmt_info_b, bump); ++ } ++ gassign *new_stmt = NULL; ++ new_stmt_info = add_new_stmt_vect_load (vinfo, vectype_info->vectype, dataref_ptr, ++ offset_info->dataref_offset, ++ vectype_info->ref_type, vectype_info->ltype, ++ new_stmt, cur_first_dr_info, gsi, ++ first_stmt_info_b); ++ push_new_stmt_to_dr_chain (slp_perm, new_stmt_info, ++ dr_chain, slp_node); ++ } ++ } ++} ++ + /* vectorizable_load. + + Check if STMT_INFO reads a non scalar data-ref (array/pointer/structure) +@@ -9338,6 +10193,8 @@ vectorizable_load (vec_info *vinfo, + if (bb_vinfo) + first_stmt_info_for_drptr + = vect_find_first_scalar_stmt_in_slp (slp_node); ++ // first_stmt_info_for_drptr = SLP_TREE_SCALAR_STMTS (slp_node)[0]; ++ + + /* Check if the chain of loads is already vectorized. */ + if (STMT_VINFO_VEC_STMTS (first_stmt_info).exists () +@@ -9601,6 +10458,9 @@ vectorizable_load (vec_info *vinfo, + } + tree vec_mask = NULL_TREE; + poly_uint64 group_elt = 0; ++ unsigned new_group_size = 0; ++ vec new_load_permutation; ++ + for (j = 0; j < ncopies; j++) + { + /* 1. Create the vector or array pointer update chain. */ +@@ -9621,6 +10481,15 @@ vectorizable_load (vec_info *vinfo, + dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr)); + dataref_offset = build_int_cst (ref_type, 0); + } ++ /* If the stmt_info need to be transposed recovery, dataref_ptr ++ will be caculated later. */ ++ else if (slp && is_a (vinfo) ++ && STMT_VINFO_GROUPED_ACCESS (stmt_info) ++ && DR_GROUP_SLP_TRANSPOSE ( ++ DR_GROUP_FIRST_ELEMENT (stmt_info))) ++ { ++ dataref_ptr = NULL_TREE; ++ } + else if (diff_first_stmt_info) + { + dataref_ptr +@@ -9731,6 +10600,63 @@ vectorizable_load (vec_info *vinfo, + /* Record that VEC_ARRAY is now dead. */ + vect_clobber_variable (vinfo, stmt_info, gsi, vec_array); + } ++ else if (slp && is_a (vinfo) ++ && STMT_VINFO_GROUPED_ACCESS (stmt_info) ++ && DR_GROUP_SLP_TRANSPOSE (DR_GROUP_FIRST_ELEMENT (stmt_info))) ++ { ++ if (dump_enabled_p ()) ++ { ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "vectorizable_load for slp transpose.\n"); ++ } ++ /* group_size: the size of group after merging. ++ group_size_b: the size of group before merging. ++ const_nunits: TYPE_VECTOR_SUBPARTS (vectype), it is the number of ++ elements in a vector. ++ nloads: const_nunits / group_size_b or 1, it means the number ++ of ARRAYs in a vector. ++ ncontinues: group_size_b / const_nunits or 1, it means the number ++ of vectors from an ARRAY. */ ++ unsigned int group_size_b = DR_GROUP_SIZE_TRANS (first_stmt_info); ++ unsigned int const_nunits = nunits.to_constant (); ++ unsigned int nloads = const_nunits; ++ unsigned int ncontinues = group_size_b; ++ tree lvectype = vectype; ++ tree ltype = calculate_new_type (vectype, const_nunits, ++ group_size_b, nloads, ++ ncontinues, lvectype); ++ bool this_load_permuted = false; ++ auto_vec group_idx; ++ generate_load_permutation (slp_node, new_group_size, group_size, ++ group_size_b, this_load_permuted, ++ group_idx, new_load_permutation); ++ slp_perm = is_slp_perm (slp_perm, this_load_permuted, nunits, ++ group_size, first_stmt_info); ++ ++ /* ncopies: the number of vectors that need to be loaded from ++ memmory. */ ++ unsigned int ncopies = new_group_size / const_nunits; ++ offset_info offset_info = {offset, NULL_TREE, dataref_offset}; ++ vectype_info vectype_info = {vectype, ltype, lvectype, ref_type}; ++ if (slp_perm) ++ { ++ dr_chain.create (ncopies); ++ } ++ if (nloads > 1 && ncontinues == 1) ++ { ++ new_vect_stmt_for_nloads (vinfo, ncopies, nloads, group_idx, ++ stmt_info, &offset_info, &vectype_info, ++ memory_access_type, slp_perm, dr_chain, ++ slp_node, gsi); ++ } ++ else ++ { ++ new_vect_stmt_for_ncontinues (vinfo, ncontinues, group_idx, ++ stmt_info, &offset_info, ++ &vectype_info, memory_access_type, ++ slp_perm, dr_chain, slp_node, gsi); ++ } ++ } + else + { + for (i = 0; i < vec_num; i++) +@@ -10177,7 +11103,32 @@ vectorizable_load (vec_info *vinfo, + if (slp && !slp_perm) + continue; + +- if (slp_perm) ++ /* Using the new load permutation to generate vector permute statements ++ from a list of loads in DR_CHAIN. */ ++ if (slp && slp_perm && is_a (vinfo) ++ && STMT_VINFO_GROUPED_ACCESS (stmt_info) ++ && DR_GROUP_SLP_TRANSPOSE (DR_GROUP_FIRST_ELEMENT (stmt_info))) ++ { ++ unsigned n_perms; ++ stmt_vec_info stmt_info_ = SLP_TREE_SCALAR_STMTS (slp_node)[0]; ++ unsigned int old_size = DR_GROUP_SIZE (stmt_info); ++ DR_GROUP_SIZE (stmt_info_) = new_group_size; ++ vec old_load_permutation ++ = SLP_TREE_LOAD_PERMUTATION (slp_node); ++ SLP_TREE_LOAD_PERMUTATION (slp_node) = new_load_permutation; ++ bool perm_load_success = vect_transform_slp_perm_load ( ++ vinfo, slp_node, dr_chain, gsi, vf, ++ false, &n_perms); ++ DR_GROUP_SIZE (stmt_info_) = old_size; ++ SLP_TREE_LOAD_PERMUTATION (slp_node) = old_load_permutation; ++ new_load_permutation.release (); ++ if (!perm_load_success) ++ { ++ dr_chain.release (); ++ return false; ++ } ++ } ++ else if (slp_perm) + { + unsigned n_perms; + /* For SLP we know we've seen all possible uses of dr_chain so +diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h +index 642eb0aeb..e13bc6c99 100644 +--- a/gcc/tree-vectorizer.h ++++ b/gcc/tree-vectorizer.h +@@ -412,6 +412,21 @@ public: + vec ddrs; + }; + ++/* Information about offset in vectorizable_load. */ ++struct offset_info { ++ tree offset; ++ tree byte_offset; ++ tree dataref_offset; ++}; ++ ++/* Information about vectype in vectorizable_load. */ ++struct vectype_info { ++ tree vectype; ++ tree ltype; ++ tree lvectype; ++ tree ref_type; ++}; ++ + /* Vectorizer state common between loop and basic-block vectorization. */ + class vec_info { + public: +@@ -455,6 +470,14 @@ public: + stmt in the chain. */ + auto_vec grouped_stores; + ++ /* All interleaving chains of loads, represented by the first ++ stmt in the chain. */ ++ auto_vec grouped_loads; ++ ++ /* All interleaving chains of stores (before transposed), represented by all ++ stmt in the chain. */ ++ auto_vec > scalar_stores; ++ + /* The set of vector modes used in the vectorized region. */ + mode_set used_vector_modes; + +@@ -899,6 +922,8 @@ public: + #define LOOP_VINFO_CHECK_NONZERO(L) (L)->check_nonzero + #define LOOP_VINFO_LOWER_BOUNDS(L) (L)->lower_bounds + #define LOOP_VINFO_GROUPED_STORES(L) (L)->grouped_stores ++#define LOOP_VINFO_GROUPED_LOADS(L) (L)->grouped_loads ++#define LOOP_VINFO_SCALAR_STORES(L) (L)->scalar_stores + #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances + #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor + #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions +@@ -982,6 +1007,25 @@ public: + vec bbs; + + vec roots; ++ ++ /* True, if bb_vinfo can goto vect_analyze_slp. */ ++ bool before_slp; ++ ++ /* True, if bb_vinfo is a transposed version. */ ++ bool transposed; ++ ++ /* The number of transposed groups. */ ++ int transposed_group; ++ ++ /* The cost of the scalar iterations. */ ++ int scalar_cost; ++ ++ /* The cost of the vector prologue and epilogue, including peeled ++ iterations and set-up code. */ ++ int vec_outside_cost; ++ ++ /* The cost of the vector loop body. */ ++ int vec_inside_cost; + } *bb_vec_info; + + #define BB_VINFO_BB(B) (B)->bb +@@ -989,6 +1033,14 @@ public: + #define BB_VINFO_SLP_INSTANCES(B) (B)->slp_instances + #define BB_VINFO_DATAREFS(B) (B)->shared->datarefs + #define BB_VINFO_DDRS(B) (B)->shared->ddrs ++#define BB_VINFO_GROUPED_LOADS(B) (B)->grouped_loads ++#define BB_VINFO_SCALAR_STORES(B) (B)->scalar_stores ++#define BB_VINFO_VEC_OUTSIDE_COST(B) (B)->vec_outside_cost ++#define BB_VINFO_VEC_INSIDE_COST(B) (B)->vec_inside_cost ++#define BB_VINFO_SCALAR_COST(B) (B)->scalar_cost ++#define BB_VINFO_SLP_TRANSPOSED(B) (B)->transposed ++#define BB_VINFO_BEFORE_SLP(B) (B)->before_slp ++#define BB_VINFO_TRANS_GROUPS(B) (B)->transposed_group + + /*-----------------------------------------------------------------*/ + /* Info on vectorized defs. */ +@@ -1219,6 +1271,17 @@ public: + stmt_vec_info next_element; + /* The size of the group. */ + unsigned int size; ++ ++ /* The size of the group before transposed. */ ++ unsigned int size_before_transpose; ++ ++ /* If true, the stmt_info is slp transposed. */ ++ bool slp_transpose; ++ ++ /* Mark the group store number for rebuild interleaving chain ++ during transpose phase. Value -1 represents unable to transpose. */ ++ int group_number; ++ + /* For stores, number of stores from this group seen. We vectorize the last + one. */ + unsigned int store_count; +@@ -1226,6 +1289,9 @@ public: + is 1. */ + unsigned int gap; + ++ /* The gap before transposed. */ ++ unsigned int gap_before_transpose; ++ + /* The minimum negative dependence distance this stmt participates in + or zero if none. */ + unsigned int min_neg_dist; +@@ -1427,6 +1493,12 @@ struct gather_scatter_info { + #define STMT_VINFO_SLP_VECT_ONLY(S) (S)->slp_vect_only_p + #define STMT_VINFO_SLP_VECT_ONLY_PATTERN(S) (S)->slp_vect_pattern_only_p + ++#define DR_GROUP_SLP_TRANSPOSE(S) \ ++ (gcc_checking_assert ((S)->dr_aux.dr), (S)->slp_transpose) ++#define DR_GROUP_SIZE_TRANS(S) \ ++ (gcc_checking_assert ((S)->dr_aux.dr), (S)->size_before_transpose) ++#define DR_GROUP_NUMBER(S) \ ++ (gcc_checking_assert ((S)->dr_aux.dr), (S)->group_number) + #define DR_GROUP_FIRST_ELEMENT(S) \ + (gcc_checking_assert ((S)->dr_aux.dr), (S)->first_element) + #define DR_GROUP_NEXT_ELEMENT(S) \ +@@ -1437,6 +1509,8 @@ struct gather_scatter_info { + (gcc_checking_assert ((S)->dr_aux.dr), (S)->store_count) + #define DR_GROUP_GAP(S) \ + (gcc_checking_assert ((S)->dr_aux.dr), (S)->gap) ++#define DR_GROUP_GAP_TRANS(S) \ ++ (gcc_checking_assert ((S)->dr_aux.dr), (S)->gap_before_transpose) + + #define REDUC_GROUP_FIRST_ELEMENT(S) \ + (gcc_checking_assert (!(S)->dr_aux.dr), (S)->first_element) +@@ -2033,6 +2107,17 @@ vect_get_scalar_dr_size (dr_vec_info *dr_info) + return tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr_info->dr)))); + } + ++/* Compare two unsigned int A and B. ++ Sorting them in ascending order. */ ++ ++static inline int ++cmp_for_group_num (const void *a_, const void *b_) ++{ ++ unsigned int a = *(unsigned int *)const_cast(a_); ++ unsigned int b = *(unsigned int *)const_cast(b_); ++ return a < b ? -1 : 1; ++} ++ + /* Return true if LOOP_VINFO requires a runtime check for whether the + vector loop is profitable. */ + +@@ -2152,7 +2237,7 @@ record_stmt_cost (stmt_vector_for_cost *body_cost_vec, int count, + + extern void vect_finish_replace_stmt (vec_info *, stmt_vec_info, gimple *); + extern void vect_finish_stmt_generation (vec_info *, stmt_vec_info, gimple *, +- gimple_stmt_iterator *); ++ gimple_stmt_iterator *,bool transpose=false); + extern opt_result vect_mark_stmts_to_be_vectorized (loop_vec_info, bool *); + extern tree vect_get_store_rhs (stmt_vec_info); + void vect_get_vec_defs_for_operand (vec_info *vinfo, stmt_vec_info, unsigned, +@@ -2168,7 +2253,7 @@ void vect_get_vec_defs (vec_info *, stmt_vec_info, slp_tree, unsigned, + tree = NULL, vec * = NULL, tree = NULL, + tree = NULL, vec * = NULL, tree = NULL); + extern tree vect_init_vector (vec_info *, stmt_vec_info, tree, tree, +- gimple_stmt_iterator *); ++ gimple_stmt_iterator *, bool transpose=false); + extern tree vect_get_slp_vect_def (slp_tree, unsigned); + extern bool vect_transform_stmt (vec_info *, stmt_vec_info, + gimple_stmt_iterator *, +@@ -2235,6 +2320,9 @@ extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT, bool); + extern void vect_permute_store_chain (vec_info *, vec &, + unsigned int, stmt_vec_info, + gimple_stmt_iterator *, vec *); ++extern void vect_transpose_store_chain (vec_info *, vec, unsigned int, ++ unsigned int, stmt_vec_info, ++ gimple_stmt_iterator *, vec *); + extern tree vect_setup_realignment (vec_info *, + stmt_vec_info, gimple_stmt_iterator *, + tree *, enum dr_alignment_support, tree, +@@ -2262,7 +2350,8 @@ extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree, + enum tree_code); + extern bool needs_fold_left_reduction_p (tree, code_helper); + /* Drive for loop analysis stage. */ +-extern opt_loop_vec_info vect_analyze_loop (class loop *, vec_info_shared *); ++extern opt_loop_vec_info vect_analyze_loop (class loop *, vec_info_shared *, ++ bool result_only_p = false); + extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL); + extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, + tree *, bool); +@@ -2331,6 +2420,7 @@ extern bool vect_transform_slp_perm_load (vec_info *, slp_tree, const vec + gimple_stmt_iterator *, poly_uint64, + bool, unsigned *, + unsigned * = nullptr, bool = false); ++extern void vect_transform_back_slp_grouped_stores (bb_vec_info, stmt_vec_info); + extern bool vect_slp_analyze_operations (vec_info *); + extern void vect_schedule_slp (vec_info *, const vec &); + extern opt_result vect_analyze_slp (vec_info *, unsigned); +-- +2.33.0 + diff --git a/0100-Add-hip09-machine-discribtion.patch b/0100-Add-hip09-machine-discribtion.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2221d937ecabd58db19b1e0f7782a57a83ac638 --- /dev/null +++ b/0100-Add-hip09-machine-discribtion.patch @@ -0,0 +1,882 @@ +From d9131757175667d35e74d9ee84689039990af768 Mon Sep 17 00:00:00 2001 +From: xingyushuai +Date: Fri, 3 Mar 2023 09:31:04 +0800 +Subject: [PATCH 001/157] Add hip09 machine discribtion + +Here is the patch introducing hip09 machine model +for the scheduler. +--- + gcc/config/aarch64/aarch64-cores.def | 1 + + gcc/config/aarch64/aarch64-cost-tables.h | 104 +++++ + gcc/config/aarch64/aarch64-tune.md | 2 +- + gcc/config/aarch64/aarch64.cc | 109 +++++ + gcc/config/aarch64/aarch64.md | 1 + + gcc/config/aarch64/hip09.md | 558 +++++++++++++++++++++++ + 6 files changed, 774 insertions(+), 1 deletion(-) + create mode 100644 gcc/config/aarch64/hip09.md + +diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def +index 70b11eb80..a854bdb24 100644 +--- a/gcc/config/aarch64/aarch64-cores.def ++++ b/gcc/config/aarch64/aarch64-cores.def +@@ -130,6 +130,7 @@ AARCH64_CORE("a64fx", a64fx, a64fx, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F + + /* HiSilicon ('H') cores. */ + AARCH64_CORE("tsv110", tsv110, tsv110, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2, tsv110, 0x48, 0xd01, -1) ++AARCH64_CORE("hip09", hip09, hip09, 8_5A, AARCH64_FL_FOR_ARCH8_5 | AARCH64_FL_SVE | AARCH64_FL_I8MM | AARCH64_FL_F32MM | AARCH64_FL_F64MM | AARCH64_FL_PROFILE | AARCH64_FL_PREDRES, hip09, 0x48, 0xd02, 0x0) + + /* ARMv8.3-A Architecture Processors. */ + +diff --git a/gcc/config/aarch64/aarch64-cost-tables.h b/gcc/config/aarch64/aarch64-cost-tables.h +index 48522606f..fc5a3cbe4 100644 +--- a/gcc/config/aarch64/aarch64-cost-tables.h ++++ b/gcc/config/aarch64/aarch64-cost-tables.h +@@ -668,6 +668,110 @@ const struct cpu_cost_table a64fx_extra_costs = + } + }; + ++const struct cpu_cost_table hip09_extra_costs = ++{ ++ /* ALU */ ++ { ++ 0, /* arith. */ ++ 0, /* logical. */ ++ 0, /* shift. */ ++ 0, /* shift_reg. */ ++ COSTS_N_INSNS (1), /* arith_shift. */ ++ COSTS_N_INSNS (1), /* arith_shift_reg. */ ++ COSTS_N_INSNS (1), /* log_shift. */ ++ COSTS_N_INSNS (1), /* log_shift_reg. */ ++ 0, /* extend. */ ++ COSTS_N_INSNS (1), /* extend_arith. */ ++ 0, /* bfi. */ ++ 0, /* bfx. */ ++ 0, /* clz. */ ++ 0, /* rev. */ ++ 0, /* non_exec. */ ++ true /* non_exec_costs_exec. */ ++ }, ++ ++ { ++ /* MULT SImode */ ++ { ++ COSTS_N_INSNS (2), /* simple. */ ++ COSTS_N_INSNS (2), /* flag_setting. */ ++ COSTS_N_INSNS (2), /* extend. */ ++ COSTS_N_INSNS (2), /* add. */ ++ COSTS_N_INSNS (2), /* extend_add. */ ++ COSTS_N_INSNS (11) /* idiv. */ ++ }, ++ /* MULT DImode */ ++ { ++ COSTS_N_INSNS (3), /* simple. */ ++ 0, /* flag_setting (N/A). */ ++ COSTS_N_INSNS (3), /* extend. */ ++ COSTS_N_INSNS (3), /* add. */ ++ COSTS_N_INSNS (3), /* extend_add. */ ++ COSTS_N_INSNS (19) /* idiv. */ ++ } ++ }, ++ /* LD/ST */ ++ { ++ COSTS_N_INSNS (3), /* load. */ ++ COSTS_N_INSNS (4), /* load_sign_extend. */ ++ COSTS_N_INSNS (3), /* ldrd. */ ++ COSTS_N_INSNS (3), /* ldm_1st. */ ++ 1, /* ldm_regs_per_insn_1st. */ ++ 2, /* ldm_regs_per_insn_subsequent. */ ++ COSTS_N_INSNS (4), /* loadf. */ ++ COSTS_N_INSNS (4), /* loadd. */ ++ COSTS_N_INSNS (4), /* load_unaligned. */ ++ 0, /* store. */ ++ 0, /* strd. */ ++ 0, /* stm_1st. */ ++ 1, /* stm_regs_per_insn_1st. */ ++ 2, /* stm_regs_per_insn_subsequent. */ ++ 0, /* storef. */ ++ 0, /* stored. */ ++ COSTS_N_INSNS (1), /* store_unaligned. */ ++ COSTS_N_INSNS (4), /* loadv. */ ++ COSTS_N_INSNS (4) /* storev. */ ++ }, ++ { ++ /* FP SFmode */ ++ { ++ COSTS_N_INSNS (10), /* div. */ ++ COSTS_N_INSNS (4), /* mult. */ ++ COSTS_N_INSNS (4), /* mult_addsub. */ ++ COSTS_N_INSNS (4), /* fma. */ ++ COSTS_N_INSNS (4), /* addsub. */ ++ COSTS_N_INSNS (1), /* fpconst. */ ++ COSTS_N_INSNS (1), /* neg. */ ++ COSTS_N_INSNS (1), /* compare. */ ++ COSTS_N_INSNS (2), /* widen. */ ++ COSTS_N_INSNS (2), /* narrow. */ ++ COSTS_N_INSNS (2), /* toint. */ ++ COSTS_N_INSNS (1), /* fromint. */ ++ COSTS_N_INSNS (2) /* roundint. */ ++ }, ++ /* FP DFmode */ ++ { ++ COSTS_N_INSNS (17), /* div. */ ++ COSTS_N_INSNS (4), /* mult. */ ++ COSTS_N_INSNS (6), /* mult_addsub. */ ++ COSTS_N_INSNS (6), /* fma. */ ++ COSTS_N_INSNS (3), /* addsub. */ ++ COSTS_N_INSNS (1), /* fpconst. */ ++ COSTS_N_INSNS (1), /* neg. */ ++ COSTS_N_INSNS (1), /* compare. */ ++ COSTS_N_INSNS (2), /* widen. */ ++ COSTS_N_INSNS (2), /* narrow. */ ++ COSTS_N_INSNS (2), /* toint. */ ++ COSTS_N_INSNS (1), /* fromint. */ ++ COSTS_N_INSNS (2) /* roundint. */ ++ } ++ }, ++ /* Vector */ ++ { ++ COSTS_N_INSNS (1) /* alu. */ ++ } ++}; ++ + const struct cpu_cost_table ampere1_extra_costs = + { + /* ALU */ +diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md +index 9dc9adc70..238bb6e31 100644 +--- a/gcc/config/aarch64/aarch64-tune.md ++++ b/gcc/config/aarch64/aarch64-tune.md +@@ -1,5 +1,5 @@ + ;; -*- buffer-read-only: t -*- + ;; Generated automatically by gentune.sh from aarch64-cores.def + (define_attr "tune" +- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,demeter,neoversev2" ++ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,hip09,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,demeter,neoversev2" + (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 5537a537c..e9b3980c4 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -465,6 +465,22 @@ static const struct cpu_addrcost_table tsv110_addrcost_table = + 0, /* imm_offset */ + }; + ++static const struct cpu_addrcost_table hip09_addrcost_table = ++{ ++ { ++ 1, /* hi */ ++ 0, /* si */ ++ 0, /* di */ ++ 1, /* ti */ ++ }, ++ 0, /* pre_modify */ ++ 0, /* post_modify */ ++ 0, /* register_offset */ ++ 1, /* register_sextend */ ++ 1, /* register_zextend */ ++ 0, /* imm_offset */ ++}; ++ + static const struct cpu_addrcost_table qdf24xx_addrcost_table = + { + { +@@ -660,6 +676,16 @@ static const struct cpu_regmove_cost a64fx_regmove_cost = + 2 /* FP2FP */ + }; + ++static const struct cpu_regmove_cost hip09_regmove_cost = ++{ ++ 1, /* GP2GP */ ++ /* Avoid the use of slow int<->fp moves for spilling by setting ++ their cost higher than memmov_cost. */ ++ 2, /* GP2FP */ ++ 3, /* FP2GP */ ++ 2 /* FP2FP */ ++}; ++ + static const struct cpu_regmove_cost neoversen2_regmove_cost = + { + 1, /* GP2GP */ +@@ -947,6 +973,43 @@ static const struct cpu_vector_cost tsv110_vector_cost = + nullptr /* issue_info */ + }; + ++static const advsimd_vec_cost hip09_advsimd_vector_cost = ++{ ++ 2, /* int_stmt_cost */ ++ 2, /* fp_stmt_cost */ ++ 0, /* ld2_st2_permute_cost */ ++ 0, /* ld3_st3_permute_cost */ ++ 0, /* ld4_st4_permute_cost */ ++ 2, /* permute_cost */ ++ 3, /* reduc_i8_cost */ ++ 3, /* reduc_i16_cost */ ++ 3, /* reduc_i32_cost */ ++ 3, /* reduc_i64_cost */ ++ 3, /* reduc_f16_cost */ ++ 3, /* reduc_f32_cost */ ++ 3, /* reduc_f64_cost */ ++ 3, /* store_elt_extra_cost */ ++ 3, /* vec_to_scalar_cost */ ++ 2, /* scalar_to_vec_cost */ ++ 5, /* align_load_cost */ ++ 5, /* unalign_load_cost */ ++ 1, /* unalign_store_cost */ ++ 1 /* store_cost */ ++}; ++ ++static const struct cpu_vector_cost hip09_vector_cost = ++{ ++ 1, /* scalar_int_stmt_cost */ ++ 1, /* scalar_fp_stmt_cost */ ++ 5, /* scalar_load_cost */ ++ 1, /* scalar_store_cost */ ++ 1, /* cond_taken_branch_cost */ ++ 1, /* cond_not_taken_branch_cost */ ++ &hip09_advsimd_vector_cost, /* advsimd */ ++ nullptr, /* sve */ ++ nullptr /* issue_info */ ++}; ++ + static const advsimd_vec_cost cortexa57_advsimd_vector_cost = + { + 2, /* int_stmt_cost */ +@@ -1293,6 +1356,18 @@ static const cpu_prefetch_tune tsv110_prefetch_tune = + -1 /* default_opt_level */ + }; + ++ ++static const cpu_prefetch_tune hip09_prefetch_tune = ++{ ++ 0, /* num_slots */ ++ 64, /* l1_cache_size */ ++ 64, /* l1_cache_line_size */ ++ 512, /* l2_cache_size */ ++ true, /* prefetch_dynamic_strides */ ++ -1, /* minimum_stride */ ++ -1 /* default_opt_level */ ++}; ++ + static const cpu_prefetch_tune xgene1_prefetch_tune = + { + 8, /* num_slots */ +@@ -1658,6 +1733,40 @@ static const struct tune_params tsv110_tunings = + &tsv110_prefetch_tune + }; + ++static const struct tune_params hip09_tunings = ++{ ++ &hip09_extra_costs, ++ &hip09_addrcost_table, ++ &hip09_regmove_cost, ++ &hip09_vector_cost, ++ &generic_branch_cost, ++ &generic_approx_modes, ++ SVE_256, /* sve_width */ ++ { 4, /* load_int. */ ++ 4, /* store_int. */ ++ 4, /* load_fp. */ ++ 4, /* store_fp. */ ++ 4, /* load_pred. */ ++ 4 /* store_pred. */ ++ }, /* memmov_cost. */ ++ 4, /* issue_rate */ ++ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_ALU_BRANCH ++ | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */ ++ "16", /* function_align. */ ++ "4", /* jump_align. */ ++ "8", /* loop_align. */ ++ 2, /* int_reassoc_width. */ ++ 4, /* fp_reassoc_width. */ ++ 1, /* vec_reassoc_width. */ ++ 2, /* min_div_recip_mul_sf. */ ++ 2, /* min_div_recip_mul_df. */ ++ 0, /* max_case_values. */ ++ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */ ++ (AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS ++ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */ ++ &hip09_prefetch_tune ++}; ++ + static const struct tune_params xgene1_tunings = + { + &xgene1_extra_costs, +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index d24c8afcf..cf699e4c7 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -477,6 +477,7 @@ + (include "thunderx2t99.md") + (include "tsv110.md") + (include "thunderx3t110.md") ++(include "hip09.md") + + ;; ------------------------------------------------------------------- + ;; Jumps and other miscellaneous insns +diff --git a/gcc/config/aarch64/hip09.md b/gcc/config/aarch64/hip09.md +new file mode 100644 +index 000000000..25428de9a +--- /dev/null ++++ b/gcc/config/aarch64/hip09.md +@@ -0,0 +1,558 @@ ++;; hip09 pipeline description ++;; Copyright (C) 2023 Free Software Foundation, Inc. ++;; ++;;Contributed by Yushuai Xing ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify it ++;; under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, but ++;; WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++;; General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++(define_automaton "hip09") ++(define_automaton "hip09_ldst") ++(define_automaton "hip09_fsu") ++ ++(define_attr "hip09_type" ++ "hip09_neon_abs, hip09_neon_fp_arith, hip09_neon_mul, hip09_neon_mla, ++ hip09_neon_dot, hip09_neon_fp_div, hip09_neon_fp_sqrt, ++ hip09_neon_ins, hip09_neon_load1, hip09_neon_load1_lanes, ++ hip09_neon_load2and4, hip09_neon_load3_3reg, ++ hip09_neon_load4_4reg, hip09_neon_store1and2, ++ hip09_neon_store1_1reg, hip09_neon_store1_2reg, ++ hip09_neon_store1_3reg, hip09_neon_store1_4reg, ++ hip09_neon_store3and4_lane, hip09_neon_store3_3reg, ++ hip09_neon_store4_4reg, unknown" ++ (cond [ ++ (eq_attr "type" "neon_abs,neon_abs_q,neon_add,neon_add_q,\ ++ neon_neg,neon_neg_q,neon_sub,neon_sub_q,neon_add_widen,\ ++ neon_sub_widen,neon_qadd,neon_qadd_q,\ ++ neon_add_long,neon_sub_long,\ ++ neon_qabs,neon_qabs_q,neon_qneg,\ ++ neon_qneg_q,neon_qsub,neon_qsub_q,neon_compare,\ ++ neon_compare_q,neon_compare_zero,\ ++ neon_compare_zero_q,neon_logic,neon_logic_q,\ ++ neon_minmax,neon_minmax_q,neon_tst,\ ++ neon_tst_q,neon_bsl,neon_bsl_q,\ ++ neon_cls,neon_cls_q,neon_ext,\ ++ neon_ext_q,neon_rev,neon_rev_q,\ ++ neon_tbl1,neon_tbl1_q,neon_fp_abs_s,\ ++ neon_fp_abs_s_q,neon_fp_abs_d,\ ++ neon_fp_neg_s,neon_fp_neg_s_q,\ ++ neon_fp_neg_d,neon_fp_neg_d_q,\ ++ neon_shift_imm_narrow_q,neon_move,neon_move_q") ++ (const_string "hip09_neon_abs") ++ (eq_attr "type" "neon_abd,neon_abd_q,\ ++ neon_arith_acc,neon_arith_acc_q,\ ++ neon_add_halve,neon_add_halve_q,\ ++ neon_sub_halve,neon_sub_halve_q,\ ++ neon_add_halve_narrow_q,\ ++ neon_sub_halve_narrow_q,neon_reduc_add,\ ++ neon_reduc_add_q,\ ++ neon_sat_mul_b,neon_sat_mul_b_q,\ ++ neon_sat_mul_b_long,neon_mul_b,neon_mul_b_q,\ ++ neon_mul_b_long,neon_mla_b,neon_mla_b_q,\ ++ neon_mla_b_long,neon_sat_mla_b_long,\ ++ neon_sat_shift_imm,\ ++ neon_sat_shift_imm_q,neon_shift_imm_long,\ ++ neon_shift_imm,neon_shift_imm_q,neon_cnt,\ ++ neon_cnt_q,neon_fp_recpe_s,neon_fp_recpe_s_q,\ ++ neon_fp_recpe_d,neon_fp_recpe_d_q,\ ++ neon_fp_rsqrte_s,neon_fp_rsqrte_s_q,\ ++ neon_fp_rsqrte_d,neon_fp_rsqrte_d_q,\ ++ neon_fp_recpx_s,neon_fp_recpx_s_q,\ ++ neon_fp_recpx_d,neon_fp_recpx_d_q,\ ++ neon_tbl2,neon_tbl2_q,neon_to_gp,\ ++ neon_to_gp_q,neon_fp_abd_s,neon_fp_abd_s_q,\ ++ neon_fp_abd_d,neon_fp_abd_d_q,\ ++ neon_fp_addsub_s,neon_fp_addsub_s_q,\ ++ neon_fp_addsub_d,neon_fp_addsub_d_q,\ ++ neon_fp_compare_s,neon_fp_compare_s_q,\ ++ neon_fp_compare_d,neon_fp_compare_d_q,\ ++ neon_fp_cvt_widen_s,neon_fp_to_int_s,\ ++ neon_fp_to_int_s_q,neon_fp_to_int_d,\ ++ neon_fp_to_int_d_q,neon_fp_minmax_s,\ ++ neon_fp_minmax_s_q,neon_fp_minmax_d,\ ++ neon_fp_minmax_d_q,neon_fp_round_s,\ ++ neon_fp_round_s_q,neon_fp_cvt_narrow_d_q,\ ++ neon_fp_round_d,neon_fp_round_d_q,\ ++ neon_fp_cvt_narrow_s_q") ++ (const_string "hip09_neon_fp_arith") ++ (eq_attr "type" "neon_sat_mul_h,neon_sat_mul_h_q,\ ++ neon_sat_mul_s,neon_sat_mul_s_q,\ ++ neon_sat_mul_h_scalar,neon_sat_mul_s_scalar,\ ++ neon_sat_mul_h_scalar_q,neon_sat_mul_h_long,\ ++ neon_sat_mul_s_long,neon_sat_mul_h_scalar_long,\ ++ neon_sat_mul_s_scalar_long,neon_mul_h,neon_mul_h_q,\ ++ neon_mul_s,neon_mul_s_q,neon_mul_h_long,\ ++ neon_mul_s_long,neon_mul_h_scalar_long,\ ++ neon_mul_s_scalar_long,neon_mla_h,neon_mla_h_q,\ ++ neon_mla_s,neon_mla_h_scalar,\ ++ neon_mla_h_scalar_q,neon_mla_s_scalar,\ ++ neon_mla_h_long,\ ++ neon_mla_s_long,neon_sat_mla_h_long,\ ++ neon_sat_mla_s_long,neon_sat_mla_h_scalar_long,\ ++ neon_sat_mla_s_scalar_long,neon_mla_s_scalar_long,\ ++ neon_mla_h_scalar_long,neon_mla_s_scalar_q,\ ++ neon_shift_acc,neon_shift_acc_q,neon_shift_reg,\ ++ neon_shift_reg_q,neon_sat_shift_reg,\ ++ neon_sat_shift_reg_q,neon_sat_shift_imm_narrow_q,\ ++ neon_tbl3,neon_tbl3_q,neon_fp_reduc_add_s,\ ++ neon_fp_reduc_add_s_q,neon_fp_reduc_add_d,\ ++ neon_fp_reduc_add_d_q,neon_fp_reduc_minmax_s,\ ++ neon_fp_reduc_minmax_d,neon_fp_reduc_minmax_s_q,\ ++ neon_fp_reduc_minmax_d_q,\ ++ neon_fp_mul_s_q,\ ++ neon_fp_mul_d,neon_fp_mul_d_q,\ ++ neon_fp_mul_d_scalar_q,neon_fp_mul_s_scalar,\ ++ neon_fp_mul_s_scalar_q") ++ (const_string "hip09_neon_mul") ++ (eq_attr "type" "neon_mla_s_q,neon_reduc_minmax,\ ++ neon_reduc_minmax_q,neon_fp_recps_s,\ ++ neon_fp_recps_s_q,neon_fp_recps_d,\ ++ neon_fp_recps_d_q,neon_tbl4,neon_tbl4_q,\ ++ neon_fp_mla_s,\ ++ neon_fp_mla_d,neon_fp_mla_d_q,\ ++ neon_fp_mla_s_scalar,neon_fp_mla_s_scalar_q,\ ++ neon_fp_mla_d_scalar_q") ++ (const_string "hip09_neon_mla") ++ (eq_attr "type" "neon_dot,neon_dot_q") ++ (const_string "hip09_neon_dot") ++ (eq_attr "type" "neon_fp_div_s,neon_fp_div_s_q,\ ++ neon_fp_div_d,neon_fp_div_d_q") ++ (const_string "hip09_neon_fp_div") ++ (eq_attr "type" "neon_fp_sqrt_s,neon_fp_sqrt_s_q,\ ++ neon_fp_sqrt_d,neon_fp_sqrt_d_q") ++ (const_string "hip09_neon_fp_sqrt") ++ (eq_attr "type" "neon_dup,neon_dup_q,\ ++ neon_ins,neon_ins_q") ++ (const_string "hip09_neon_ins") ++ (eq_attr "type" "neon_load1_1reg,neon_load1_1reg_q,\ ++ neon_load1_2reg,neon_load1_2reg_q,\ ++ neon_load1_3reg,neon_load1_3reg_q,\ ++ neon_load1_4reg,neon_load1_4reg_q") ++ (const_string "hip09_neon_load1") ++ (eq_attr "type" "neon_load1_one_lane,\ ++ neon_load1_one_lane_q,\ ++ neon_load1_all_lanes,neon_load1_all_lanes_q") ++ (const_string "hip09_neon_load1_lanes") ++ (eq_attr "type" "neon_load2_all_lanes,\ ++ neon_load2_all_lanes_q,\ ++ neon_load2_one_lane,neon_load2_2reg,\ ++ neon_load2_2reg_q,neon_load3_one_lane,\ ++ neon_load3_all_lanes,neon_load3_all_lanes_q,\ ++ neon_load4_one_lane,neon_load4_all_lanes,\ ++ neon_load4_all_lanes_q") ++ (const_string "hip09_neon_load2and4") ++ (eq_attr "type" "neon_load3_3reg,neon_load3_3reg_q") ++ (const_string "hip09_neon_load3_3reg") ++ (eq_attr "type" "neon_load4_4reg,neon_load4_4reg_q") ++ (const_string "hip09_neon_load4_4reg") ++ (eq_attr "type" "neon_store1_one_lane,\ ++ neon_store1_one_lane_q,neon_store2_one_lane,\ ++ neon_store2_one_lane_q,neon_store2_2reg,\ ++ neon_store2_2reg_q") ++ (const_string "hip09_neon_store1and2") ++ (eq_attr "type" "neon_store1_1reg,neon_store1_1reg_q") ++ (const_string "hip09_neon_store1_1reg") ++ (eq_attr "type" "neon_store1_2reg,neon_store1_2reg_q") ++ (const_string "hip09_neon_store1_2reg") ++ (eq_attr "type" "neon_store1_3reg,neon_store1_3reg_q") ++ (const_string "hip09_neon_store1_3reg") ++ (eq_attr "type" "neon_store1_4reg,neon_store1_4reg_q") ++ (const_string "hip09_neon_store1_4reg") ++ (eq_attr "type" "neon_store3_one_lane,\ ++ neon_store3_one_lane_q,neon_store4_one_lane,\ ++ neon_store4_one_lane_q") ++ (const_string "hip09_neon_store3and4_lane") ++ (eq_attr "type" "neon_store3_3reg,\ ++ neon_store3_3reg_q") ++ (const_string "hip09_neon_store3_3reg") ++ (eq_attr "type" "neon_store4_4reg,\ ++ neon_store4_4reg_q") ++ (const_string "hip09_neon_store4_4reg")] ++ (const_string "unknown"))) ++ ++; The hip09 core is modelled as issues pipeline that has ++; the following functional units. ++; 1. Two pipelines for branch micro operations: BRU1, BRU2 ++ ++(define_cpu_unit "hip09_bru0" "hip09") ++(define_cpu_unit "hip09_bru1" "hip09") ++ ++(define_reservation "hip09_bru01" "hip09_bru0|hip09_bru1") ++ ++; 2. Four pipelines for single cycle integer micro operations: ALUs1, ALUs2, ALUs3, ALUs4 ++ ++(define_cpu_unit "hip09_alus0" "hip09") ++(define_cpu_unit "hip09_alus1" "hip09") ++(define_cpu_unit "hip09_alus2" "hip09") ++(define_cpu_unit "hip09_alus3" "hip09") ++ ++(define_reservation "hip09_alus0123" "hip09_alus0|hip09_alus1|hip09_alus2|hip09_alus3") ++(define_reservation "hip09_alus01" "hip09_alus0|hip09_alus1") ++(define_reservation "hip09_alus23" "hip09_alus2|hip09_alus3") ++ ++; 3. Two pipelines for multi cycles integer micro operations: ALUm1, ALUm2 ++ ++(define_cpu_unit "hip09_alum0" "hip09") ++(define_cpu_unit "hip09_alum1" "hip09") ++ ++(define_reservation "hip09_alum01" "hip09_alum0|hip09_alum1") ++ ++; 4. Two pipelines for load micro opetations: Load1, Load2 ++ ++(define_cpu_unit "hip09_load0" "hip09_ldst") ++(define_cpu_unit "hip09_load1" "hip09_ldst") ++ ++(define_reservation "hip09_ld01" "hip09_load0|hip09_load1") ++ ++; 5. Two pipelines for store micro operations: Store1, Store2 ++ ++(define_cpu_unit "hip09_store0" "hip09_ldst") ++(define_cpu_unit "hip09_store1" "hip09_ldst") ++ ++(define_reservation "hip09_st01" "hip09_store0|hip09_store1") ++ ++; 6. Two pipelines for store data micro operations: STD0,STD1 ++ ++(define_cpu_unit "hip09_store_data0" "hip09_ldst") ++(define_cpu_unit "hip09_store_data1" "hip09_ldst") ++ ++(define_reservation "hip09_std01" "hip09_store_data0|hip09_store_data1") ++ ++; 7. Four asymmetric pipelines for Asimd and FP micro operations: FSU1, FSU2, FSU3, FSU4 ++ ++(define_cpu_unit "hip09_fsu0" "hip09_fsu") ++(define_cpu_unit "hip09_fsu1" "hip09_fsu") ++(define_cpu_unit "hip09_fsu2" "hip09_fsu") ++(define_cpu_unit "hip09_fsu3" "hip09_fsu") ++ ++(define_reservation "hip09_fsu0123" "hip09_fsu0|hip09_fsu1|hip09_fsu2|hip09_fsu3") ++(define_reservation "hip09_fsu02" "hip09_fsu0|hip09_fsu2") ++ ++ ++; 8. Two pipelines for sve operations but same with fsu1 and fsu3: SVE1, SVE2 ++ ++;; Simple Execution Unit: ++; ++;; Simple ALU without shift ++(define_insn_reservation "hip09_alu" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "alu_imm,logic_imm,\ ++ adc_imm,adc_reg,\ ++ alu_sreg,logic_reg,\ ++ mov_imm,mov_reg,\ ++ csel,rotate_imm,bfm,mov_imm,\ ++ clz,rbit,rev")) ++ "hip09_alus0123") ++ ++(define_insn_reservation "hip09_alus" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "alus_sreg,alus_imm,\ ++ adcs_reg,adcs_imm,\ ++ logics_imm,logics_reg,adr")) ++ "hip09_alus23") ++ ++;; ALU ops with shift and extend ++(define_insn_reservation "hip09_alu_ext_shift" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "alu_ext,alus_ext,\ ++ logics_shift_imm,logics_shift_reg,\ ++ logic_shift_reg,logic_shift_imm,\ ++ ")) ++ "hip09_alum01") ++ ++;; Multiplies instructions ++(define_insn_reservation "hip09_mult" 3 ++ (and (eq_attr "tune" "hip09") ++ (ior (eq_attr "mul32" "yes") ++ (eq_attr "widen_mul64" "yes"))) ++ "hip09_alum01") ++ ++;; Integer divide ++(define_insn_reservation "hip09_div" 10 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "udiv,sdiv")) ++ "hip09_alum0") ++ ++;; Branch execution Unit ++; ++; Branches take two issue slot. ++; No latency as there is no result ++(define_insn_reservation "hip09_branch" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "branch,call")) ++ "hip09_bru01 + hip09_alus23") ++ ++;; Load execution Unit ++; ++; Loads of up to two words. ++(define_insn_reservation "hip09_load1" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "load_4,load_8")) ++ "hip09_ld01") ++ ++; Stores of up to two words. ++(define_insn_reservation "hip09_store1" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "store_4,store_8")) ++ "hip09_st01") ++ ++;; FP data processing instructions. ++ ++(define_insn_reservation "hip09_fp_arith" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "ffariths,ffarithd,fmov,fconsts,fconstd,\ ++ f_mrc")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_cmp" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fcmps,fcmpd")) ++ "hip09_fsu0123+hip09_alus23") ++ ++(define_insn_reservation "hip09_fp_ccmp" 7 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fccmps,fccmpd")) ++ "hip09_alus01+hip09_fsu0123+hip09_alus23") ++ ++(define_insn_reservation "hip09_fp_csel" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fcsel,f_mcr")) ++ "hip09_alus01+hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_divs" 7 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fdivs")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_divd" 10 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fdivd")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_sqrts" 9 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fsqrts")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_sqrtd" 15 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fsqrtd")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_mul" 3 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fmuls,fmuld")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_add" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fadds,faddd,f_minmaxs,f_minmaxd,f_cvt,\ ++ f_rints,f_rintd")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_fp_mac" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "fmacs,fmacd")) ++ "hip09_fsu0123") ++ ++;; FP miscellaneous instructions. ++ ++(define_insn_reservation "hip09_fp_cvt" 5 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "f_cvtf2i")) ++ "hip09_fsu0123+hip09_alus23") ++ ++(define_insn_reservation "hip09_fp_cvt2" 5 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "f_cvti2f")) ++ "hip09_alus01+hip09_fsu0123") ++ ++;; FP Load Instructions ++ ++(define_insn_reservation "hip09_fp_load" 7 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "f_loads,f_loadd")) ++ "hip09_ld01") ++ ++(define_insn_reservation "hip09_fp_load2" 6 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "neon_ldp_q,neon_ldp")) ++ "hip09_ld01+hip09_alus01") ++ ++;; FP store instructions ++ ++(define_insn_reservation "hip09_fp_store" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "f_stores,f_stored")) ++ "hip09_st01+hip09_std01") ++ ++;; ASIMD integer instructions ++ ++(define_insn_reservation "hip09_asimd_base1" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_abs")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_base2" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_fp_arith")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_base3" 3 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_mul")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_base4" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_mla")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_base5" 5 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "neon_fp_mul_s")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_dot" 6 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_dot")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_bfmmla" 9 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "neon_fp_mla_s_q")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_fdiv" 15 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_fp_div")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_fsqrt" 25 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_fp_sqrt")) ++ "hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_pmull" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "crypto_pmull")) ++ "hip09_fsu2") ++ ++(define_insn_reservation "hip09_asimd_dup" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_ins")) ++ "hip09_alus01+hip09_fsu0123") ++ ++;; ASIMD load instructions ++ ++(define_insn_reservation "hip09_asimd_ld1_reg" 6 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_load1")) ++ "hip09_ld01") ++ ++(define_insn_reservation "hip09_asimd_ld1_lane" 7 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_load1_lanes")) ++ "hip09_ld01+hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_ld23" 8 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_load2and4")) ++"hip09_ld01+hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_ld3_mtp" 9 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_load3_3reg")) ++ "hip09_ld01+hip09_fsu0123") ++ ++(define_insn_reservation "hip09_asimd_ld4_mtp" 13 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_load4_4reg")) ++ "hip09_ld01+hip09_fsu0123") ++ ++;; ASIMD store instructions ++ ++(define_insn_reservation "hip09_asimd_st12" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store1and2")) ++ "hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st1_1reg" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store1_1reg")) ++ "hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st1_2reg" 3 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store1_2reg")) ++ "hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st1_3reg" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store1_3reg")) ++ "hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st1_4reg" 5 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store1_4reg")) ++ "hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st34_lane" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store3and4_lane")) ++ "hip09_fsu0123+hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st3_mtp" 7 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store3_3reg")) ++ "hip09_fsu0123+hip09_st01+hip09_std01") ++ ++(define_insn_reservation "hip09_asimd_st4_mtp" 10 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "hip09_type" "hip09_neon_store4_4reg")) ++ "hip09_fsu0123+hip09_st01+hip09_std01") ++ ++;; Cryptography extensions ++ ++(define_insn_reservation "hip09_asimd_aes" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "crypto_aese,crypto_aesmc")) ++ "hip09_fsu02") ++ ++(define_insn_reservation "hip09_asimd_sha3" 1 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "crypto_sha3")) ++ "hip09_fsu2") ++ ++(define_insn_reservation "hip09_asimd_sha1" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "crypto_sha1_fast,crypto_sha1_xor,\ ++ crypto_sha256_fast,crypto_sha512,\ ++ crypto_sm3")) ++ "hip09_fsu2") ++ ++(define_insn_reservation "hip09_asimd_sha1_and256" 4 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "crypto_sha1_slow,crypto_sha256_slow,\ ++ crypto_sm4")) ++ "hip09_fsu2") ++ ++;; CRC extension. ++ ++(define_insn_reservation "hip09_crc" 2 ++ (and (eq_attr "tune" "hip09") ++ (eq_attr "type" "crc")) ++ "hip09_alum01") +-- +2.33.0 + diff --git a/0101-Add-hip11-CPU-pipeline-scheduling.patch b/0101-Add-hip11-CPU-pipeline-scheduling.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b89890555fa6f0ccb95e7d657c0ba87ebb745d2 --- /dev/null +++ b/0101-Add-hip11-CPU-pipeline-scheduling.patch @@ -0,0 +1,755 @@ +From 824fccdab1d3c5e87fb88b31f0eeb7abd1b35c1f Mon Sep 17 00:00:00 2001 +From: XingYuShuai <1150775134@qq.com> +Date: Mon, 26 Feb 2024 20:34:06 +0800 +Subject: [PATCH 002/157] Add hip11 CPU pipeline scheduling + +This patch adds an mcpu: hip11. It has been tested on aarch64 +and no regressions from this patch. +--- + gcc/config/aarch64/aarch64-cores.def | 1 + + gcc/config/aarch64/aarch64-cost-tables.h | 104 ++++++ + gcc/config/aarch64/aarch64-tune.md | 2 +- + gcc/config/aarch64/aarch64.cc | 108 ++++++ + gcc/config/aarch64/aarch64.md | 1 + + gcc/config/aarch64/hip11.md | 418 +++++++++++++++++++++++ + gcc/doc/invoke.texi | 2 +- + 7 files changed, 634 insertions(+), 2 deletions(-) + create mode 100644 gcc/config/aarch64/hip11.md + +diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def +index a854bdb24..601b72abb 100644 +--- a/gcc/config/aarch64/aarch64-cores.def ++++ b/gcc/config/aarch64/aarch64-cores.def +@@ -173,6 +173,7 @@ AARCH64_CORE("cortex-a710", cortexa710, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | + AARCH64_CORE("cortex-x2", cortexx2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd48, -1) + + AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversen2, 0x41, 0xd49, -1) ++AARCH64_CORE("hip11", hip11, hip11, 8_5A, AARCH64_FL_FOR_ARCH8_5| AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_F16, hip11, 0x48, 0xd22, -1) + + AARCH64_CORE("demeter", demeter, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) + AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) +diff --git a/gcc/config/aarch64/aarch64-cost-tables.h b/gcc/config/aarch64/aarch64-cost-tables.h +index fc5a3cbe4..0ee427b61 100644 +--- a/gcc/config/aarch64/aarch64-cost-tables.h ++++ b/gcc/config/aarch64/aarch64-cost-tables.h +@@ -561,6 +561,110 @@ const struct cpu_cost_table tsv110_extra_costs = + } + }; + ++const struct cpu_cost_table hip11_extra_costs = ++{ ++ /* ALU */ ++ { ++ 0, /* arith. */ ++ 0, /* logical. */ ++ 0, /* shift. */ ++ 0, /* shift_reg. */ ++ COSTS_N_INSNS (1), /* arith_shift. */ ++ COSTS_N_INSNS (1), /* arith_shift_reg. */ ++ COSTS_N_INSNS (1), /* log_shift. */ ++ COSTS_N_INSNS (1), /* log_shift_reg. */ ++ 0, /* extend. */ ++ COSTS_N_INSNS (1), /* extend_arith. */ ++ 0, /* bfi. */ ++ 0, /* bfx. */ ++ 0, /* clz. */ ++ 0, /* rev. */ ++ 0, /* non_exec. */ ++ true /* non_exec_costs_exec. */ ++ }, ++ ++ { ++ /* MULT SImode */ ++ { ++ COSTS_N_INSNS (2), /* simple. */ ++ COSTS_N_INSNS (2), /* flag_setting. */ ++ COSTS_N_INSNS (2), /* extend. */ ++ COSTS_N_INSNS (2), /* add. */ ++ COSTS_N_INSNS (2), /* extend_add. */ ++ COSTS_N_INSNS (11) /* idiv. */ ++ }, ++ /* MULT DImode */ ++ { ++ COSTS_N_INSNS (3), /* simple. */ ++ 0, /* flag_setting (N/A). */ ++ COSTS_N_INSNS (3), /* extend. */ ++ COSTS_N_INSNS (3), /* add. */ ++ COSTS_N_INSNS (3), /* extend_add. */ ++ COSTS_N_INSNS (19) /* idiv. */ ++ } ++ }, ++ /* LD/ST */ ++ { ++ COSTS_N_INSNS (3), /* load. */ ++ COSTS_N_INSNS (4), /* load_sign_extend. */ ++ COSTS_N_INSNS (3), /* ldrd. */ ++ COSTS_N_INSNS (3), /* ldm_1st. */ ++ 1, /* ldm_regs_per_insn_1st. */ ++ 2, /* ldm_regs_per_insn_subsequent. */ ++ COSTS_N_INSNS (4), /* loadf. */ ++ COSTS_N_INSNS (4), /* loadd. */ ++ COSTS_N_INSNS (4), /* load_unaligned. */ ++ 0, /* store. */ ++ 0, /* strd. */ ++ 0, /* stm_1st. */ ++ 1, /* stm_regs_per_insn_1st. */ ++ 2, /* stm_regs_per_insn_subsequent. */ ++ 0, /* storef. */ ++ 0, /* stored. */ ++ COSTS_N_INSNS (1), /* store_unaligned. */ ++ COSTS_N_INSNS (4), /* loadv. */ ++ COSTS_N_INSNS (4) /* storev. */ ++ }, ++ { ++ /* FP SFmode */ ++ { ++ COSTS_N_INSNS (10), /* div. */ ++ COSTS_N_INSNS (4), /* mult. */ ++ COSTS_N_INSNS (4), /* mult_addsub. */ ++ COSTS_N_INSNS (4), /* fma. */ ++ COSTS_N_INSNS (4), /* addsub. */ ++ COSTS_N_INSNS (1), /* fpconst. */ ++ COSTS_N_INSNS (1), /* neg. */ ++ COSTS_N_INSNS (1), /* compare. */ ++ COSTS_N_INSNS (2), /* widen. */ ++ COSTS_N_INSNS (2), /* narrow. */ ++ COSTS_N_INSNS (2), /* toint. */ ++ COSTS_N_INSNS (1), /* fromint. */ ++ COSTS_N_INSNS (2) /* roundint. */ ++ }, ++ /* FP DFmode */ ++ { ++ COSTS_N_INSNS (17), /* div. */ ++ COSTS_N_INSNS (4), /* mult. */ ++ COSTS_N_INSNS (6), /* mult_addsub. */ ++ COSTS_N_INSNS (6), /* fma. */ ++ COSTS_N_INSNS (3), /* addsub. */ ++ COSTS_N_INSNS (1), /* fpconst. */ ++ COSTS_N_INSNS (1), /* neg. */ ++ COSTS_N_INSNS (1), /* compare. */ ++ COSTS_N_INSNS (2), /* widen. */ ++ COSTS_N_INSNS (2), /* narrow. */ ++ COSTS_N_INSNS (2), /* toint. */ ++ COSTS_N_INSNS (1), /* fromint. */ ++ COSTS_N_INSNS (2) /* roundint. */ ++ } ++ }, ++ /* Vector */ ++ { ++ COSTS_N_INSNS (1) /* alu. */ ++ } ++}; ++ + const struct cpu_cost_table a64fx_extra_costs = + { + /* ALU */ +diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md +index 238bb6e31..511422081 100644 +--- a/gcc/config/aarch64/aarch64-tune.md ++++ b/gcc/config/aarch64/aarch64-tune.md +@@ -1,5 +1,5 @@ + ;; -*- buffer-read-only: t -*- + ;; Generated automatically by gentune.sh from aarch64-cores.def + (define_attr "tune" +- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,hip09,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,demeter,neoversev2" ++ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,hip09,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,hip11,demeter,neoversev2" + (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index e9b3980c4..7c62ddb2a 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -481,6 +481,22 @@ static const struct cpu_addrcost_table hip09_addrcost_table = + 0, /* imm_offset */ + }; + ++static const struct cpu_addrcost_table hip11_addrcost_table = ++{ ++ { ++ 1, /* hi */ ++ 0, /* si */ ++ 0, /* di */ ++ 1, /* ti */ ++ }, ++ 0, /* pre_modify */ ++ 0, /* post_modify */ ++ 0, /* register_offset */ ++ 1, /* register_sextend */ ++ 1, /* register_zextend */ ++ 0, /* imm_offset */ ++}; ++ + static const struct cpu_addrcost_table qdf24xx_addrcost_table = + { + { +@@ -666,6 +682,16 @@ static const struct cpu_regmove_cost tsv110_regmove_cost = + 2 /* FP2FP */ + }; + ++static const struct cpu_regmove_cost hip11_regmove_cost = ++{ ++ 1, /* GP2GP */ ++ /* Avoid the use of slow int<->fp moves for spilling by setting ++ their cost higher than memmov_cost. */ ++ 2, /* GP2FP */ ++ 3, /* FP2GP */ ++ 2 /* FP2FP */ ++}; ++ + static const struct cpu_regmove_cost a64fx_regmove_cost = + { + 1, /* GP2GP */ +@@ -1010,6 +1036,43 @@ static const struct cpu_vector_cost hip09_vector_cost = + nullptr /* issue_info */ + }; + ++static const advsimd_vec_cost hip11_advsimd_vector_cost = ++{ ++ 2, /* int_stmt_cost */ ++ 2, /* fp_stmt_cost */ ++ 0, /* ld2_st2_permute_cost */ ++ 0, /* ld3_st3_permute_cost */ ++ 0, /* ld4_st4_permute_cost */ ++ 2, /* permute_cost */ ++ 3, /* reduc_i8_cost */ ++ 3, /* reduc_i16_cost */ ++ 3, /* reduc_i32_cost */ ++ 3, /* reduc_i64_cost */ ++ 3, /* reduc_f16_cost */ ++ 3, /* reduc_f32_cost */ ++ 3, /* reduc_f64_cost */ ++ 3, /* store_elt_extra_cost */ ++ 5, /* vec_to_scalar_cost */ ++ 5, /* scalar_to_vec_cost */ ++ 5, /* align_load_cost */ ++ 5, /* unalign_load_cost */ ++ 1, /* unalign_store_cost */ ++ 1 /* store_cost */ ++}; ++ ++static const struct cpu_vector_cost hip11_vector_cost = ++{ ++ 1, /* scalar_int_stmt_cost */ ++ 1, /* scalar_fp_stmt_cost */ ++ 5, /* scalar_load_cost */ ++ 1, /* scalar_store_cost */ ++ 1, /* cond_taken_branch_cost */ ++ 1, /* cond_not_taken_branch_cost */ ++ &hip11_advsimd_vector_cost, /* advsimd */ ++ nullptr, /* sve */ ++ nullptr /* issue_info */ ++}; ++ + static const advsimd_vec_cost cortexa57_advsimd_vector_cost = + { + 2, /* int_stmt_cost */ +@@ -1368,6 +1431,17 @@ static const cpu_prefetch_tune hip09_prefetch_tune = + -1 /* default_opt_level */ + }; + ++static const cpu_prefetch_tune hip11_prefetch_tune = ++{ ++ 0, /* num_slots */ ++ 64, /* l1_cache_size */ ++ 64, /* l1_cache_line_size */ ++ 512, /* l2_cache_size */ ++ true, /* prefetch_dynamic_strides */ ++ -1, /* minimum_stride */ ++ -1 /* default_opt_level */ ++}; ++ + static const cpu_prefetch_tune xgene1_prefetch_tune = + { + 8, /* num_slots */ +@@ -1767,6 +1841,40 @@ static const struct tune_params hip09_tunings = + &hip09_prefetch_tune + }; + ++static const struct tune_params hip11_tunings = ++{ ++ &hip11_extra_costs, ++ &hip11_addrcost_table, ++ &hip11_regmove_cost, ++ &hip11_vector_cost, ++ &generic_branch_cost, ++ &generic_approx_modes, ++ SVE_512, /* sve_width */ ++ { 4, /* load_int. */ ++ 4, /* store_int. */ ++ 4, /* load_fp. */ ++ 4, /* store_fp. */ ++ 4, /* load_pred. */ ++ 4 /* store_pred. */ ++ }, /* memmov_cost. */ ++ 4, /* issue_rate */ ++ (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_ALU_BRANCH ++ | AARCH64_FUSE_ALU_CBZ), /* fusible_ops */ ++ "16", /* function_align. */ ++ "4", /* jump_align. */ ++ "8", /* loop_align. */ ++ 2, /* int_reassoc_width. */ ++ 4, /* fp_reassoc_width. */ ++ 1, /* vec_reassoc_width. */ ++ 2, /* min_div_recip_mul_sf. */ ++ 2, /* min_div_recip_mul_df. */ ++ 0, /* max_case_values. */ ++ tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */ ++ (AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS ++ | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */ ++ &hip11_prefetch_tune ++}; ++ + static const struct tune_params xgene1_tunings = + { + &xgene1_extra_costs, +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index cf699e4c7..c0c64a798 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -478,6 +478,7 @@ + (include "tsv110.md") + (include "thunderx3t110.md") + (include "hip09.md") ++(include "hip11.md") + + ;; ------------------------------------------------------------------- + ;; Jumps and other miscellaneous insns +diff --git a/gcc/config/aarch64/hip11.md b/gcc/config/aarch64/hip11.md +new file mode 100644 +index 000000000..45f91e65b +--- /dev/null ++++ b/gcc/config/aarch64/hip11.md +@@ -0,0 +1,418 @@ ++;; hip11 pipeline description ++;; Copyright (C) 2018-2024 Free Software Foundation, Inc. ++;; ++;; This file is part of GCC. ++;; ++;; GCC is free software; you can redistribute it and/or modify it ++;; under the terms of the GNU General Public License as published by ++;; the Free Software Foundation; either version 3, or (at your option) ++;; any later version. ++;; ++;; GCC is distributed in the hope that it will be useful, but ++;; WITHOUT ANY WARRANTY; without even the implied warranty of ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++;; General Public License for more details. ++;; ++;; You should have received a copy of the GNU General Public License ++;; along with GCC; see the file COPYING3. If not see ++;; . ++ ++(define_automaton "hip11") ++ ++;; The hip11 core is modelled as issues pipeline that has ++;; the following functional units. ++;; 1. Three pipelines for integer operations: ALU1, ALU2, ALU3 ++ ++(define_cpu_unit "hip11_alu1_issue" "hip11") ++(define_reservation "hip11_alu1" "hip11_alu1_issue") ++ ++(define_cpu_unit "hip11_alu2_issue" "hip11") ++(define_reservation "hip11_alu2" "hip11_alu2_issue") ++ ++(define_cpu_unit "hip11_alu3_issue" "hip11") ++(define_reservation "hip11_alu3" "hip11_alu3_issue") ++ ++(define_reservation "hip11alu" "hip11_alu1|hip11_alu2|hip11_alu3") ++ ++;; 2. One pipeline for complex integer operations: MDU ++ ++(define_cpu_unit "hip11_mdu_issue" "hip11") ++(define_reservation "hip11_mdu" "hip11_mdu_issue") ++ ++;; 3. Two asymmetric pipelines for Asimd and FP operations: FSU1, FSU2 ++(define_automaton "hip11_fsu") ++ ++(define_cpu_unit "hip11_fsu1_issue" ++ "hip11_fsu") ++(define_cpu_unit "hip11_fsu2_issue" ++ "hip11_fsu") ++ ++(define_reservation "hip11_fsu1" "hip11_fsu1_issue") ++(define_reservation "hip11_fsu2" "hip11_fsu2_issue") ++(define_reservation "hip11_fsu_pipe" "hip11_fsu1|hip11_fsu2") ++ ++;; 4. Two pipeline for branch operations but same with alu2 and alu3: BRU1, BRU2 ++ ++;; 5. Two pipelines for load and store operations: LS1, LS2. ++ ++(define_cpu_unit "hip11_ls1_issue" "hip11") ++(define_cpu_unit "hip11_ls2_issue" "hip11") ++(define_reservation "hip11_ls1" "hip11_ls1_issue") ++(define_reservation "hip11_ls2" "hip11_ls2_issue") ++ ++;; Block all issue queues. ++ ++(define_reservation "hip11_block" "hip11_fsu1_issue + hip11_fsu2_issue ++ + hip11_mdu_issue + hip11_alu1_issue ++ + hip11_alu2_issue + hip11_alu3_issue + hip11_ls1_issue + hip11_ls2_issue") ++ ++;; Branch execution Unit ++;; ++(define_insn_reservation "hip11_branch" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "branch")) ++ "hip11_alu2|hip11_alu3") ++ ++(define_insn_reservation "hip11_return_from_subroutine" 6 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "branch") ++ (eq_attr "sls_length" "retbr")) ++ "hip11_mdu,(hip11_alu2|hip11_alu3)") ++ ++ ;; Simple Execution Unit: ++;; ++;; Simple ALU without shift ++(define_insn_reservation "hip11_alu" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "alu_imm,logic_imm,\ ++ alu_sreg,logic_reg,\ ++ adc_imm,adc_reg,\ ++ adr,bfm,clz,rbit,rev,\ ++ shift_imm,shift_reg,\ ++ mov_imm,mov_reg,\ ++ mvn_imm,mvn_reg,\ ++ mrs,multiple,csel,\ ++ rotate_imm")) ++ "hip11_alu1|hip11_alu2|hip11_alu3") ++ ++(define_insn_reservation "hip11_alus" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "alus_imm,logics_imm,\ ++ alus_sreg,logics_reg,\ ++ adcs_imm,adcs_reg")) ++ "hip11_alu2|hip11_alu3") ++ ++;; ALU ops with shift ++(define_insn_reservation "hip11_alu_shift" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "extend,\ ++ alu_shift_imm_lsl_1to4,alu_shift_imm_other,alu_shift_reg,\ ++ crc,logic_shift_imm,logic_shift_reg,\ ++ mov_shift,mvn_shift,\ ++ mov_shift_reg,mvn_shift_reg")) ++ "hip11_mdu") ++ ++(define_insn_reservation "hip11_alus_shift" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "alus_shift_imm,alus_shift_reg,\ ++ logics_shift_imm,logics_shift_reg")) ++ "hip11_alu2|hip11_alu3") ++ ++;; Multiplies instructions ++(define_insn_reservation "hip11_mult" 3 ++ (and (eq_attr "tune" "hip11") ++ (ior (eq_attr "mul32" "yes") ++ (eq_attr "widen_mul64" "yes"))) ++ "hip11_mdu") ++ ++;; Integer divide ++(define_insn_reservation "hip11_div" 10 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "udiv,sdiv")) ++ "hip11_mdu") ++ ++(define_insn_reservation "hip11_mla" 4 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "mla,smlal,umlal,smull,umull")) ++ "hip11_mdu") ++ ++;; Block all issue pipes for a cycle ++(define_insn_reservation "hip11_block" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "block")) ++ "hip11_block") ++ ++;; Load-store execution Unit ++;; ++(define_insn_reservation "hip11_load1" 4 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "load_4,load_8,load_16")) ++ "hip11_ls1|hip11_ls2") ++ ++(define_insn_reservation "hip11_fp_load" 5 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "f_loads,f_loadd")) ++ "hip11_ls1|hip11_ls2") ++ ++(define_insn_reservation "hip11_neon_ld1_single" 7 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load1_one_lane,neon_load1_one_lane_q,\ ++ neon_load1_all_lanes,neon_load1_all_lanes_q")) ++ "(hip11_ls1|hip11_ls2)+hip11_fsu1") ++ ++(define_insn_reservation "hip11_neon_ld1_1reg" 5 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load1_1reg,neon_load1_1reg_q")) ++ "hip11_ls1|hip11_ls2") ++ ++(define_insn_reservation "hip11_neon_ld1_2reg" 6 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load1_2reg,neon_load1_2reg_q")) ++ "hip11_ls1|hip11_ls2") ++ ++(define_insn_reservation "hip11_neon_ld1_3reg" 7 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load1_3reg,neon_load1_3reg_q")) ++ "hip11_ls1|hip11_ls2") ++ ++(define_insn_reservation "hip11_neon_ld1_4reg" 8 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load1_4reg,neon_load1_4reg_q")) ++ "hip11_ls1|hip11_ls2") ++ ++(define_insn_reservation "hip11_neon_ld2" 8 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load2_one_lane,neon_load2_one_lane_q,\ ++ neon_load2_all_lanes,neon_load2_all_lanes_q,\ ++ neon_load2_2reg,neon_load2_2reg_q,\ ++ neon_load2_4reg,neon_load2_4reg_q")) ++ "(hip11_ls1|hip11_ls2)+hip11_fsu1") ++ ++(define_insn_reservation "hip11_neon_ld3_single" 9 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load3_one_lane,neon_load3_one_lane_q,\ ++ neon_load3_all_lanes,neon_load3_all_lanes_q")) ++ "(hip11_ls1|hip11_ls2)+hip11_fsu1") ++ ++(define_insn_reservation "hip11_neon_ld3_multiple" 13 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load3_3reg,neon_load3_3reg_q")) ++ "(hip11_ls1|hip11_ls2)+hip11_fsu1") ++ ++(define_insn_reservation "hip11_neon_ld4_single" 10 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load4_one_lane,neon_load4_one_lane_q,\ ++ neon_load4_all_lanes,neon_load4_all_lanes_q")) ++ "(hip11_ls1|hip11_ls2)+hip11_fsu1") ++ ++(define_insn_reservation "hip11_neon_ld4_multiple" 11 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_load4_4reg,neon_load4_4reg_q")) ++ "(hip11_ls1|hip11_ls2)+hip11_fsu1") ++ ++;; Stores of up to two words. ++(define_insn_reservation "hip11_store1" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "store_4,store_8,store_16,\ ++ f_stored,f_stores")) ++ "hip11_ls1|hip11_ls2") ++ ++;; Floating-Point Operations. ++(define_insn_reservation "hip11_fp_arith" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "ffariths,ffarithd,f_minmaxs,\ ++ f_minmaxd,fadds,faddd,neon_fcadd")) ++ "hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_fp_mul" 3 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_fp_mul_d,neon_fp_mul_d_q,\ ++ neon_fp_mul_s_scalar,neon_fp_mul_s_scalar_q,\ ++ neon_fp_mul_d_scalar_q,fmuld,fmuls")) ++ "hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_fp_cmp" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fccmpd,fccmps")) ++ "hip11alu,hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_fp_csel" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fcsel")) ++ "hip11alu,hip11_fsu1") ++ ++(define_insn_reservation "hip11_fp_fcmp" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fcmpd,fcmps")) ++ "hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_fp_divs" 7 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fdivs")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_fp_divd" 10 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fdivd")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_fp_sqrts" 9 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fsqrts")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_fp_sqrtd" 15 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fsqrtd")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_fp_mac" 4 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fmacs,ffmas,fmacd,ffmad")) ++ "hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_fp_mov" 1 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "fmov,neon_dup,neon_dup_q,\ ++ neon_from_gp,neon_from_gp_q,\ ++ neon_ins,neon_ins_q,\ ++ neon_to_gp,neon_to_gp_q,\ ++ neon_move,neon_move_q,\ ++ neon_rev,neon_rev_q,\ ++ neon_permute,neon_permute_q,\ ++ neon_shift_imm_narrow_q,\ ++ neon_ext,neon_ext_q,\ ++ neon_rbit,\ ++ crypto_sha3,neon_tbl1,neon_tbl1_q,\ ++ neon_tbl2_q,f_mcr,neon_tst,neon_tst_q,\ ++ neon_move_narrow_q")) ++ "hip11_fsu1") ++ ++;; ASIMD instructions ++(define_insn_reservation "hip11_asimd_simple_arithmetic" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_abs,neon_abs_q,neon_neg,neon_neg_q,\ ++ neon_abd,neon_abd_q,\ ++ neon_add_long,neon_sub_long,neon_sub_widen,neon_add_widen,\ ++ neon_add_halve_narrow_q,neon_sub_halve_narrow_q,\ ++ neon_arith_acc,neon_arith_acc_q,\ ++ neon_compare,neon_compare_q,\ ++ neon_compare_zero,neon_compare_zero_q,\ ++ neon_minmax,neon_minmax_q,\ ++ neon_logic,neon_logic_q,\ ++ neon_reduc_add,neon_reduc_add_q,\ ++ neon_reduc_minmax,neon_reduc_minmax_q,\ ++ neon_fp_to_int_s,neon_fp_to_int_s_q,\ ++ neon_fp_to_int_d,neon_fp_to_int_d_q,\ ++ neon_fp_cvt_widen_s,\ ++ neon_fp_cvt_narrow_d_q,\ ++ neon_cls,neon_cls_q,\ ++ neon_cnt,neon_cnt_q,\ ++ f_rints,f_rintd,f_cvtf2i,f_cvt,\ ++ neon_tbl3,neon_fp_round_s,neon_fp_round_s_q,\ ++ neon_fp_round_d,neon_fp_round_d_q,\ ++ neon_int_to_fp_s,neon_fp_recpe_s,neon_fp_recpe_s_q,\ ++ neon_fp_recpe_d,neon_fp_recpe_d_q,\ ++ neon_fp_cvt_narrow_s_q,\ ++ crypto_aese,crypto_aesmc,\ ++ crypto_sha1_fast,crypto_sha1_xor,\ ++ crypto_sha1_slow,\ ++ crypto_sha256_fast,\ ++ crypto_sha512,crypto_sm3,\ ++ neon_qabs,neon_qabs_q,\ ++ neon_qneg,neon_qneg_q,\ ++ neon_qadd,neon_qadd_q,\ ++ neon_qsub,neon_qsub_q,\ ++ neon_add_halve,neon_add_halve_q,\ ++ neon_sub_halve,neon_sub_halve_q,\ ++ neon_fp_reduc_minmax_s,neon_fp_reduc_minmax_s_q,\ ++ neon_fp_reduc_minmax_d,neon_fp_reduc_minmax_d_q,\ ++ neon_fp_rsqrte_s,neon_fp_rsqrte_s_q,\ ++ neon_fp_rsqrte_d,neon_fp_rsqrte_d_q")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_asimd_complex_arithmetic" 4 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_mul_b,neon_mul_b_q,\ ++ neon_mul_h,neon_mul_h_q,\ ++ neon_mul_s,neon_mul_s_q,\ ++ neon_mla_b,neon_mla_b_q,\ ++ neon_mla_h,neon_mla_h_q,\ ++ neon_mla_s,\ ++ neon_mla_h_scalar,neon_mla_h_scalar_q,\ ++ neon_mla_s_scalar,neon_mla_s_scalar_q,\ ++ neon_sat_mul_h_scalar,neon_sat_mul_h_scalar_q,\ ++ neon_sat_mul_s_scalar,neon_sat_mul_s_scalar_q,\ ++ neon_sat_mul_b,neon_sat_mul_b_q,\ ++ neon_sat_mul_h,neon_sat_mul_h_q,\ ++ neon_sat_mul_s,neon_sat_mul_s_q,\ ++ neon_mla_b_long,neon_mla_h_long,neon_mla_s_long,\ ++ neon_mul_b_long,neon_mul_h_long,neon_mul_s_long,\ ++ neon_sat_mla_b_long,neon_sat_mla_h_long,neon_sat_mla_s_long,\ ++ neon_sat_mla_h_scalar_long,neon_sat_mla_s_scalar_long,\ ++ neon_sat_mul_b_long,neon_sat_mul_h_long,neon_sat_mul_s_long,\ ++ neon_sat_mul_h_scalar_long,neon_sat_mul_s_scalar_long,\ ++ crypto_pmull,\ ++ neon_sat_shift_reg,neon_sat_shift_reg_q,\ ++ neon_shift_reg,neon_shift_reg_q,\ ++ neon_shift_imm,neon_shift_imm_q,\ ++ neon_shift_imm_long,\ ++ neon_sat_shift_imm,neon_sat_shift_imm_q,\ ++ neon_sat_shift_imm_narrow_q,\ ++ neon_shift_acc,neon_shift_acc_q,\ ++ crypto_sha256_slow")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_asimd_fp_compare" 2 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_fp_abs_s,neon_fp_abs_s_q,\ ++ neon_fp_abs_d,neon_fp_abs_d_q,\ ++ neon_fp_neg_s,neon_fp_neg_s_q,\ ++ neon_fp_neg_d,neon_fp_neg_d_q,\ ++ neon_fp_compare_s,neon_fp_compare_s_q,\ ++ neon_fp_compare_d,neon_fp_compare_d_q,\ ++ neon_fp_minmax_s,neon_fp_minmax_s_q,\ ++ neon_fp_minmax_d,neon_fp_minmax_d_q,\ ++ neon_fp_addsub_s,neon_fp_addsub_s_q,\ ++ neon_fp_addsub_d,neon_fp_addsub_d_q,\ ++ neon_fp_reduc_add_s,neon_fp_reduc_add_s_q,\ ++ neon_fp_reduc_add_d,neon_fp_reduc_add_d_q,\ ++ neon_fp_abd_s,neon_fp_abd_s_q,\ ++ neon_fp_abd_d,neon_fp_abd_d_q")) ++ "hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_asimd_fdiv" 10 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_fp_div_s,neon_fp_div_s_q,\ ++ neon_fp_div_d,neon_fp_div_d_q")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_asimd_fsqrt" 15 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_fp_sqrt_s,neon_fp_sqrt_s_q,\ ++ neon_fp_sqrt_d,neon_fp_sqrt_d_q")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_asimd_fp_multiply_add" 4 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_fp_mla_s,neon_fp_mla_s_q,\ ++ neon_fp_mla_d,neon_fp_mla_d_q,\ ++ neon_fp_mla_s_scalar,neon_fp_mla_s_scalar_q,\ ++ neon_fp_mul_s,neon_fp_mul_s_q,neon_fcmla,\ ++ neon_fp_recps_s,neon_fp_recps_s_q,\ ++ neon_fp_recps_d,neon_fp_recps_d_q,\ ++ neon_fp_rsqrts_s,neon_fp_rsqrts_s_q,\ ++ neon_fp_rsqrts_d,neon_fp_rsqrts_d_q")) ++ "hip11_fsu_pipe") ++ ++(define_insn_reservation "hip11_asimd_frecpx" 3 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_fp_recpx_s,neon_fp_recpx_s_q,\ ++ neon_fp_recpx_d,neon_fp_recpx_d_q,neon_tbl4,\ ++ neon_dot,neon_dot_q")) ++ "hip11_fsu1") ++ ++(define_insn_reservation "hip11_asimd_mmla" 6 ++ (and (eq_attr "tune" "hip11") ++ (eq_attr "type" "neon_mla_s_q")) ++ "hip11_fsu1") +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 7ca60dd64..17d9e4126 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -19212,7 +19212,7 @@ performance of the code. Permissible values for this option are: + @samp{octeontx2}, @samp{octeontx2t98}, @samp{octeontx2t96} + @samp{octeontx2t93}, @samp{octeontx2f95}, @samp{octeontx2f95n}, + @samp{octeontx2f95mm}, +-@samp{a64fx}, ++@samp{a64fx},@samp{hip11} + @samp{thunderx}, @samp{thunderxt88}, + @samp{thunderxt88p1}, @samp{thunderxt81}, @samp{tsv110}, + @samp{thunderxt83}, @samp{thunderx2t99}, @samp{thunderx3t110}, @samp{zeus}, +-- +2.33.0 + diff --git a/0102-Add-Crc32-Optimization-in-Gzip-For-crc32-algorithm-i.patch b/0102-Add-Crc32-Optimization-in-Gzip-For-crc32-algorithm-i.patch new file mode 100644 index 0000000000000000000000000000000000000000..6fb0cef7ac11ea7483c88f6e86c2936dd0dac366 --- /dev/null +++ b/0102-Add-Crc32-Optimization-in-Gzip-For-crc32-algorithm-i.patch @@ -0,0 +1,2164 @@ +From 8fa9788ac64a9ea5dc92c61c8f2ec11075cd17ec Mon Sep 17 00:00:00 2001 +From: XingYushuai +Date: Thu, 15 Dec 2022 14:34:16 +0800 +Subject: [PATCH 003/157] Add Crc32 Optimization in Gzip For crc32 algorithm in + APBC int_gzip. + +Match crc32 lookup table algorithm. An example for crc32 lookup table +elg: ```c do { c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); } while (--n); + +Usage: `gcc -O3 -march=armv8.1-a -floop-crc yourfile.c` +Node: The cpu you use needs to support the crc32 instructions +--- + gcc/Makefile.in | 1 + + gcc/common.opt | 4 + + gcc/config/aarch64/aarch64-builtins.cc | 30 + + gcc/config/aarch64/aarch64-protos.h | 1 + + gcc/config/aarch64/aarch64.cc | 12 + + gcc/doc/invoke.texi | 6 +- + gcc/doc/tm.texi | 9 + + gcc/doc/tm.texi.in | 2 + + gcc/match.pd | 23 + + gcc/passes.def | 1 + + gcc/target.def | 14 + + .../tree-ssa/loop-crc-loop-condition-fail.c | 85 ++ + .../tree-ssa/loop-crc-loop-form-fail-2.c | 90 ++ + .../gcc.dg/tree-ssa/loop-crc-loop-form-fail.c | 112 ++ + .../gcc.dg/tree-ssa/loop-crc-sucess.c | 83 + + .../tree-ssa/loop-crc-table-check-fail.c | 114 ++ + gcc/timevar.def | 1 + + gcc/tree-pass.h | 1 + + gcc/tree-ssa-loop-crc.cc | 1333 +++++++++++++++++ + 19 files changed, 1921 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-crc-sucess.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-crc-table-check-fail.c + create mode 100644 gcc/tree-ssa-loop-crc.cc + +diff --git a/gcc/Makefile.in b/gcc/Makefile.in +index 5cd838270..2b9f025dc 100644 +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -1649,6 +1649,7 @@ OBJS = \ + tree-ssa-ifcombine.o \ + tree-ssa-live.o \ + tree-ssa-loop-ch.o \ ++ tree-ssa-loop-crc.o \ + tree-ssa-loop-im.o \ + tree-ssa-loop-ivcanon.o \ + tree-ssa-loop-ivopts.o \ +diff --git a/gcc/common.opt b/gcc/common.opt +index b18f0b944..42fb2fc19 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1119,6 +1119,10 @@ fcrypto-accel-aes + Common Var(flag_crypto_accel_aes) Init(0) Optimization + Perform crypto acceleration AES pattern matching. + ++floop-crc ++Common Var(flag_loop_crc) Optimization ++Do the loop crc conversion. ++ + fauto-inc-dec + Common Var(flag_auto_inc_dec) Init(1) Optimization + Generate auto-inc/dec instructions. +diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc +index 42276e7ca..3b952ef39 100644 +--- a/gcc/config/aarch64/aarch64-builtins.cc ++++ b/gcc/config/aarch64/aarch64-builtins.cc +@@ -551,6 +551,12 @@ typedef struct + #define VAR1(T, N, MAP, FLAG, A) \ + AARCH64_SIMD_BUILTIN_##T##_##N##A, + ++enum aarch64_crc_builtins{ ++ AARCH64_BUILTIN_CRC32B, ++ AARCH64_BUILTIN_CRC32H, ++ AARCH64_BUILTIN_CRC32W, ++}; ++ + enum aarch64_builtins + { + AARCH64_BUILTIN_MIN, +@@ -1812,6 +1818,30 @@ aarch64_general_builtin_decl (unsigned code, bool) + return aarch64_builtin_decls[code]; + } + ++/* Implement TARGET_GET_CRC_BUILTIN_CODE */ ++unsigned ++get_crc_builtin_code(unsigned code, bool) ++{ ++ if (code > AARCH64_BUILTIN_CRC32W) ++ return AARCH64_BUILTIN_MIN; ++ ++ unsigned res = AARCH64_BUILTIN_MIN; ++ switch (code) { ++ case AARCH64_BUILTIN_CRC32B: ++ res = AARCH64_BUILTIN_crc32b; ++ break; ++ case AARCH64_BUILTIN_CRC32H: ++ res = AARCH64_BUILTIN_crc32h; ++ break; ++ case AARCH64_BUILTIN_CRC32W: ++ res = AARCH64_BUILTIN_crc32w; ++ break; ++ default: ++ break; ++ } ++ return res; ++} ++ + typedef enum + { + SIMD_ARG_COPY_TO_REG, +diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h +index 475d174dd..853197ee9 100644 +--- a/gcc/config/aarch64/aarch64-protos.h ++++ b/gcc/config/aarch64/aarch64-protos.h +@@ -994,6 +994,7 @@ gimple *aarch64_general_gimple_fold_builtin (unsigned int, gcall *, + gimple_stmt_iterator *); + rtx aarch64_general_expand_builtin (unsigned int, tree, rtx, int); + tree aarch64_general_builtin_decl (unsigned, bool); ++unsigned get_crc_builtin_code(unsigned , bool); + tree aarch64_general_builtin_rsqrt (unsigned int); + tree aarch64_builtin_vectorized_function (unsigned int, tree, tree); + void handle_arm_acle_h (void); +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 5537a537c..280e0b618 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -15210,6 +15210,15 @@ aarch64_builtin_decl (unsigned int code, bool initialize_p) + gcc_unreachable (); + } + ++/* Implement TARGET_GET_CRC_BUILTIN_CODE. */ ++static unsigned ++aarch64_get_crc_builtin_code(unsigned code, bool initialize_p) ++{ ++ unsigned subcode = get_crc_builtin_code(code,initialize_p); ++ unsigned res = subcode << AARCH64_BUILTIN_SHIFT; ++ return res; ++} ++ + /* Return true if it is safe and beneficial to use the approximate rsqrt optabs + to optimize 1.0/sqrt. */ + +@@ -27677,6 +27686,9 @@ aarch64_get_v16qi_mode () + #undef TARGET_BUILTIN_DECL + #define TARGET_BUILTIN_DECL aarch64_builtin_decl + ++#undef TARGET_GET_CRC_BUILTIN_CODE ++#define TARGET_GET_CRC_BUILTIN_CODE aarch64_get_crc_builtin_code ++ + #undef TARGET_BUILTIN_RECIPROCAL + #define TARGET_BUILTIN_RECIPROCAL aarch64_builtin_reciprocal + +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 7ca60dd64..c3ce148b0 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -537,7 +537,7 @@ Objective-C and Objective-C++ Dialects}. + -fisolate-erroneous-paths-dereference -fisolate-erroneous-paths-attribute @gol + -fivopts -fkeep-inline-functions -fkeep-static-functions @gol + -fkeep-static-consts -flimit-function-alignment -flive-range-shrinkage @gol +--floop-block -floop-interchange -floop-strip-mine @gol ++-floop-block -floop-crc -floop-interchange -floop-strip-mine @gol + -floop-unroll-and-jam -floop-nest-optimize @gol + -floop-parallelize-all -flra-remat -flto -flto-compression-level @gol + -flto-partition=@var{alg} -fmerge-all-constants @gol +@@ -12159,6 +12159,10 @@ GIMPLE -> GRAPHITE -> GIMPLE transformation. Some minimal optimizations + are also performed by the code generator isl, like index splitting and + dead code elimination in loops. + ++@item -floop-crc ++@opindex floop-crc ++Do the loop crc conversion ++ + @item -floop-nest-optimize + @opindex floop-nest-optimize + Enable the isl based loop nest optimizer. This is a generic loop nest +diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi +index 851d31c18..5a1e0fe43 100644 +--- a/gcc/doc/tm.texi ++++ b/gcc/doc/tm.texi +@@ -11658,6 +11658,15 @@ If @var{code} is out of range the function should return + @code{error_mark_node}. + @end deftypefn + ++@deftypefn {Target Hook} unsigned TARGET_GET_CRC_BUILTIN_CODE (unsigned @var{code}, bool @var{initialize_p}) ++Define this hook to get crc32 builtin code. It should be a function that ++returns the crc32 builtin function code @var{code}. ++If there is no such builtin and it cannot be initialized at this time ++if @var{initialize_p} is true the function should return @code{NULL_TREE}. ++If @var{code} is out of range the function should return ++@code{error_mark_node}. ++@end deftypefn ++ + @deftypefn {Target Hook} rtx TARGET_EXPAND_BUILTIN (tree @var{exp}, rtx @var{target}, rtx @var{subtarget}, machine_mode @var{mode}, int @var{ignore}) + + Expand a call to a machine specific built-in function that was set up by +diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in +index ac95cdf7a..6ff0eff66 100644 +--- a/gcc/doc/tm.texi.in ++++ b/gcc/doc/tm.texi.in +@@ -7704,6 +7704,8 @@ to by @var{ce_info}. + + @hook TARGET_BUILTIN_DECL + ++@hook TARGET_GET_CRC_BUILTIN_CODE ++ + @hook TARGET_EXPAND_BUILTIN + + @hook TARGET_RESOLVE_OVERLOADED_BUILTIN +diff --git a/gcc/match.pd b/gcc/match.pd +index aee58e47b..1f42090a2 100644 +--- a/gcc/match.pd ++++ b/gcc/match.pd +@@ -4409,6 +4409,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) + ) + #endif + ++#if GIMPLE ++/* Try to match ++ _4 = (int) _3; NOP_EXPR (SSA_NAME @2) ++ _5 = _4 ^ c_10; BIT_XOR_EXPR (SSA_NAME@1, SSA_NAME) ++ _6 = _5 & 255; BIT_AND_EXPR (SSA_NAME, INTEGER_CST@3) ++*/ ++(match (crc_match_index @1 @2 @3) ++ (bit_and (bit_xor (nop SSA_NAME@2) SSA_NAME@1) INTEGER_CST@3) ++ (if (INTEGRAL_TYPE_P (type) && tree_to_uhwi(@3) == 255)) ++) ++#endif ++ ++#if GIMPLE ++/* Try to match ++ _8 = c_12 >> 8; RSHIFT_EXPR (SSA_NAME @1, INTEGER_CST @2) ++ c_19 = _7 ^ _8; BIT_XOR_EXPR (SSA_NAME@3, SSA_NAME) ++*/ ++(match (crc_match_res @1 @2 @3) ++ (bit_xor SSA_NAME@3 (rshift SSA_NAME@1 INTEGER_CST@2)) ++ (if (INTEGRAL_TYPE_P (type) && tree_to_uhwi(@2) == 8)) ++) ++#endif ++ + /* Simplification moved from fold_cond_expr_with_comparison. It may also + be extended. */ + /* This pattern implements two kinds simplification: +diff --git a/gcc/passes.def b/gcc/passes.def +index cdc600298..89d6889e5 100644 +--- a/gcc/passes.def ++++ b/gcc/passes.def +@@ -95,6 +95,7 @@ along with GCC; see the file COPYING3. If not see + NEXT_PASS (pass_cd_dce, false /* update_address_taken_p */); + NEXT_PASS (pass_phiopt, true /* early_p */); + NEXT_PASS (pass_array_widen_compare); ++ NEXT_PASS (pass_loop_crc); + NEXT_PASS (pass_tail_recursion); + NEXT_PASS (pass_if_to_switch); + NEXT_PASS (pass_convert_switch); +diff --git a/gcc/target.def b/gcc/target.def +index c9bb2b4c2..8abf49f0a 100644 +--- a/gcc/target.def ++++ b/gcc/target.def +@@ -2413,6 +2413,20 @@ If @var{code} is out of range the function should return\n\ + @code{error_mark_node}.", + tree, (unsigned code, bool initialize_p), NULL) + ++/* Initialize (if INITIALIZE_P is true) and return the real code of ++ target-specific built-in function. ++ Return NULL if that is not possible. Return error_mark_node if CODE ++ is outside of the range of valid crc32 codes. */ ++DEFHOOK ++(get_crc_builtin_code, ++ "Define this hook to get crc32 builtin code. It should be a function that\n\ ++returns the crc32 builtin function code @var{code}.\n\ ++If there is no such builtin and it cannot be initialized at this time\n\ ++if @var{initialize_p} is true the function should return @code{NULL_TREE}.\n\ ++If @var{code} is out of range the function should return\n\ ++@code{error_mark_node}.", ++ unsigned , (unsigned code, bool initialize_p), NULL) ++ + /* Expand a target-specific builtin. */ + DEFHOOK + (expand_builtin, +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c +new file mode 100644 +index 000000000..3620e92f7 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c +@@ -0,0 +1,85 @@ ++/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ ++/* { dg-options "-O3 -march=armv8.1-a -mabi=lp64 -floop-crc -fdump-tree-loop_crc-details" } */ ++ ++#include ++#include ++typedef unsigned long ulg; ++typedef unsigned char uch; ++ ++static const ulg crc_32_tab[] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; ++ ++ulg updcrc (s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) ++ if (n) do { ++ c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); ++ } while (--n || c != 0) ; ++ } ++ crc = c; ++exit1: ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++/* { dg-final { scan-tree-dump-times "Wrong loop form for crc matching." 1 "loop_crc"} } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c +new file mode 100644 +index 000000000..fac759c67 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c +@@ -0,0 +1,90 @@ ++/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ ++/* { dg-options "-O3 -march=armv8.1-a -mabi=lp64 -floop-crc -fdump-tree-loop_crc-details" } */ ++ ++#include ++#include ++typedef unsigned long ulg; ++typedef unsigned char uch; ++ ++static const ulg crc_32_tab[] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; ++int test[5] = {0}; ++ ++ulg updcrc (s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) ++ if (n) do { ++ c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); ++ } while (--n) ; ++ } ++ do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); ++ test[c%5] = c; ++ } while (--n) ; ++ crc = c; ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++/* { dg-final { scan-tree-dump-times "Table check fail. not only single array is read." 1 "loop_crc"} } */ ++/* { dg-final { scan-tree-dump-times "Wrong crc table for crc matching." 1 "loop_crc"} } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c +new file mode 100644 +index 000000000..ba9e5bb95 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c +@@ -0,0 +1,112 @@ ++/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ ++/* { dg-options "-O3 -march=armv8.1-a -mabi=lp64 -floop-crc -fdump-tree-loop_crc-details" } */ ++ ++#include ++#include ++typedef unsigned long ulg; ++typedef unsigned char uch; ++ ++static const ulg crc_32_tab[] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; ++ ++/* check when the loop have a innor loop, should fail. */ ++ulg updcrc (s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) ++ do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); ++ for (int i = 0; i < 5; i++) { ++ c++; ++ } ++ ++ } while (--n); ++ } ++ crc = c; ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++ ++/* check when the loop have a second backedge, should fail. */ ++ulg updcrc1(s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) ++ do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); ++ } while (--n || c != 0) ; ++ } ++ crc = c; ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++/* { dg-final { scan-tree-dump-times "Wrong crc table for crc matching." 1 "loop_crc"} } */ ++/* { dg-final { scan-tree-dump-times "Table check fail. not only single array is read." 1 "loop_crc"} } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-sucess.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-sucess.c +new file mode 100644 +index 000000000..dad7bdbfc +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-sucess.c +@@ -0,0 +1,83 @@ ++/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ ++/* { dg-options "-O3 -march=armv8.1-a -mabi=lp64 -floop-crc -fdump-tree-loop_crc-details" } */ ++ ++#include ++#include ++typedef unsigned long ulg; ++typedef unsigned char uch; ++ ++static const ulg crc_32_tab[] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; ++ ++ulg updcrc (s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) do { ++ c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); ++ } while (--n); ++ } ++ crc = c; ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++/* { dg-final { scan-tree-dump-times "The 1th loop form is success matched,and the loop can be optimized." 1 "loop_crc"} } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-table-check-fail.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-table-check-fail.c +new file mode 100644 +index 000000000..523a7740c +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-crc-table-check-fail.c +@@ -0,0 +1,114 @@ ++/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ ++/* { dg-options "-O3 -march=armv8.1-a -mabi=lp64 -floop-crc -fdump-tree-loop_crc-details" } */ ++ ++#include ++#include ++typedef unsigned long ulg; ++typedef unsigned char uch; ++ ++static const ulg crc_32_tab[] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf1L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; ++int test[5] = {0}; ++ ++/* check when the loop is doing more then 1 array read or writing an array, both should fail. */ ++ulg updcrc (s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) ++ do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8) * test[c%5]; ++ } while (--n) ; ++ } ++ do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); ++ test[c%5] = c; ++ } while (--n) ; ++ crc = c; ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++ ++/* check when the loop is not working on a correct crc_table. should fail. */ ++ulg updcrc1(s, n) ++ uch *s; /* pointer to bytes to pump through */ ++ unsigned n; /* number of bytes in s[] */ ++{ ++ register ulg c; /* temporary variable */ ++ ++ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ ++ ++ if (s == NULL) { ++ c = 0xffffffffL; ++ } else { ++ c = crc; ++ if (n) ++ do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); ++ } while (--n) ; ++ } ++ crc = c; ++ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ ++} ++/* { dg-final { scan-tree-dump-times "Table check fail. not only single array is read." 2 "loop_crc"} } */ ++/* { dg-final { scan-tree-dump-times "Wrong crc table for crc matching." 3 "loop_crc"} } */ ++/* { dg-final { scan-tree-dump-times "Table check fail. Table not matching." 1 "loop_crc"} } */ +diff --git a/gcc/timevar.def b/gcc/timevar.def +index 8e7510eb3..8341b9ffd 100644 +--- a/gcc/timevar.def ++++ b/gcc/timevar.def +@@ -220,6 +220,7 @@ DEFTIMEVAR (TV_TREE_COPY_RENAME , "tree rename SSA copies") + DEFTIMEVAR (TV_TREE_SSA_VERIFY , "tree SSA verifier") + DEFTIMEVAR (TV_TREE_STMT_VERIFY , "tree STMT verifier") + DEFTIMEVAR (TV_TREE_ARRAY_WIDEN_COMPARE, "tree array widen compare") ++DEFTIMEVAR (TV_TREE_LOOP_CRC , "tree loop crc") + DEFTIMEVAR (TV_TREE_SWITCH_CONVERSION, "tree switch conversion") + DEFTIMEVAR (TV_TREE_SWITCH_LOWERING, "tree switch lowering") + DEFTIMEVAR (TV_TREE_RECIP , "gimple CSE reciprocals") +diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h +index 34e60bc38..6cd679e10 100644 +--- a/gcc/tree-pass.h ++++ b/gcc/tree-pass.h +@@ -454,6 +454,7 @@ extern gimple_opt_pass *make_pass_phiopt (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_forwprop (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_phiprop (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_array_widen_compare (gcc::context *ctxt); ++extern gimple_opt_pass *make_pass_loop_crc (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_tree_ifcombine (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_dse (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_nrv (gcc::context *ctxt); +diff --git a/gcc/tree-ssa-loop-crc.cc b/gcc/tree-ssa-loop-crc.cc +new file mode 100644 +index 000000000..b9c2f71ca +--- /dev/null ++++ b/gcc/tree-ssa-loop-crc.cc +@@ -0,0 +1,1333 @@ ++/* This pass converts special loops where do CRC algorithms to ++ simple CRC instructions in AArch64. ++ Copyright (C) 2023-2023 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the ++Free Software Foundation; either version 3, or (at your option) any ++later version. ++ ++GCC is distributed in the hope that it will be useful, but WITHOUT ++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#include "config.h" ++#include "system.h" ++#include "coretypes.h" ++#include "backend.h" ++#include "target.h" ++#include "tree.h" ++#include "gimple.h" ++#include "tree-pass.h" ++#include "gimple-ssa.h" ++#include "tree-pretty-print.h" ++#include "fold-const.h" ++#include "gimplify.h" ++#include "gimple-iterator.h" ++#include "tree-ssa-loop-manip.h" ++#include "tree-ssa-loop.h" ++#include "ssa.h" ++#include "tree-into-ssa.h" ++#include "cfganal.h" ++#include "cfgloop.h" ++#include "gimple-pretty-print.h" ++#include "tree-cfg.h" ++#include "cgraph.h" ++#include "print-tree.h" ++#include "cfghooks.h" ++#include "gimple-fold.h" ++#include "diagnostic-core.h" ++ ++/* This pass handles scenarios similar to the following: ++ulg updcrc (s, n) ++ uch *s; ++ unsigned n; ++{ ++ register ulg c; ++ ++ static ulg crc = (ulg)0xffffffffL; ++ ++ if (s == NULL) ++ { ++ c = 0xffffffffL; ++ } ++ else ++ { ++ c = crc; ++ if (n) ++ do ++ { ++ c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); ++ } while (--n); ++ } ++ crc = c; ++ return c ^ 0xffffffffL; ++} ++ ++If the hardware supports the crc instruction, then the pass completes the ++conversion of the above scenario into: ++ ++#define SIZE_U32 sizeof(uint32_t) ++unsigned long updcrc(s, n) ++ unsigned char *s; ++ unsigned n; ++{ ++ register unsigned long c; ++ ++ static unsigned long crc = (unsigned long)0xffffffffL; ++ ++ if (s == NULL) ++ { ++ c = 0xffffffffL; ++ } ++ else ++ { ++ c = crc; ++ if (n) ++ { ++ uint32_t nn = n/SIZE_U32; ++ do ++ { ++ c = __crc32w (c,*((uint32_t *)s)); ++ s += SIZE_U32; ++ } while(--nn); ++ } ++ } ++ if (n & sizeof (uint16_t)) ++ { ++ c = __crc32h (c, *((uint16_t *)s)); ++ s += sizeof (uint16_t); ++ } ++ if (n & sizeof (uint8_t)) ++ c = __crc32b (c, *s); ++ crc = c; ++ return c ^ 0xffffffffL; ++} ++ ++This pass is to complete the conversion of such scenarios from ++the internal perspective of the compiler: ++1) match_crc_loop: The function completes the screening of such ++ scenarios; ++2) convert_to_new_loop: The function completes the conversion of ++ origin_loop to new loops, and removes origin_loop; ++3) origin_loop_info: The structure is used to record important ++ information of origin_loop: such as loop exit, initial value ++ of induction variable, etc; ++4) create_new_loops: The function is used as the key content ++ of the pass to complete the creation of new loops. */ ++ ++extern bool gimple_crc_match_index (tree, tree *, tree (*)(tree)); ++extern bool gimple_crc_match_res (tree, tree *, tree (*)(tree)); ++ ++static gimple *crc_table_read_stmt = NULL; ++ ++static gphi *phi_s = NULL; ++static gphi *phi_c = NULL; ++static tree nn_tree = NULL; ++ ++enum aarch64_crc_builtins ++{ ++ AARCH64_BUILTIN_CRC32B, ++ AARCH64_BUILTIN_CRC32H, ++ AARCH64_BUILTIN_CRC32W, ++}; ++ ++/* The useful information of origin loop. */ ++struct origin_loop_info ++{ ++ tree limit; /* The limit index of the array in the old loop. */ ++ tree base_n; /* The initial value of the old loop. */ ++ tree base_s; /* The initial value of the old loop. */ ++ tree base_c; /* The initial value of the old loop. */ ++ edge entry_edge; /* The edge into the old loop. */ ++ edge exit_edge; /* The edge outto the old loop. */ ++ basic_block exit_bb; ++}; ++ ++typedef struct origin_loop_info origin_loop_info; ++ ++static origin_loop_info origin_loop; ++hash_map n_map; ++hash_map nn_map; ++hash_map s_map; ++hash_map c_map; ++hash_map crc_map; ++ ++/* Initialize the origin_loop structure. */ ++static void ++init_origin_loop_structure () ++{ ++ origin_loop.entry_edge = NULL; ++ origin_loop.exit_edge = NULL; ++ origin_loop.exit_bb = NULL; ++ origin_loop.limit = NULL; ++ origin_loop.base_n = NULL; ++ origin_loop.base_s = NULL; ++ origin_loop.base_c = NULL; ++} ++ ++/* Get the edge that first entered the loop. */ ++static edge ++get_loop_preheader_edge (class loop *loop) ++{ ++ edge e; ++ edge_iterator ei; ++ ++ FOR_EACH_EDGE (e, ei, loop->header->preds) ++ if (e->src != loop->latch) ++ break; ++ ++ return e; ++} ++ ++/* Returns true if t is SSA_NAME and user variable exists. */ ++ ++static bool ++ssa_name_var_p (tree t) ++{ ++ if (!t || TREE_CODE (t) != SSA_NAME) ++ return false; ++ if (SSA_NAME_VAR (t)) ++ return true; ++ return false; ++} ++ ++/* Returns true if t1 and t2 are SSA_NAME and belong to the same variable. */ ++ ++static bool ++same_ssa_name_var_p (tree t1, tree t2) ++{ ++ if (!ssa_name_var_p (t1) || !ssa_name_var_p (t2)) ++ return false; ++ if (SSA_NAME_VAR (t1) == SSA_NAME_VAR (t2)) ++ return true; ++ return false; ++} ++ ++/* Get origin loop induction variable upper bound. */ ++ ++static bool ++get_iv_upper_bound (gimple *stmt) ++{ ++ if (origin_loop.limit != NULL || origin_loop.base_n != NULL) ++ return false; ++ ++ tree lhs = gimple_cond_lhs (stmt); ++ tree rhs = gimple_cond_rhs (stmt); ++ ++ if (TREE_CODE (TREE_TYPE (lhs)) != INTEGER_TYPE ++ || TREE_CODE (TREE_TYPE (rhs)) != INTEGER_TYPE) ++ return false; ++ ++ /* TODO: Currently, the input restrictions on lhs and rhs are implemented ++ through PARM_DECL. We may consider relax the restrictions later, and ++ we need to consider the overall adaptation scenario and adding test ++ cases. */ ++ if (ssa_name_var_p (lhs) && TREE_CODE (SSA_NAME_VAR (lhs)) == PARM_DECL) ++ { ++ origin_loop.limit = rhs; ++ origin_loop.base_n = lhs; ++ } ++ else ++ return false; ++ ++ if (origin_loop.limit != NULL && origin_loop.base_n != NULL) ++ return true; ++ ++ return false; ++} ++ ++/* Get origin loop info. */ ++static bool ++get_origin_loop_info (class loop *loop) ++{ ++ auto_vec edges = get_loop_exit_edges (loop); ++ origin_loop.exit_edge = edges[0]; ++ origin_loop.exit_bb = origin_loop.exit_edge->dest; ++ origin_loop.entry_edge = get_loop_preheader_edge (loop); ++ origin_loop.base_s = PHI_ARG_DEF_FROM_EDGE (phi_s,origin_loop.entry_edge); ++ origin_loop.base_c = PHI_ARG_DEF_FROM_EDGE (phi_c,origin_loop.entry_edge); ++ ++ basic_block preheader_bb = origin_loop.entry_edge->src; ++ ++ if (preheader_bb->preds->length () != 1) ++ return false; ++ ++ edge entry_pre_bb_edge = EDGE_PRED (preheader_bb, 0); ++ ++ basic_block pre_preheader_bb = entry_pre_bb_edge->src; ++ ++ gimple_stmt_iterator gsi; ++ gimple *stmt; ++ bool get_upper_bound = false; ++ for (gsi = gsi_start_bb (pre_preheader_bb); !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ stmt = gsi_stmt (gsi); ++ if (stmt && gimple_code (stmt) == GIMPLE_COND ++ && get_iv_upper_bound (stmt)) ++ { ++ get_upper_bound = true; ++ break; ++ } ++ } ++ ++ return get_upper_bound; ++} ++ ++/* The loop form check will check the entire loop control flow ++ It should be a loop that: ++ 1. a do-while loop with header and latch only with no other control flow ++ inside the loop ++ 2. have only one exiting edge ++ 3. have only one back edge and one entry edge ++*/ ++static bool ++crc_loop_form_check (class loop *loop) ++{ ++ if (loop->num_nodes > 2 || loop->inner) ++ return false; ++ // Should only have 1 exit edge ++ auto_vec edges = get_loop_exit_edges (loop); ++ if (edges.length() != 1) ++ return false; ++ ++ // The header should have only 2 incoming edges ++ // One of them is the preheader edge and the other is the backedge from the ++ // latch ++ if (EDGE_COUNT (loop->header->preds) != 2) ++ return false; ++ edge e1 = EDGE_PRED (loop->header, 0); ++ edge e2 = EDGE_PRED (loop->header, 1); ++ ++ if ((e1->src == loop->latch && e2->src->loop_father != loop) ++ || (e2->src == loop->latch && e1->src->loop_father != loop)) ++ return true; ++ ++ return false; ++} ++ ++/* Check there is only one array is read in the loop. ++ Return the only array as crc_table. */ ++static bool ++only_one_array_read (class loop *loop, tree &crc_table) ++{ ++ gimple_stmt_iterator gsi; ++ gimple *stmt; ++ bool res = false; ++ for (gsi = gsi_start_bb (loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ stmt = gsi_stmt (gsi); ++ if (stmt == NULL) ++ return false; ++ ++ if (gimple_code (stmt) == GIMPLE_ASSIGN ++ && TREE_CODE (gimple_assign_lhs (stmt)) == ARRAY_REF) ++ return false; ++ ++ /* Only one-dimensional integer arrays meet the condition. */ ++ if (gimple_code (stmt) == GIMPLE_ASSIGN ++ && TREE_CODE (gimple_assign_rhs1 (stmt)) == ARRAY_REF ++ && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)) == VAR_DECL ++ && TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (stmt))) == INTEGER_TYPE) ++ { ++ if (crc_table == NULL ++ && TREE_READONLY (gimple_assign_rhs1 (stmt))) ++ { ++ crc_table = gimple_assign_rhs1 (stmt); ++ crc_table_read_stmt = stmt; ++ res = true; ++ } ++ else ++ return false; ++ } ++ } ++ return res; ++} ++ ++static const unsigned HOST_WIDE_INT crc_32_tab[] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; ++ ++/* Check the content of the array. */ ++static bool ++match_crc_table (tree crc_table) ++{ ++ const unsigned LOW_BOUND = 0; ++ const unsigned UP_BOUND = 255; ++ const unsigned ELEMENT_SIZE = 8; ++ tree low_bound = array_ref_low_bound (crc_table); ++ tree up_bound = array_ref_up_bound (crc_table); ++ tree element_size = array_ref_element_size (crc_table); ++ if (!tree_fits_uhwi_p(low_bound) || !tree_fits_uhwi_p(up_bound) || ++ !tree_fits_uhwi_p(element_size)) ++ return false; ++ unsigned HOST_WIDE_INT lb = tree_to_uhwi (low_bound); ++ unsigned HOST_WIDE_INT ub = tree_to_uhwi (up_bound); ++ unsigned HOST_WIDE_INT es = tree_to_uhwi (element_size); ++ if (lb != LOW_BOUND || ub != UP_BOUND || es != ELEMENT_SIZE) ++ return false; ++ ++ tree decl = TREE_OPERAND (crc_table, 0); ++ tree ctor = ctor_for_folding(decl); ++ for (int i = lb; i <= ub; i++) ++ { ++ unsigned HOST_WIDE_INT val = tree_to_uhwi (CONSTRUCTOR_ELT (ctor, ++ i)->value); ++ if (crc_32_tab[i] != val) ++ return false; ++ } ++ return true; ++} ++ ++/* Check the crc table. The loop should have only one data reference. ++ And match the data reference with the predefined array. */ ++static bool ++crc_table_check (class loop *loop) ++{ ++ tree crc_table = NULL; ++ if (!only_one_array_read (loop, crc_table)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\nTable check fail. not only single array " ++ "is read.\n"); ++ return false; ++ } ++ if (!match_crc_table (crc_table)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\nTable check fail. Table not matching.\n"); ++ return false; ++ } ++ return true; ++} ++ ++/* Check whether the evolution pattern of phi is phi = SSA_NAME + target*/ ++static bool ++evolution_pattern_plus_with_p (class loop *loop, gphi *phi, ++ unsigned HOST_WIDE_INT target) ++{ ++ edge backedge = find_edge (loop->latch, loop->header); ++ if (backedge == NULL) ++ return false; ++ tree evolution_node = PHI_ARG_DEF_FROM_EDGE (phi, backedge); ++ gimple *evolution_expr = SSA_NAME_DEF_STMT (evolution_node); ++ ++ if (evolution_expr && (gimple_assign_rhs_code (evolution_expr) == PLUS_EXPR || ++ gimple_assign_rhs_code (evolution_expr) ++ == POINTER_PLUS_EXPR)) ++ { ++ tree rhs1 = gimple_assign_rhs1 (evolution_expr); ++ tree rhs2 = gimple_assign_rhs2 (evolution_expr); ++ if (TREE_CODE (rhs1) == SSA_NAME && TREE_CODE (rhs2) == INTEGER_CST ++ && tree_to_uhwi (rhs2) == target) ++ return true; ++ } ++ return false; ++} ++ ++/* Check whether there are only 3 phi nodes in the header block. ++ Return 3 phi nodes in the capture. */ ++static bool ++check_num_of_phi (basic_block header, gphi *capture[]) ++{ ++ gphi *phi; ++ gphi_iterator gsi; ++ int num_of_phi = 0; ++ ++ for (gsi = gsi_start_phis (header); !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ phi = gsi.phi (); ++ if (phi) ++ num_of_phi++; ++ if (num_of_phi > 3) ++ return false; ++ capture[num_of_phi - 1] = phi; ++ } ++ /* Phi node should be exactly 3. */ ++ return num_of_phi == 3; ++} ++ ++/* Check the evolution pattern of three phi nodes. ++ Should be one of the node +1 every time (s), one of the node -1 ++ every time (n), and a 3rd one neither (c). Return 3 phi nodes in ++ the capture with the order of s,n,c.*/ ++static bool ++check_evolution_pattern (class loop *loop, gphi *capture[]) ++{ ++ gphi *s = NULL; ++ gphi *n = NULL; ++ gphi *c = NULL; ++ ++ for (int i = 0; i < 3; i++) ++ { ++ if (evolution_pattern_plus_with_p (loop, capture[i], 1)) ++ { ++ if (s != NULL) ++ return false; ++ s = capture[i]; ++ phi_s = s; ++ } ++ else if (evolution_pattern_plus_with_p (loop, capture[i], 4294967295)) ++ { ++ if (n != NULL) ++ return false; ++ n = capture[i]; ++ } ++ else ++ { ++ if (c != NULL) ++ return false; ++ c = capture[i]; ++ phi_c = c; ++ } ++ } ++ ++ // Some envolution pattern cannot find ++ if (!n || !s || !c) ++ return false; ++ ++ capture[0] = s; ++ capture[1] = n; ++ capture[2] = c; ++ return true; ++} ++/* Check the calculation pattern before and after the crc_table array read stmt. ++ _7 = crc_32_tab[_6]; ++ The caculation of index _6 should be the result of a sequency of calculation ++ by the s and c ++ The result of the array read _7 should be used to calculate the new c. */ ++static bool ++check_calculation_pattern (class loop *loop, gphi *capture[]) ++{ ++ gphi *s = capture[0]; ++ gphi *c = capture[2]; ++ tree res_ops[3]; ++ tree index = TREE_OPERAND (gimple_assign_rhs1 (crc_table_read_stmt), 1); ++ ++ /* Try to match ++ _4 = (int) _3; //NOP_EXPR (SSA_NAME @2) ++ _5 = _4 ^ c_10; //BIT_XOR_EXPR (SSA_NAME, PHI @1) ++ _6 = _5 & 255; //BIT_XOR_EXPR (SSA_NAME, INTEGER_CST@3) ++ */ ++ if (!gimple_crc_match_index (index, res_ops, NULL)) ++ return false; ++ gimple *s_res_stmt = SSA_NAME_DEF_STMT (res_ops[0]); ++ if (!s_res_stmt) ++ return false; ++ gimple *s_def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (s_res_stmt)); ++ if (!s_def_stmt) ++ return false; ++ tree s_res = TREE_OPERAND (gimple_assign_rhs1 (s_def_stmt), 0); ++ if (res_ops[1] != gimple_phi_result (c) || s_res != gimple_phi_result (s)) ++ return false; ++ ++ /* Try to match ++ _8 = c_12 >> 8; // RSHIFT_EXPR (SSA_NAME @1, INTEGER_CST @2) ++ c_19 = _7 ^ _8; // BIT_XOR_EXPR (SSA_NAME@3, SSA_NAME) ++ */ ++ edge backedge = find_edge (loop->latch, loop->header); ++ tree updated_c = PHI_ARG_DEF_FROM_EDGE (c, backedge); ++ if (!gimple_crc_match_res (updated_c, res_ops, NULL)) ++ return false; ++ if (res_ops[0] != gimple_phi_result (c) ++ || res_ops[2] != gimple_assign_lhs (crc_table_read_stmt)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n gimple_crc_match_res pattern check failed.\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Check the exit condition is n != 0. */ ++static bool ++check_exit_condition (class loop *loop, gphi *n) ++{ ++ edge backedge = find_edge (loop->latch, loop->header); ++ gimple *cond_stmt = gsi_stmt (gsi_last_bb (loop->header)); ++ if (!cond_stmt || gimple_code (cond_stmt) != GIMPLE_COND ++ || gimple_cond_code (cond_stmt) != NE_EXPR ++ || gimple_cond_lhs (cond_stmt) != PHI_ARG_DEF_FROM_EDGE (n, backedge) ++ || tree_to_uhwi (gimple_cond_rhs (cond_stmt)) != 0) ++ return false; ++ ++ return true; ++} ++ ++/* Check the loop body. The loop body we are trying to match is ++ ++# s_10 = PHI ++# n_11 = PHI ++# c_12 = PHI ++_1 = (int) c_12; ++s_18 = s_10 + 1; ++_3 = *s_10; ++_4 = (int) _3; ++_5 = _1 ^ _4; ++_6 = _5 & 255; ++_7 = crc_32_tab[_6]; ++_8 = c_12 >> 8; ++c_19 = _7 ^ _8; ++n_20 = n_11 + 4294967295; ++if (n_20 != 0) ++ goto ; [INV] ++else ++ goto ; [INV] ++ ++which is doing a very simple calculation ++do { ++ c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); ++} while (--n); ++ ++In this case ,we don't want this loop to have any other operation inside. ++so the matching condition is ++1. There are only 3 loop variant during each itoration, namely s,c,n, ++ which is limited by the condition that the loop have exactly 3 phi nodes. ++2. The 3 loop variants should have evolution pattern as 1 of the 3 nodes is ++ increased by 1 every itoration, 1 of the 3 nodes is decreased by 1 every itor ++ and the 3rd one is neither. These three tree node SSA value will be captured ++ for the later arithmatic pattern matching ++3. Pattern matching for the index of crc_table ++4. pattern matching for the result of c calcuation after read from crc_table ++5. The exit condition matching. ++ */ ++static bool ++crc_loop_body_check (class loop *loop) ++{ ++ basic_block header = loop->header; ++ gphi *capture[3]; ++ if (!check_num_of_phi(header, capture)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n num of phi noeds check failed.\n"); ++ return false; ++ } ++ if (!check_evolution_pattern (loop, capture)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n evolution pattern check failed.\n"); ++ return false; ++ } ++ if (!check_calculation_pattern (loop, capture)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n calculation pattern check failed.\n"); ++ return false; ++ } ++ if (!check_exit_condition (loop, capture[1])) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n exit condition check failed.\n"); ++ return false; ++ } ++ return true; ++} ++ ++static bool check_prev_bb (basic_block prev_bb, enum tree_code code) ++{ ++ gimple_stmt_iterator gsi; ++ gimple *stmt; ++ for (gsi = gsi_start_bb (prev_bb); !gsi_end_p (gsi); ++ gsi_next (&gsi)) ++ { ++ stmt = gsi_stmt (gsi); ++ if (stmt == NULL) ++ return false; ++ ++ if (gimple_code (stmt) == GIMPLE_COND ++ && gimple_cond_code (stmt) == code ++ && TREE_CODE (gimple_cond_rhs (stmt)) == INTEGER_CST ++ && tree_int_cst_sgn (gimple_cond_rhs (stmt)) == 0) ++ return true; ++ } ++ return false; ++} ++ ++/* Check the prev_bb of prev_bb of loop header. The prev_bb we are trying to ++match is ++ ++c_15 = crc; ++if (n_16 (D) != 0) ++ goto ; [INV] ++else ++ goto ; [INV] ++ ++ In this case , we must be sure that the n is not zero. ++ so the match condition is ++ 1 the n is not zero. ++ ++ : ++if (s_13 (D) == 0B) ++ goto ; [INV] ++else ++ goto ; [INV] ++ ++ In this case, we must be sure the s is not NULL. ++ so the match condition is ++ 1 the s is not NULL. ++*/ ++static bool ++crc_prev_bb_of_loop_header_check (class loop *loop) ++{ ++ basic_block header = loop->header; ++ basic_block prev_header_bb = header->prev_bb; ++ if (NULL == prev_header_bb) ++ return false; ++ ++ basic_block prev_prev_header_bb = prev_header_bb->prev_bb; ++ if (NULL == prev_prev_header_bb) ++ return false; ++ ++ if (!check_prev_bb (prev_prev_header_bb, NE_EXPR)) ++ return false; ++ ++ basic_block first_bb = prev_prev_header_bb->prev_bb; ++ if (NULL == first_bb) ++ return false; ++ ++ if (!check_prev_bb (first_bb, EQ_EXPR)) ++ return false; ++ ++ return true; ++} ++ ++static bool ++match_crc_loop (class loop *loop) ++{ ++ if (!crc_loop_form_check (loop)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\nWrong loop form for crc matching.\n"); ++ return false; ++ } ++ if (!crc_table_check (loop)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\nWrong crc table for crc matching.\n"); ++ return false; ++ } ++ if (!crc_loop_body_check (loop)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\nWrong loop body for crc matching.\n"); ++ return false; ++ } ++ if (!crc_prev_bb_of_loop_header_check (loop)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\nWrong prev basic_blocks of loop header for" ++ " crc matching.\n"); ++ return false; ++ } ++ ++ init_origin_loop_structure (); ++ if (!get_origin_loop_info (loop)) ++ return false; ++ ++ return true; ++} ++ ++static void ++create_new_bb (basic_block &new_bb, basic_block after_bb, ++ basic_block dominator_bb, class loop *outer) ++{ ++ new_bb = create_empty_bb (after_bb); ++ add_bb_to_loop (new_bb, outer); ++ set_immediate_dominator (CDI_DOMINATORS, new_bb, dominator_bb); ++} ++ ++static void ++change_preheader_bb (edge entry_edge) ++{ ++ gimple_seq stmts = NULL; ++ gimple_stmt_iterator gsi; ++ gimple *g; ++ tree lhs1; ++ ++ lhs1 = create_tmp_var (TREE_TYPE (origin_loop.base_n),"nn"); ++ lhs1 = make_ssa_name (lhs1); ++ gsi = gsi_last_bb (entry_edge->src); ++ g = gimple_build_assign (lhs1, RSHIFT_EXPR, origin_loop.base_n, ++ build_int_cst (TREE_TYPE (origin_loop.base_n), 2)); ++ gimple_seq_add_stmt (&stmts, g); ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++ nn_tree = lhs1; ++ set_current_def (nn_tree, lhs1); ++ nn_map.put (entry_edge->src, lhs1); ++} ++ ++static gphi * ++create_phi_node_for_bb (tree old_name, basic_block bb) ++{ ++ gphi *phi = create_phi_node (NULL_TREE, bb); ++ create_new_def_for (old_name, phi, gimple_phi_result_ptr (phi)); ++ return phi; ++} ++ ++static gimple * ++call_builtin_fun (int code,tree &lhs, tree arg1, tree arg2) ++{ ++ unsigned int builtin_code = targetm.get_crc_builtin_code (code, true); ++ // Get the decl of __builtin_aarch64_crc32w ++ tree fn = targetm.builtin_decl (builtin_code, true); ++ if (!fn || fn == error_mark_node) ++ fatal_error (input_location, ++ "target specific builtin not available"); ++ gimple *call_builtin = gimple_build_call (fn, 2, arg1, arg2); ++ lhs = make_ssa_name (unsigned_type_node); ++ gimple_call_set_lhs (call_builtin, lhs); ++ ++ return call_builtin; ++} ++ ++/* Create loop_header and loop_latch for new loop ++ : ++ # s_14 = PHI ++ # c_16 = PHI ++ # nn_19 = PHI ++ _1 = (unsigned int) c_16; ++ _2 = MEM[(uint32_t *)s_14]; ++ _40 = __builtin_aarch64_crc32w (_1, _2); ++ c_29 = (long unsigned int) _40; ++ s_30 = s_14 + 4; ++ nn_31 = nn_19 + 4294967295; ++ if (nn_31 != 0) ++ The IR of bb is as above. */ ++static void ++create_loop_bb (basic_block &loop_bb, basic_block after_bb, ++ basic_block dominator_bb, class loop *outer, edge entry_edge) ++{ ++ gimple_seq stmts = NULL; ++ gimple_stmt_iterator gsi; ++ gimple *g; ++ gphi *phi_s_loop; ++ gphi *phi_c_loop; ++ gphi *phi_nn_loop; ++ ++ create_new_bb (loop_bb, after_bb, dominator_bb, outer); ++ redirect_edge_and_branch (entry_edge, loop_bb); ++ gsi = gsi_last_bb (loop_bb); ++ tree entry_nn = get_current_def (nn_tree); ++ phi_s_loop = create_phi_node_for_bb (origin_loop.base_s, loop_bb); ++ phi_c_loop = create_phi_node_for_bb (origin_loop.base_c, loop_bb); ++ phi_nn_loop = create_phi_node_for_bb (entry_nn, loop_bb); ++ ++ tree res_s = gimple_phi_result (phi_s_loop); ++ tree res_nn = gimple_phi_result (phi_nn_loop); ++ tree lhs1 = gimple_build (&stmts, NOP_EXPR, unsigned_type_node, ++ gimple_phi_result (phi_c_loop)); ++ g = gimple_build_assign (make_ssa_name (unsigned_type_node), ++ fold_build2 (MEM_REF, unsigned_type_node, res_s, ++ build_int_cst ( ++ build_pointer_type ( ++ unsigned_type_node),0))); ++ gimple_seq_add_stmt (&stmts, g); ++ tree lhs2 = gimple_assign_lhs (g); // _2 = MEM[(uint32_t *)s_14]; ++ unsigned int code = AARCH64_BUILTIN_CRC32W; ++ tree lhs3; ++ gimple *build_crc32w = call_builtin_fun (code, lhs3, lhs1, lhs2); ++ crc_map.put (loop_bb, lhs3); ++ gimple_seq_add_stmt (&stmts, build_crc32w); ++ ++ tree lhs4 = copy_ssa_name (origin_loop.base_c); ++ g = gimple_build_assign (lhs4, NOP_EXPR, lhs3); ++ gimple_seq_add_stmt (&stmts, g); ++ c_map.put (loop_bb, lhs4); ++ ++ tree lhs5 = copy_ssa_name (origin_loop.base_s); ++ g = gimple_build_assign (lhs5, POINTER_PLUS_EXPR, res_s, ++ build_int_cst (sizetype, 4)); ++ gimple_seq_add_stmt (&stmts, g); ++ s_map.put (loop_bb, lhs5); ++ ++ tree lhs6 = copy_ssa_name (nn_tree); ++ g = gimple_build_assign (lhs6, PLUS_EXPR, res_nn, ++ build_int_cst (TREE_TYPE (res_nn), 4294967295)); ++ gimple_seq_add_stmt (&stmts,g); ++ nn_map.put (loop_bb, lhs6); ++ ++ gcond *cond_stmt = gimple_build_cond (NE_EXPR, lhs6, origin_loop.limit, ++ NULL_TREE, NULL_TREE); ++ gimple_seq_add_stmt (&stmts, cond_stmt); ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++} ++ ++/* : ++ # c_6 = PHI ++ # s_46 = PHI ++ _44 = n_26(D) & 2; ++ if (_44 != 0) ++ The IR of bb is as above. */ ++static void ++create_cond_bb (basic_block &cond_bb, basic_block after_bb, ++ basic_block dominator_bb, class loop *outer) ++{ ++ gimple_seq stmts = NULL; ++ gimple_stmt_iterator gsi; ++ gphi *phi_s_loop; ++ gphi *phi_c_loop; ++ ++ create_new_bb (cond_bb, after_bb, dominator_bb, outer); ++ gsi = gsi_last_bb (cond_bb); ++ tree entry_nn = get_current_def (nn_tree); ++ phi_s_loop = create_phi_node_for_bb (origin_loop.base_s, cond_bb); ++ phi_c_loop = create_phi_node_for_bb (origin_loop.base_c, cond_bb); ++ tree res_s = gimple_phi_result (phi_s_loop); ++ set_current_def (origin_loop.base_s, res_s); ++ s_map.put (cond_bb, res_s); ++ tree res_c = gimple_phi_result (phi_c_loop); ++ set_current_def (origin_loop.base_c, res_c); ++ c_map.put (cond_bb, res_c); ++ ++ tree lhs1 = gimple_build (&stmts, BIT_AND_EXPR, ++ TREE_TYPE (origin_loop.base_n), origin_loop.base_n, ++ build_int_cst (TREE_TYPE (origin_loop.base_n), 2)); ++ gcond *cond_stmt = gimple_build_cond (NE_EXPR, lhs1, origin_loop.limit, ++ NULL_TREE, NULL_TREE); ++ gimple_seq_add_stmt (&stmts, cond_stmt); ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++} ++ ++/* : ++ _7 = MEM[(uint16_t *)s_46]; ++ _41 = __builtin_aarch64_crc32h (_8, _7); ++ c_33 = (long unsigned int) _41; ++ s_34 = s_30 + 2; ++ The IR of bb is as above. */ ++static void ++create_cond_true_bb (basic_block &cond_true_bb, basic_block after_bb, ++ basic_block dominator_bb, class loop *outer) ++{ ++ gimple_seq stmts = NULL; ++ gimple *g; ++ gimple_stmt_iterator gsi; ++ ++ create_new_bb (cond_true_bb, after_bb, dominator_bb, outer); ++ gsi = gsi_last_bb (cond_true_bb); ++ tree s_46 = *(s_map.get (after_bb)); ++ tree type = build_pointer_type (short_unsigned_type_node); ++ g = gimple_build_assign (make_ssa_name (short_unsigned_type_node), ++ fold_build2 (MEM_REF, short_unsigned_type_node, s_46, ++ build_int_cst (type, 0))); ++ gimple_seq_add_stmt (&stmts,g); ++ tree lhs1 = gimple_assign_lhs (g); // _7 = MEM[(uint16_t *)s_46]; ++ unsigned int code = AARCH64_BUILTIN_CRC32H; ++ tree lhs2; ++ gimple *call_builtin = call_builtin_fun (code, lhs2, ++ *(crc_map.get ( ++ cond_true_bb->prev_bb->prev_bb)), lhs1); ++ crc_map.put (cond_true_bb,lhs2); ++ gimple_seq_add_stmt (&stmts, call_builtin); ++ ++ tree lhs3 = copy_ssa_name (origin_loop.base_c); ++ g = gimple_build_assign (lhs3, NOP_EXPR, lhs2); ++ gimple_seq_add_stmt (&stmts, g); ++ c_map.put (cond_true_bb, lhs3); ++ ++ tree lhs5 = copy_ssa_name (s_46); ++ g = gimple_build_assign (lhs5, POINTER_PLUS_EXPR, s_46, ++ build_int_cst (sizetype, 2)); // s_30 + 2; ++ gimple_seq_add_stmt (&stmts, g); ++ s_map.put (cond_true_bb, lhs5); ++ ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++ s_map.put (cond_true_bb, lhs5); ++} ++ ++/* : ++ # s_15 = PHI ++ # c_17 = PHI ++ _3 = n_26(D) & 1; ++ if (_3 != 0) ++ The IR of bb is as above. */ ++static void ++create_cond_false_bb (basic_block &cond_false_bb, basic_block after_bb, ++ basic_block dominator_bb, class loop *outer) ++{ ++ gimple_seq stmts = NULL; ++ gimple_stmt_iterator gsi; ++ gphi *phi_s_cond_true_bb; ++ gphi *phi_c_cond_true_bb; ++ ++ create_new_bb (cond_false_bb, after_bb, dominator_bb, outer); ++ make_single_succ_edge (after_bb, cond_false_bb, EDGE_FALLTHRU); ++ ++ tree entry_s = get_current_def (origin_loop.base_s); ++ phi_s_cond_true_bb = create_phi_node_for_bb (entry_s, cond_false_bb); ++ tree entry_c = get_current_def (origin_loop.base_c); ++ phi_c_cond_true_bb = create_phi_node_for_bb (entry_c, cond_false_bb); ++ tree res_s = gimple_phi_result (phi_s_cond_true_bb); ++ set_current_def (origin_loop.base_s, res_s); ++ s_map.put (cond_false_bb, res_s); ++ tree res_c = gimple_phi_result (phi_c_cond_true_bb); ++ set_current_def (origin_loop.base_c, res_c); ++ c_map.put (cond_false_bb, res_c); ++ ++ gsi = gsi_last_bb (cond_false_bb); ++ tree lhs1 = gimple_build (&stmts, BIT_AND_EXPR, ++ TREE_TYPE (origin_loop.base_n), origin_loop.base_n, ++ build_int_cst (TREE_TYPE (origin_loop.base_n), 1)); ++ gcond *cond_stmt = gimple_build_cond (NE_EXPR, lhs1, origin_loop.limit, ++ NULL_TREE, NULL_TREE); ++ gimple_seq_add_stmt (&stmts, cond_stmt); ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++} ++ ++/* : ++ _11 = (unsigned int) c_17; ++ _12 = *s_15; ++ _42 = __builtin_aarch64_crc32b (_11, _12); ++ c_36 = (long unsigned int) _42; ++ The IR of bb is as above. */ ++static void ++create_lastcond_true_bb (basic_block &new_bb, basic_block after_bb, ++ basic_block dominator_bb, class loop *outer) ++{ ++ gimple_seq stmts = NULL; ++ gimple_stmt_iterator gsi; ++ gimple *g; ++ ++ create_new_bb (new_bb, after_bb, dominator_bb, outer); ++ gsi = gsi_last_bb (new_bb); ++ ++ tree lhs1 = gimple_build (&stmts, NOP_EXPR, unsigned_type_node, ++ get_current_def (origin_loop.base_c)); ++ tree lhs2; ++ tree s_15 = get_current_def (origin_loop.base_s); ++ g = gimple_build_assign (make_ssa_name (unsigned_char_type_node), ++ fold_build2 (MEM_REF, unsigned_char_type_node, s_15, ++ build_int_cst (TREE_TYPE (s_15), 0))); ++ gimple_seq_add_stmt (&stmts, g); ++ lhs2 = gimple_assign_lhs (g); ++ ++ unsigned int code = AARCH64_BUILTIN_CRC32B; ++ tree lhs3; ++ gimple *call_builtin = call_builtin_fun (code, lhs3, lhs1, lhs2); ++ crc_map.put (new_bb,lhs3); ++ gimple_seq_add_stmt (&stmts,call_builtin); ++ ++ tree lhs4 = copy_ssa_name (origin_loop.base_c); ++ g = gimple_build_assign (lhs4, NOP_EXPR, lhs3); ++ gimple_seq_add_stmt (&stmts, g); ++ c_map.put (new_bb, lhs4); ++ ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++} ++ ++static bool ++optional_add_phi_arg (gphi * phi, tree phi_res, tree phi_arg, edge e) ++{ ++ location_t loc; ++ if (same_ssa_name_var_p (phi_arg, phi_res)) ++ { ++ if (virtual_operand_p (phi_arg)) ++ loc = UNKNOWN_LOCATION; ++ else ++ loc = gimple_location (SSA_NAME_DEF_STMT (phi_arg)); ++ add_phi_arg (phi, phi_arg, e, loc); ++ ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Add phi_arg for bb with phi node. */ ++static void ++update_phi_nodes (basic_block bb) ++{ ++ edge e; ++ edge_iterator ei; ++ gphi *phi; ++ gphi_iterator gsi; ++ tree res; ++ ++ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ phi = gsi.phi (); ++ res = gimple_phi_result (phi); ++ ++ FOR_EACH_EDGE (e, ei, bb->preds) ++ { ++ if (PHI_ARG_DEF_FROM_EDGE (phi, e)) ++ continue; ++ tree var_c; ++ tree *ptr_var_c = c_map.get (e->src); ++ if (ptr_var_c == NULL) ++ var_c = origin_loop.base_c; ++ else ++ var_c = *ptr_var_c; ++ if (optional_add_phi_arg (phi, res, var_c, e)) ++ continue; ++ ++ tree var_nn; ++ tree *ptr_var_nn = nn_map.get (e->src); ++ if (ptr_var_nn == NULL) ++ var_nn = nn_tree; ++ else ++ var_nn = *ptr_var_nn; ++ if (optional_add_phi_arg (phi, res, var_nn, e)) ++ continue; ++ ++ tree var_s; ++ tree *ptr_var_s = s_map.get (e->src); ++ if (ptr_var_s == NULL) ++ var_s = origin_loop.base_s; ++ else ++ var_s = *ptr_var_s; ++ if (optional_add_phi_arg (phi, res, var_s, e)) ++ continue; ++ } ++ } ++} ++ ++static void ++create_new_loops (edge entry_edge) ++{ ++ class loop *new_loop = NULL; ++ basic_block loop_bb, cond_bb, cond_true_bb, cond_false_bb, lastcond_true_bb; ++ class loop *outer = entry_edge->src->loop_father; ++ change_preheader_bb (entry_edge); ++ ++ create_loop_bb (loop_bb, entry_edge->src, entry_edge->src, outer, entry_edge); ++ create_cond_bb (cond_bb, loop_bb, loop_bb, outer); ++ make_edge (loop_bb, loop_bb, EDGE_TRUE_VALUE); ++ make_edge (loop_bb, cond_bb, EDGE_FALSE_VALUE); ++ update_phi_nodes (loop_bb); ++ ++ new_loop = alloc_loop (); ++ new_loop->header = loop_bb; ++ new_loop->latch = loop_bb; ++ add_loop (new_loop, outer); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "\nPrint byte new loop %d:\n", new_loop->num); ++ flow_loop_dump (new_loop, dump_file, NULL, 1); ++ fprintf (dump_file, "\n\n"); ++ } ++ ++ create_cond_true_bb (cond_true_bb, cond_bb, cond_bb, outer); ++ make_edge (cond_bb, cond_true_bb, EDGE_TRUE_VALUE); ++ create_cond_false_bb (cond_false_bb, cond_true_bb, cond_bb, outer); ++ make_edge (cond_bb, cond_false_bb, EDGE_FALSE_VALUE); ++ update_phi_nodes (cond_bb); ++ update_phi_nodes (cond_false_bb); ++ create_lastcond_true_bb (lastcond_true_bb, cond_false_bb, ++ cond_false_bb, outer); ++ make_edge (cond_false_bb, lastcond_true_bb, EDGE_TRUE_VALUE); ++ make_edge (cond_false_bb, origin_loop.exit_bb, EDGE_FALSE_VALUE); ++ make_single_succ_edge (lastcond_true_bb, origin_loop.exit_bb, EDGE_FALLTHRU); ++ ++ update_phi_nodes (origin_loop.exit_bb); ++ remove_edge (origin_loop.exit_edge); ++} ++ ++/* Clear information about the original loop. */ ++static void ++remove_origin_loop (class loop *loop) ++{ ++ basic_block *body = get_loop_body_in_dom_order (loop); ++ unsigned n = loop->num_nodes; ++ for (int i = 0; i < n; ++i) ++ delete_basic_block (body[i]); ++ free (body); ++ delete_loop (loop); ++} ++ ++/* Make sure that the dominance relationship of the newly inserted cfg ++ is not missing. */ ++static void ++update_loop_dominator (cdi_direction dir) ++{ ++ gcc_assert (dom_info_available_p (dir)); ++ ++ basic_block bb; ++ FOR_EACH_BB_FN (bb, cfun) ++ { ++ basic_block imm_bb = get_immediate_dominator (dir, bb); ++ if (!imm_bb || bb == origin_loop.exit_bb) ++ { ++ set_immediate_dominator (CDI_DOMINATORS, bb, ++ recompute_dominator (CDI_DOMINATORS, bb)); ++ continue; ++ } ++ } ++} ++ ++/* Perform the conversion of origin_loop to new_loop. */ ++static void ++convert_to_new_loop (class loop *loop) ++{ ++ create_new_loops (origin_loop.entry_edge); ++ remove_origin_loop (loop); ++ update_loop_dominator (CDI_DOMINATORS); ++ update_ssa (TODO_update_ssa); ++} ++ ++/* The main entry of loop crc optimizes. */ ++static unsigned int ++tree_ssa_loop_crc () ++{ ++ if (TARGET_CRC32 == false) ++ { ++ warning (OPT____,"The loop-crc optimization is not working." \ ++ "You should make sure that the specified architecture" \ ++ "supports crc:-march=armv8.1-a"); ++ return 0; ++ } ++ unsigned int todo = 0; ++ class loop *loop; ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ flow_loops_dump (dump_file, NULL, 1); ++ fprintf (dump_file, "\nStarting the loop_crc pass\n"); ++ } ++ ++ enum li_flags LI = LI_FROM_INNERMOST; ++ for (auto loop : loops_list (cfun, LI)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "======================================\n"); ++ fprintf (dump_file, "Processing loop %d:\n", loop->num); ++ fprintf (dump_file, "======================================\n"); ++ flow_loop_dump (loop, dump_file, NULL, 1); ++ fprintf (dump_file, "\n\n"); ++ } ++ ++ if (match_crc_loop (loop)) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "The %dth loop form is success matched," ++ "and the loop can be optimized.\n", ++ loop->num); ++ } ++ ++ convert_to_new_loop (loop); ++ todo |= (TODO_update_ssa); ++ } ++ } ++ return todo; ++} ++ ++/* Loop crc. */ ++ ++namespace { ++const pass_data pass_data_tree_loop_crc = ++{ ++ GIMPLE_PASS, ++ "loop_crc", ++ OPTGROUP_LOOP, ++ TV_TREE_LOOP_CRC, ++ (PROP_cfg | PROP_ssa), ++ 0, ++ 0, ++ 0, ++ (TODO_update_ssa | TODO_verify_all) ++}; ++ ++class pass_loop_crc : public gimple_opt_pass ++{ ++public: ++ pass_loop_crc (gcc::context *ctxt) ++ : gimple_opt_pass (pass_data_tree_loop_crc, ctxt) ++ {} ++ ++ /* Opt_pass methods: */ ++ virtual bool gate (function *); ++ virtual unsigned int execute (function *); ++}; // Class pass_loop_crc ++ ++bool ++pass_loop_crc::gate (function *) ++{ ++ return (flag_loop_crc > 0 && optimize >= 3); ++} ++ ++unsigned int ++pass_loop_crc::execute (function *fun) ++{ ++ if (number_of_loops (fun) <= 1) ++ return 0; ++ ++ /* Only supports LP64 data mode. */ ++ if (TYPE_PRECISION (long_integer_type_node) != 64 ++ || POINTER_SIZE != 64 || TYPE_PRECISION (integer_type_node) != 32) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "The current data mode is not supported," ++ "only the LP64 date mode is supported.\n"); ++ return 0; ++ } ++ ++ return tree_ssa_loop_crc (); ++} ++ ++} // Anon namespace ++ ++gimple_opt_pass * ++make_pass_loop_crc (gcc::context *ctxt) ++{ ++ return new pass_loop_crc (ctxt); ++} +-- +2.33.0 + diff --git a/0103-SME-Remove-hip09-and-hip11-in-aarch64-cores.def-to-b.patch b/0103-SME-Remove-hip09-and-hip11-in-aarch64-cores.def-to-b.patch new file mode 100644 index 0000000000000000000000000000000000000000..5589f82dbb1c1b19cf8b1a12816e2f7e0e2b5cf3 --- /dev/null +++ b/0103-SME-Remove-hip09-and-hip11-in-aarch64-cores.def-to-b.patch @@ -0,0 +1,34 @@ +From 72c48ade495ef99ef032a6c44365eb102b74888e Mon Sep 17 00:00:00 2001 +From: xiezhiheng +Date: Fri, 23 Aug 2024 15:14:04 +0800 +Subject: [PATCH 004/157] [SME] Remove hip09 and hip11 in aarch64-cores.def to + backport SME + +Will apply it in the end. +--- + gcc/config/aarch64/aarch64-cores.def | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def +index 601b72abb..70b11eb80 100644 +--- a/gcc/config/aarch64/aarch64-cores.def ++++ b/gcc/config/aarch64/aarch64-cores.def +@@ -130,7 +130,6 @@ AARCH64_CORE("a64fx", a64fx, a64fx, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F + + /* HiSilicon ('H') cores. */ + AARCH64_CORE("tsv110", tsv110, tsv110, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2, tsv110, 0x48, 0xd01, -1) +-AARCH64_CORE("hip09", hip09, hip09, 8_5A, AARCH64_FL_FOR_ARCH8_5 | AARCH64_FL_SVE | AARCH64_FL_I8MM | AARCH64_FL_F32MM | AARCH64_FL_F64MM | AARCH64_FL_PROFILE | AARCH64_FL_PREDRES, hip09, 0x48, 0xd02, 0x0) + + /* ARMv8.3-A Architecture Processors. */ + +@@ -173,7 +172,6 @@ AARCH64_CORE("cortex-a710", cortexa710, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | + AARCH64_CORE("cortex-x2", cortexx2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd48, -1) + + AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversen2, 0x41, 0xd49, -1) +-AARCH64_CORE("hip11", hip11, hip11, 8_5A, AARCH64_FL_FOR_ARCH8_5| AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_F16, hip11, 0x48, 0xd22, -1) + + AARCH64_CORE("demeter", demeter, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) + AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) +-- +2.33.0 + diff --git a/0097-Backport-SME-AArch64-Cleanup-CPU-option-processing-c.patch b/0104-Backport-SME-AArch64-Cleanup-CPU-option-processing-c.patch similarity index 100% rename from 0097-Backport-SME-AArch64-Cleanup-CPU-option-processing-c.patch rename to 0104-Backport-SME-AArch64-Cleanup-CPU-option-processing-c.patch diff --git a/0098-Backport-SME-AArch64-Cleanup-option-processing-code.patch b/0105-Backport-SME-AArch64-Cleanup-option-processing-code.patch similarity index 100% rename from 0098-Backport-SME-AArch64-Cleanup-option-processing-code.patch rename to 0105-Backport-SME-AArch64-Cleanup-option-processing-code.patch diff --git a/0099-Backport-SME-aarch64-Add-march-support-for-Armv9.1-A.patch b/0106-Backport-SME-aarch64-Add-march-support-for-Armv9.1-A.patch similarity index 100% rename from 0099-Backport-SME-aarch64-Add-march-support-for-Armv9.1-A.patch rename to 0106-Backport-SME-aarch64-Add-march-support-for-Armv9.1-A.patch diff --git a/0100-Backport-SME-Revert-aarch64-Define-__ARM_FEATURE_RCP.patch b/0107-Backport-SME-Revert-aarch64-Define-__ARM_FEATURE_RCP.patch similarity index 100% rename from 0100-Backport-SME-Revert-aarch64-Define-__ARM_FEATURE_RCP.patch rename to 0107-Backport-SME-Revert-aarch64-Define-__ARM_FEATURE_RCP.patch diff --git a/0101-Backport-SME-Revert-Ampere-1-and-Ampere-1A-core-defi.patch b/0108-Backport-SME-Revert-Ampere-1-and-Ampere-1A-core-defi.patch similarity index 100% rename from 0101-Backport-SME-Revert-Ampere-1-and-Ampere-1A-core-defi.patch rename to 0108-Backport-SME-Revert-Ampere-1-and-Ampere-1A-core-defi.patch diff --git a/0102-Backport-SME-aarch64-Rename-AARCH64_ISA-architecture.patch b/0109-Backport-SME-aarch64-Rename-AARCH64_ISA-architecture.patch similarity index 100% rename from 0102-Backport-SME-aarch64-Rename-AARCH64_ISA-architecture.patch rename to 0109-Backport-SME-aarch64-Rename-AARCH64_ISA-architecture.patch diff --git a/0103-Backport-SME-aarch64-Rename-AARCH64_FL-architecture-.patch b/0110-Backport-SME-aarch64-Rename-AARCH64_FL-architecture-.patch similarity index 100% rename from 0103-Backport-SME-aarch64-Rename-AARCH64_FL-architecture-.patch rename to 0110-Backport-SME-aarch64-Rename-AARCH64_FL-architecture-.patch diff --git a/0104-Backport-SME-aarch64-Rename-AARCH64_FL_FOR_ARCH-macr.patch b/0111-Backport-SME-aarch64-Rename-AARCH64_FL_FOR_ARCH-macr.patch similarity index 100% rename from 0104-Backport-SME-aarch64-Rename-AARCH64_FL_FOR_ARCH-macr.patch rename to 0111-Backport-SME-aarch64-Rename-AARCH64_FL_FOR_ARCH-macr.patch diff --git a/0105-Backport-SME-aarch64-Add-V-to-aarch64-arches.def-nam.patch b/0112-Backport-SME-aarch64-Add-V-to-aarch64-arches.def-nam.patch similarity index 100% rename from 0105-Backport-SME-aarch64-Add-V-to-aarch64-arches.def-nam.patch rename to 0112-Backport-SME-aarch64-Add-V-to-aarch64-arches.def-nam.patch diff --git a/0106-Backport-SME-aarch64-Small-config.gcc-cleanups.patch b/0113-Backport-SME-aarch64-Small-config.gcc-cleanups.patch similarity index 100% rename from 0106-Backport-SME-aarch64-Small-config.gcc-cleanups.patch rename to 0113-Backport-SME-aarch64-Small-config.gcc-cleanups.patch diff --git a/0107-Backport-SME-aarch64-Avoid-redundancy-in-aarch64-cor.patch b/0114-Backport-SME-aarch64-Avoid-redundancy-in-aarch64-cor.patch similarity index 100% rename from 0107-Backport-SME-aarch64-Avoid-redundancy-in-aarch64-cor.patch rename to 0114-Backport-SME-aarch64-Avoid-redundancy-in-aarch64-cor.patch diff --git a/0108-Backport-SME-aarch64-Remove-AARCH64_FL_RCPC8_4-PR107.patch b/0115-Backport-SME-aarch64-Remove-AARCH64_FL_RCPC8_4-PR107.patch similarity index 100% rename from 0108-Backport-SME-aarch64-Remove-AARCH64_FL_RCPC8_4-PR107.patch rename to 0115-Backport-SME-aarch64-Remove-AARCH64_FL_RCPC8_4-PR107.patch diff --git a/0109-Backport-SME-aarch64-Fix-transitive-closure-of-featu.patch b/0116-Backport-SME-aarch64-Fix-transitive-closure-of-featu.patch similarity index 100% rename from 0109-Backport-SME-aarch64-Fix-transitive-closure-of-featu.patch rename to 0116-Backport-SME-aarch64-Fix-transitive-closure-of-featu.patch diff --git a/0110-Backport-SME-aarch64-Reorder-an-entry-in-aarch64-opt.patch b/0117-Backport-SME-aarch64-Reorder-an-entry-in-aarch64-opt.patch similarity index 100% rename from 0110-Backport-SME-aarch64-Reorder-an-entry-in-aarch64-opt.patch rename to 0117-Backport-SME-aarch64-Reorder-an-entry-in-aarch64-opt.patch diff --git a/0111-Backport-SME-aarch64-Simplify-feature-definitions.patch b/0118-Backport-SME-aarch64-Simplify-feature-definitions.patch similarity index 100% rename from 0111-Backport-SME-aarch64-Simplify-feature-definitions.patch rename to 0118-Backport-SME-aarch64-Simplify-feature-definitions.patch diff --git a/0112-Backport-SME-aarch64-Simplify-generation-of-.arch-st.patch b/0119-Backport-SME-aarch64-Simplify-generation-of-.arch-st.patch similarity index 100% rename from 0112-Backport-SME-aarch64-Simplify-generation-of-.arch-st.patch rename to 0119-Backport-SME-aarch64-Simplify-generation-of-.arch-st.patch diff --git a/0113-Backport-SME-aarch64-Avoid-std-string-in-static-data.patch b/0120-Backport-SME-aarch64-Avoid-std-string-in-static-data.patch similarity index 100% rename from 0113-Backport-SME-aarch64-Avoid-std-string-in-static-data.patch rename to 0120-Backport-SME-aarch64-Avoid-std-string-in-static-data.patch diff --git a/0114-Backport-SME-aarch64-Tweak-constness-of-option-relat.patch b/0121-Backport-SME-aarch64-Tweak-constness-of-option-relat.patch similarity index 100% rename from 0114-Backport-SME-aarch64-Tweak-constness-of-option-relat.patch rename to 0121-Backport-SME-aarch64-Tweak-constness-of-option-relat.patch diff --git a/0115-Backport-SME-aarch64-Make-more-use-of-aarch64_featur.patch b/0122-Backport-SME-aarch64-Make-more-use-of-aarch64_featur.patch similarity index 100% rename from 0115-Backport-SME-aarch64-Make-more-use-of-aarch64_featur.patch rename to 0122-Backport-SME-aarch64-Make-more-use-of-aarch64_featur.patch diff --git a/0116-Backport-SME-aarch64-Tweak-contents-of-flags_on-off-.patch b/0123-Backport-SME-aarch64-Tweak-contents-of-flags_on-off-.patch similarity index 100% rename from 0116-Backport-SME-aarch64-Tweak-contents-of-flags_on-off-.patch rename to 0123-Backport-SME-aarch64-Tweak-contents-of-flags_on-off-.patch diff --git a/0117-Backport-SME-aarch64-Tweak-handling-of-mgeneral-regs.patch b/0124-Backport-SME-aarch64-Tweak-handling-of-mgeneral-regs.patch similarity index 100% rename from 0117-Backport-SME-aarch64-Tweak-handling-of-mgeneral-regs.patch rename to 0124-Backport-SME-aarch64-Tweak-handling-of-mgeneral-regs.patch diff --git a/0118-Backport-SME-aarch64-Remove-redundant-TARGET_-checks.patch b/0125-Backport-SME-aarch64-Remove-redundant-TARGET_-checks.patch similarity index 100% rename from 0118-Backport-SME-aarch64-Remove-redundant-TARGET_-checks.patch rename to 0125-Backport-SME-aarch64-Remove-redundant-TARGET_-checks.patch diff --git a/0119-Backport-SME-aarch64-Define-__ARM_FEATURE_RCPC.patch b/0126-Backport-SME-aarch64-Define-__ARM_FEATURE_RCPC.patch similarity index 100% rename from 0119-Backport-SME-aarch64-Define-__ARM_FEATURE_RCPC.patch rename to 0126-Backport-SME-aarch64-Define-__ARM_FEATURE_RCPC.patch diff --git a/0120-Backport-SME-Add-Ampere-1-and-Ampere-1A-core-definit.patch b/0127-Backport-SME-Add-Ampere-1-and-Ampere-1A-core-definit.patch similarity index 100% rename from 0120-Backport-SME-Add-Ampere-1-and-Ampere-1A-core-definit.patch rename to 0127-Backport-SME-Add-Ampere-1-and-Ampere-1A-core-definit.patch diff --git a/0121-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch b/0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch similarity index 100% rename from 0121-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch rename to 0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch diff --git a/0122-Backport-SME-aarch64-Commonise-some-folding-code.patch b/0129-Backport-SME-aarch64-Commonise-some-folding-code.patch similarity index 100% rename from 0122-Backport-SME-aarch64-Commonise-some-folding-code.patch rename to 0129-Backport-SME-aarch64-Commonise-some-folding-code.patch diff --git a/0123-Backport-SME-aarch64-Add-a-Z-operand-modifier-for-SV.patch b/0130-Backport-SME-aarch64-Add-a-Z-operand-modifier-for-SV.patch similarity index 100% rename from 0123-Backport-SME-aarch64-Add-a-Z-operand-modifier-for-SV.patch rename to 0130-Backport-SME-aarch64-Add-a-Z-operand-modifier-for-SV.patch diff --git a/0124-Backport-SME-mode-switching-Remove-unused-bbnum-fiel.patch b/0131-Backport-SME-mode-switching-Remove-unused-bbnum-fiel.patch similarity index 100% rename from 0124-Backport-SME-mode-switching-Remove-unused-bbnum-fiel.patch rename to 0131-Backport-SME-mode-switching-Remove-unused-bbnum-fiel.patch diff --git a/0125-Backport-SME-mode-switching-Tweak-the-macro-hook-doc.patch b/0132-Backport-SME-mode-switching-Tweak-the-macro-hook-doc.patch similarity index 100% rename from 0125-Backport-SME-mode-switching-Tweak-the-macro-hook-doc.patch rename to 0132-Backport-SME-mode-switching-Tweak-the-macro-hook-doc.patch diff --git a/0126-Backport-SME-mode-switching-Add-note-problem.patch b/0133-Backport-SME-mode-switching-Add-note-problem.patch similarity index 100% rename from 0126-Backport-SME-mode-switching-Add-note-problem.patch rename to 0133-Backport-SME-mode-switching-Add-note-problem.patch diff --git a/0127-Backport-SME-mode-switching-Avoid-quadractic-list-op.patch b/0134-Backport-SME-mode-switching-Avoid-quadractic-list-op.patch similarity index 100% rename from 0127-Backport-SME-mode-switching-Avoid-quadractic-list-op.patch rename to 0134-Backport-SME-mode-switching-Avoid-quadractic-list-op.patch diff --git a/0128-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch b/0135-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch similarity index 100% rename from 0128-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch rename to 0135-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch diff --git a/0129-Backport-SME-mode-switching-Simplify-recording-of-tr.patch b/0136-Backport-SME-mode-switching-Simplify-recording-of-tr.patch similarity index 100% rename from 0129-Backport-SME-mode-switching-Simplify-recording-of-tr.patch rename to 0136-Backport-SME-mode-switching-Simplify-recording-of-tr.patch diff --git a/0130-Backport-SME-mode-switching-Tweak-entry-exit-handlin.patch b/0137-Backport-SME-mode-switching-Tweak-entry-exit-handlin.patch similarity index 100% rename from 0130-Backport-SME-mode-switching-Tweak-entry-exit-handlin.patch rename to 0137-Backport-SME-mode-switching-Tweak-entry-exit-handlin.patch diff --git a/0131-Backport-SME-mode-switching-Allow-targets-to-set-the.patch b/0138-Backport-SME-mode-switching-Allow-targets-to-set-the.patch similarity index 100% rename from 0131-Backport-SME-mode-switching-Allow-targets-to-set-the.patch rename to 0138-Backport-SME-mode-switching-Allow-targets-to-set-the.patch diff --git a/0132-Backport-SME-mode-switching-Pass-set-of-live-registe.patch b/0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch similarity index 100% rename from 0132-Backport-SME-mode-switching-Pass-set-of-live-registe.patch rename to 0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch diff --git a/0133-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch b/0140-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch similarity index 100% rename from 0133-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch rename to 0140-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch diff --git a/0134-Backport-SME-mode-switching-Use-1-based-edge-aux-fie.patch b/0141-Backport-SME-mode-switching-Use-1-based-edge-aux-fie.patch similarity index 100% rename from 0134-Backport-SME-mode-switching-Use-1-based-edge-aux-fie.patch rename to 0141-Backport-SME-mode-switching-Use-1-based-edge-aux-fie.patch diff --git a/0135-Backport-SME-mode-switching-Add-a-target-configurabl.patch b/0142-Backport-SME-mode-switching-Add-a-target-configurabl.patch similarity index 100% rename from 0135-Backport-SME-mode-switching-Add-a-target-configurabl.patch rename to 0142-Backport-SME-mode-switching-Add-a-target-configurabl.patch diff --git a/0136-Backport-SME-mode-switching-Add-a-backprop-hook.patch b/0143-Backport-SME-mode-switching-Add-a-backprop-hook.patch similarity index 100% rename from 0136-Backport-SME-mode-switching-Add-a-backprop-hook.patch rename to 0143-Backport-SME-mode-switching-Add-a-backprop-hook.patch diff --git a/0137-Backport-SME-aarch64-Add-a-result_mode-helper-functi.patch b/0144-Backport-SME-aarch64-Add-a-result_mode-helper-functi.patch similarity index 100% rename from 0137-Backport-SME-aarch64-Add-a-result_mode-helper-functi.patch rename to 0144-Backport-SME-aarch64-Add-a-result_mode-helper-functi.patch diff --git a/0138-Backport-SME-rtl-Try-to-remove-EH-edges-after-pro-ep.patch b/0145-Backport-SME-rtl-Try-to-remove-EH-edges-after-pro-ep.patch similarity index 100% rename from 0138-Backport-SME-rtl-Try-to-remove-EH-edges-after-pro-ep.patch rename to 0145-Backport-SME-rtl-Try-to-remove-EH-edges-after-pro-ep.patch diff --git a/0139-Backport-SME-Fix-PR-middle-end-107705-ICE-after-recl.patch b/0146-Backport-SME-Fix-PR-middle-end-107705-ICE-after-recl.patch similarity index 100% rename from 0139-Backport-SME-Fix-PR-middle-end-107705-ICE-after-recl.patch rename to 0146-Backport-SME-Fix-PR-middle-end-107705-ICE-after-recl.patch diff --git a/0140-Backport-SME-function-Change-return-type-of-predicat.patch b/0147-Backport-SME-function-Change-return-type-of-predicat.patch similarity index 100% rename from 0140-Backport-SME-function-Change-return-type-of-predicat.patch rename to 0147-Backport-SME-function-Change-return-type-of-predicat.patch diff --git a/0141-Backport-SME-Allow-prologues-and-epilogues-to-be-ins.patch b/0148-Backport-SME-Allow-prologues-and-epilogues-to-be-ins.patch similarity index 100% rename from 0141-Backport-SME-Allow-prologues-and-epilogues-to-be-ins.patch rename to 0148-Backport-SME-Allow-prologues-and-epilogues-to-be-ins.patch diff --git a/0142-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch b/0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch similarity index 100% rename from 0142-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch rename to 0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch diff --git a/0143-Backport-SME-Add-a-new-target-hook-TARGET_START_CALL.patch b/0150-Backport-SME-Add-a-new-target-hook-TARGET_START_CALL.patch similarity index 100% rename from 0143-Backport-SME-Add-a-new-target-hook-TARGET_START_CALL.patch rename to 0150-Backport-SME-Add-a-new-target-hook-TARGET_START_CALL.patch diff --git a/0144-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch b/0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch similarity index 100% rename from 0144-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch rename to 0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch diff --git a/0145-Backport-SME-New-compact-syntax-for-insn-and-insn_sp.patch b/0152-Backport-SME-New-compact-syntax-for-insn-and-insn_sp.patch similarity index 100% rename from 0145-Backport-SME-New-compact-syntax-for-insn-and-insn_sp.patch rename to 0152-Backport-SME-New-compact-syntax-for-insn-and-insn_sp.patch diff --git a/0146-Backport-SME-recog-Improve-parser-for-pattern-new-co.patch b/0153-Backport-SME-recog-Improve-parser-for-pattern-new-co.patch similarity index 100% rename from 0146-Backport-SME-recog-Improve-parser-for-pattern-new-co.patch rename to 0153-Backport-SME-recog-Improve-parser-for-pattern-new-co.patch diff --git a/0147-Backport-SME-recog-Support-space-in-cons.patch b/0154-Backport-SME-recog-Support-space-in-cons.patch similarity index 100% rename from 0147-Backport-SME-recog-Support-space-in-cons.patch rename to 0154-Backport-SME-recog-Support-space-in-cons.patch diff --git a/0148-Backport-SME-aarch64-Generalise-require_immediate_la.patch b/0155-Backport-SME-aarch64-Generalise-require_immediate_la.patch similarity index 100% rename from 0148-Backport-SME-aarch64-Generalise-require_immediate_la.patch rename to 0155-Backport-SME-aarch64-Generalise-require_immediate_la.patch diff --git a/0149-Backport-SME-aarch64-Add-backend-support-for-DFP.patch b/0156-Backport-SME-aarch64-Add-backend-support-for-DFP.patch similarity index 100% rename from 0149-Backport-SME-aarch64-Add-backend-support-for-DFP.patch rename to 0156-Backport-SME-aarch64-Add-backend-support-for-DFP.patch diff --git a/0150-Backport-SME-aarch64-Vector-move-fixes-for-nosimd.patch b/0157-Backport-SME-aarch64-Vector-move-fixes-for-nosimd.patch similarity index 100% rename from 0150-Backport-SME-aarch64-Vector-move-fixes-for-nosimd.patch rename to 0157-Backport-SME-aarch64-Vector-move-fixes-for-nosimd.patch diff --git a/0151-Backport-SME-aarch64-Simplify-output-template-emissi.patch b/0158-Backport-SME-aarch64-Simplify-output-template-emissi.patch similarity index 100% rename from 0151-Backport-SME-aarch64-Simplify-output-template-emissi.patch rename to 0158-Backport-SME-aarch64-Simplify-output-template-emissi.patch diff --git a/0152-Backport-SME-Improve-immediate-expansion-PR106583.patch b/0159-Backport-SME-Improve-immediate-expansion-PR106583.patch similarity index 100% rename from 0152-Backport-SME-Improve-immediate-expansion-PR106583.patch rename to 0159-Backport-SME-Improve-immediate-expansion-PR106583.patch diff --git a/0153-Backport-SME-AArch64-Cleanup-move-immediate-code.patch b/0160-Backport-SME-AArch64-Cleanup-move-immediate-code.patch similarity index 100% rename from 0153-Backport-SME-AArch64-Cleanup-move-immediate-code.patch rename to 0160-Backport-SME-AArch64-Cleanup-move-immediate-code.patch diff --git a/0154-Backport-SME-AArch64-convert-some-patterns-to-compac.patch b/0161-Backport-SME-AArch64-convert-some-patterns-to-compac.patch similarity index 100% rename from 0154-Backport-SME-AArch64-convert-some-patterns-to-compac.patch rename to 0161-Backport-SME-AArch64-convert-some-patterns-to-compac.patch diff --git a/0155-Backport-SME-aarch64-Use-SVE-s-RDVL-instruction.patch b/0162-Backport-SME-aarch64-Use-SVE-s-RDVL-instruction.patch similarity index 100% rename from 0155-Backport-SME-aarch64-Use-SVE-s-RDVL-instruction.patch rename to 0162-Backport-SME-aarch64-Use-SVE-s-RDVL-instruction.patch diff --git a/0156-Backport-SME-aarch64-Make-AARCH64_FL_SVE-requirement.patch b/0163-Backport-SME-aarch64-Make-AARCH64_FL_SVE-requirement.patch similarity index 100% rename from 0156-Backport-SME-aarch64-Make-AARCH64_FL_SVE-requirement.patch rename to 0163-Backport-SME-aarch64-Make-AARCH64_FL_SVE-requirement.patch diff --git a/0157-Backport-SME-aarch64-Add-group-suffixes-to-SVE-intri.patch b/0164-Backport-SME-aarch64-Add-group-suffixes-to-SVE-intri.patch similarity index 100% rename from 0157-Backport-SME-aarch64-Add-group-suffixes-to-SVE-intri.patch rename to 0164-Backport-SME-aarch64-Add-group-suffixes-to-SVE-intri.patch diff --git a/0158-Backport-SME-aarch64-Add-sve_type-to-SVE-builtins-co.patch b/0165-Backport-SME-aarch64-Add-sve_type-to-SVE-builtins-co.patch similarity index 100% rename from 0158-Backport-SME-aarch64-Add-sve_type-to-SVE-builtins-co.patch rename to 0165-Backport-SME-aarch64-Add-sve_type-to-SVE-builtins-co.patch diff --git a/0159-Backport-SME-aarch64-Generalise-some-SVE-ACLE-error-.patch b/0166-Backport-SME-aarch64-Generalise-some-SVE-ACLE-error-.patch similarity index 100% rename from 0159-Backport-SME-aarch64-Generalise-some-SVE-ACLE-error-.patch rename to 0166-Backport-SME-aarch64-Generalise-some-SVE-ACLE-error-.patch diff --git a/0160-Backport-SME-aarch64-Replace-vague-previous-argument.patch b/0167-Backport-SME-aarch64-Replace-vague-previous-argument.patch similarity index 100% rename from 0160-Backport-SME-aarch64-Replace-vague-previous-argument.patch rename to 0167-Backport-SME-aarch64-Replace-vague-previous-argument.patch diff --git a/0161-Backport-SME-aarch64-Make-more-use-of-sve_type-in-AC.patch b/0168-Backport-SME-aarch64-Make-more-use-of-sve_type-in-AC.patch similarity index 100% rename from 0161-Backport-SME-aarch64-Make-more-use-of-sve_type-in-AC.patch rename to 0168-Backport-SME-aarch64-Make-more-use-of-sve_type-in-AC.patch diff --git a/0162-Backport-SME-aarch64-Tweak-error-message-for-tuple-v.patch b/0169-Backport-SME-aarch64-Tweak-error-message-for-tuple-v.patch similarity index 100% rename from 0162-Backport-SME-aarch64-Tweak-error-message-for-tuple-v.patch rename to 0169-Backport-SME-aarch64-Tweak-error-message-for-tuple-v.patch diff --git a/0163-Backport-SME-aarch64-Add-tuple-forms-of-svreinterpre.patch b/0170-Backport-SME-aarch64-Add-tuple-forms-of-svreinterpre.patch similarity index 100% rename from 0163-Backport-SME-aarch64-Add-tuple-forms-of-svreinterpre.patch rename to 0170-Backport-SME-aarch64-Add-tuple-forms-of-svreinterpre.patch diff --git a/0164-Backport-SME-attribs-Use-existing-traits-for-excl_ha.patch b/0171-Backport-SME-attribs-Use-existing-traits-for-excl_ha.patch similarity index 100% rename from 0164-Backport-SME-attribs-Use-existing-traits-for-excl_ha.patch rename to 0171-Backport-SME-attribs-Use-existing-traits-for-excl_ha.patch diff --git a/0165-Backport-SME-Allow-target-attributes-in-non-gnu-name.patch b/0172-Backport-SME-Allow-target-attributes-in-non-gnu-name.patch similarity index 100% rename from 0165-Backport-SME-Allow-target-attributes-in-non-gnu-name.patch rename to 0172-Backport-SME-Allow-target-attributes-in-non-gnu-name.patch diff --git a/0166-Backport-SME-aarch64-Fix-plugin-header-install.patch b/0173-Backport-SME-aarch64-Fix-plugin-header-install.patch similarity index 100% rename from 0166-Backport-SME-aarch64-Fix-plugin-header-install.patch rename to 0173-Backport-SME-aarch64-Fix-plugin-header-install.patch diff --git a/0167-Backport-SME-aarch64-Add-arm_streaming-_compatible-a.patch b/0174-Backport-SME-aarch64-Add-arm_streaming-_compatible-a.patch similarity index 100% rename from 0167-Backport-SME-aarch64-Add-arm_streaming-_compatible-a.patch rename to 0174-Backport-SME-aarch64-Add-arm_streaming-_compatible-a.patch diff --git a/0168-Backport-SME-aarch64-Add-sme.patch b/0175-Backport-SME-aarch64-Add-sme.patch similarity index 100% rename from 0168-Backport-SME-aarch64-Add-sme.patch rename to 0175-Backport-SME-aarch64-Add-sme.patch diff --git a/0169-Backport-SME-aarch64-Add-r-m-and-m-r-alternatives-to.patch b/0176-Backport-SME-aarch64-Add-r-m-and-m-r-alternatives-to.patch similarity index 100% rename from 0169-Backport-SME-aarch64-Add-r-m-and-m-r-alternatives-to.patch rename to 0176-Backport-SME-aarch64-Add-r-m-and-m-r-alternatives-to.patch diff --git a/0170-Backport-SME-AArch64-Rewrite-simd-move-immediate-pat.patch b/0177-Backport-SME-AArch64-Rewrite-simd-move-immediate-pat.patch similarity index 100% rename from 0170-Backport-SME-AArch64-Rewrite-simd-move-immediate-pat.patch rename to 0177-Backport-SME-AArch64-Rewrite-simd-move-immediate-pat.patch diff --git a/0171-Backport-SME-AArch64-remove-test-comment-from-mov-mo.patch b/0178-Backport-SME-AArch64-remove-test-comment-from-mov-mo.patch similarity index 100% rename from 0171-Backport-SME-AArch64-remove-test-comment-from-mov-mo.patch rename to 0178-Backport-SME-AArch64-remove-test-comment-from-mov-mo.patch diff --git a/0172-Backport-SME-aarch64-Distinguish-streaming-compatibl.patch b/0179-Backport-SME-aarch64-Distinguish-streaming-compatibl.patch similarity index 100% rename from 0172-Backport-SME-aarch64-Distinguish-streaming-compatibl.patch rename to 0179-Backport-SME-aarch64-Distinguish-streaming-compatibl.patch diff --git a/0173-Backport-SME-aarch64-Mark-relevant-SVE-instructions-.patch b/0180-Backport-SME-aarch64-Mark-relevant-SVE-instructions-.patch similarity index 100% rename from 0173-Backport-SME-aarch64-Mark-relevant-SVE-instructions-.patch rename to 0180-Backport-SME-aarch64-Mark-relevant-SVE-instructions-.patch diff --git a/0174-Backport-SME-AArch64-Support-new-tbranch-optab.patch b/0181-Backport-SME-AArch64-Support-new-tbranch-optab.patch similarity index 100% rename from 0174-Backport-SME-AArch64-Support-new-tbranch-optab.patch rename to 0181-Backport-SME-AArch64-Support-new-tbranch-optab.patch diff --git a/0175-Backport-SME-aarch64-Use-local-frame-vars-in-shrink-.patch b/0182-Backport-SME-aarch64-Use-local-frame-vars-in-shrink-.patch similarity index 100% rename from 0175-Backport-SME-aarch64-Use-local-frame-vars-in-shrink-.patch rename to 0182-Backport-SME-aarch64-Use-local-frame-vars-in-shrink-.patch diff --git a/0176-Backport-SME-aarch64-Avoid-a-use-of-callee_offset.patch b/0183-Backport-SME-aarch64-Avoid-a-use-of-callee_offset.patch similarity index 100% rename from 0176-Backport-SME-aarch64-Avoid-a-use-of-callee_offset.patch rename to 0183-Backport-SME-aarch64-Avoid-a-use-of-callee_offset.patch diff --git a/0177-Backport-SME-aarch64-Explicitly-handle-frames-with-n.patch b/0184-Backport-SME-aarch64-Explicitly-handle-frames-with-n.patch similarity index 100% rename from 0177-Backport-SME-aarch64-Explicitly-handle-frames-with-n.patch rename to 0184-Backport-SME-aarch64-Explicitly-handle-frames-with-n.patch diff --git a/0178-Backport-SME-aarch64-Add-bytes_below_saved_regs-to-f.patch b/0185-Backport-SME-aarch64-Add-bytes_below_saved_regs-to-f.patch similarity index 100% rename from 0178-Backport-SME-aarch64-Add-bytes_below_saved_regs-to-f.patch rename to 0185-Backport-SME-aarch64-Add-bytes_below_saved_regs-to-f.patch diff --git a/0179-Backport-SME-aarch64-Add-bytes_below_hard_fp-to-fram.patch b/0186-Backport-SME-aarch64-Add-bytes_below_hard_fp-to-fram.patch similarity index 100% rename from 0179-Backport-SME-aarch64-Add-bytes_below_hard_fp-to-fram.patch rename to 0186-Backport-SME-aarch64-Add-bytes_below_hard_fp-to-fram.patch diff --git a/0180-Backport-SME-aarch64-Robustify-stack-tie-handling.patch b/0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch similarity index 100% rename from 0180-Backport-SME-aarch64-Robustify-stack-tie-handling.patch rename to 0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch diff --git a/0181-Backport-SME-aarch64-Tweak-aarch64_save-restore_call.patch b/0188-Backport-SME-aarch64-Tweak-aarch64_save-restore_call.patch similarity index 100% rename from 0181-Backport-SME-aarch64-Tweak-aarch64_save-restore_call.patch rename to 0188-Backport-SME-aarch64-Tweak-aarch64_save-restore_call.patch diff --git a/0182-Backport-SME-aarch64-Only-calculate-chain_offset-if-.patch b/0189-Backport-SME-aarch64-Only-calculate-chain_offset-if-.patch similarity index 100% rename from 0182-Backport-SME-aarch64-Only-calculate-chain_offset-if-.patch rename to 0189-Backport-SME-aarch64-Only-calculate-chain_offset-if-.patch diff --git a/0183-Backport-SME-aarch64-Rename-locals_offset-to-bytes_a.patch b/0190-Backport-SME-aarch64-Rename-locals_offset-to-bytes_a.patch similarity index 100% rename from 0183-Backport-SME-aarch64-Rename-locals_offset-to-bytes_a.patch rename to 0190-Backport-SME-aarch64-Rename-locals_offset-to-bytes_a.patch diff --git a/0184-Backport-SME-aarch64-Rename-hard_fp_offset-to-bytes_.patch b/0191-Backport-SME-aarch64-Rename-hard_fp_offset-to-bytes_.patch similarity index 100% rename from 0184-Backport-SME-aarch64-Rename-hard_fp_offset-to-bytes_.patch rename to 0191-Backport-SME-aarch64-Rename-hard_fp_offset-to-bytes_.patch diff --git a/0185-Backport-SME-aarch64-Tweak-frame_size-comment.patch b/0192-Backport-SME-aarch64-Tweak-frame_size-comment.patch similarity index 100% rename from 0185-Backport-SME-aarch64-Tweak-frame_size-comment.patch rename to 0192-Backport-SME-aarch64-Tweak-frame_size-comment.patch diff --git a/0186-Backport-SME-aarch64-Measure-reg_offset-from-the-bot.patch b/0193-Backport-SME-aarch64-Measure-reg_offset-from-the-bot.patch similarity index 100% rename from 0186-Backport-SME-aarch64-Measure-reg_offset-from-the-bot.patch rename to 0193-Backport-SME-aarch64-Measure-reg_offset-from-the-bot.patch diff --git a/0187-Backport-SME-aarch64-Simplify-top-of-frame-allocatio.patch b/0194-Backport-SME-aarch64-Simplify-top-of-frame-allocatio.patch similarity index 100% rename from 0187-Backport-SME-aarch64-Simplify-top-of-frame-allocatio.patch rename to 0194-Backport-SME-aarch64-Simplify-top-of-frame-allocatio.patch diff --git a/0188-Backport-SME-aarch64-Minor-initial-adjustment-tweak.patch b/0195-Backport-SME-aarch64-Minor-initial-adjustment-tweak.patch similarity index 100% rename from 0188-Backport-SME-aarch64-Minor-initial-adjustment-tweak.patch rename to 0195-Backport-SME-aarch64-Minor-initial-adjustment-tweak.patch diff --git a/0189-Backport-SME-aarch64-Tweak-stack-clash-boundary-cond.patch b/0196-Backport-SME-aarch64-Tweak-stack-clash-boundary-cond.patch similarity index 100% rename from 0189-Backport-SME-aarch64-Tweak-stack-clash-boundary-cond.patch rename to 0196-Backport-SME-aarch64-Tweak-stack-clash-boundary-cond.patch diff --git a/0190-Backport-SME-aarch64-Put-LR-save-probe-in-first-16-b.patch b/0197-Backport-SME-aarch64-Put-LR-save-probe-in-first-16-b.patch similarity index 100% rename from 0190-Backport-SME-aarch64-Put-LR-save-probe-in-first-16-b.patch rename to 0197-Backport-SME-aarch64-Put-LR-save-probe-in-first-16-b.patch diff --git a/0191-Backport-SME-aarch64-Simplify-probe-of-final-frame-a.patch b/0198-Backport-SME-aarch64-Simplify-probe-of-final-frame-a.patch similarity index 100% rename from 0191-Backport-SME-aarch64-Simplify-probe-of-final-frame-a.patch rename to 0198-Backport-SME-aarch64-Simplify-probe-of-final-frame-a.patch diff --git a/0192-Backport-SME-aarch64-Explicitly-record-probe-registe.patch b/0199-Backport-SME-aarch64-Explicitly-record-probe-registe.patch similarity index 100% rename from 0192-Backport-SME-aarch64-Explicitly-record-probe-registe.patch rename to 0199-Backport-SME-aarch64-Explicitly-record-probe-registe.patch diff --git a/0193-Backport-SME-aarch64-Remove-below_hard_fp_saved_regs.patch b/0200-Backport-SME-aarch64-Remove-below_hard_fp_saved_regs.patch similarity index 100% rename from 0193-Backport-SME-aarch64-Remove-below_hard_fp_saved_regs.patch rename to 0200-Backport-SME-aarch64-Remove-below_hard_fp_saved_regs.patch diff --git a/0194-Backport-SME-aarch64-Make-stack-smash-canary-protect.patch b/0201-Backport-SME-aarch64-Make-stack-smash-canary-protect.patch similarity index 100% rename from 0194-Backport-SME-aarch64-Make-stack-smash-canary-protect.patch rename to 0201-Backport-SME-aarch64-Make-stack-smash-canary-protect.patch diff --git a/0195-Backport-SME-Handle-epilogues-that-contain-jumps.patch b/0202-Backport-SME-Handle-epilogues-that-contain-jumps.patch similarity index 100% rename from 0195-Backport-SME-Handle-epilogues-that-contain-jumps.patch rename to 0202-Backport-SME-Handle-epilogues-that-contain-jumps.patch diff --git a/0196-Backport-SME-aarch64-Use-vecs-to-store-register-save.patch b/0203-Backport-SME-aarch64-Use-vecs-to-store-register-save.patch similarity index 100% rename from 0196-Backport-SME-aarch64-Use-vecs-to-store-register-save.patch rename to 0203-Backport-SME-aarch64-Use-vecs-to-store-register-save.patch diff --git a/0197-Backport-SME-aarch64-Put-LR-save-slot-first-in-more-.patch b/0204-Backport-SME-aarch64-Put-LR-save-slot-first-in-more-.patch similarity index 100% rename from 0197-Backport-SME-aarch64-Put-LR-save-slot-first-in-more-.patch rename to 0204-Backport-SME-aarch64-Put-LR-save-slot-first-in-more-.patch diff --git a/0198-Backport-SME-aarch64-Switch-PSTATE.SM-around-calls.patch b/0205-Backport-SME-aarch64-Switch-PSTATE.SM-around-calls.patch similarity index 100% rename from 0198-Backport-SME-aarch64-Switch-PSTATE.SM-around-calls.patch rename to 0205-Backport-SME-aarch64-Switch-PSTATE.SM-around-calls.patch diff --git a/0199-Backport-SME-aarch64-Add-support-for-SME-ZA-attribut.patch b/0206-Backport-SME-aarch64-Add-support-for-SME-ZA-attribut.patch similarity index 100% rename from 0199-Backport-SME-aarch64-Add-support-for-SME-ZA-attribut.patch rename to 0206-Backport-SME-aarch64-Add-support-for-SME-ZA-attribut.patch diff --git a/0200-Backport-SME-aarch64-Add-a-register-class-for-w12-w1.patch b/0207-Backport-SME-aarch64-Add-a-register-class-for-w12-w1.patch similarity index 100% rename from 0200-Backport-SME-aarch64-Add-a-register-class-for-w12-w1.patch rename to 0207-Backport-SME-aarch64-Add-a-register-class-for-w12-w1.patch diff --git a/0201-Backport-SME-aarch64-Add-a-VNx1TI-mode.patch b/0208-Backport-SME-aarch64-Add-a-VNx1TI-mode.patch similarity index 100% rename from 0201-Backport-SME-aarch64-Add-a-VNx1TI-mode.patch rename to 0208-Backport-SME-aarch64-Add-a-VNx1TI-mode.patch diff --git a/0202-Backport-SME-aarch64-Generalise-unspec_based_functio.patch b/0209-Backport-SME-aarch64-Generalise-unspec_based_functio.patch similarity index 100% rename from 0202-Backport-SME-aarch64-Generalise-unspec_based_functio.patch rename to 0209-Backport-SME-aarch64-Generalise-unspec_based_functio.patch diff --git a/0203-Backport-SME-aarch64-Generalise-_m-rules-for-SVE-int.patch b/0210-Backport-SME-aarch64-Generalise-_m-rules-for-SVE-int.patch similarity index 100% rename from 0203-Backport-SME-aarch64-Generalise-_m-rules-for-SVE-int.patch rename to 0210-Backport-SME-aarch64-Generalise-_m-rules-for-SVE-int.patch diff --git a/0204-Backport-SME-aarch64-Add-support-for-arm_sme.h.patch b/0211-Backport-SME-aarch64-Add-support-for-arm_sme.h.patch similarity index 100% rename from 0204-Backport-SME-aarch64-Add-support-for-arm_sme.h.patch rename to 0211-Backport-SME-aarch64-Add-support-for-arm_sme.h.patch diff --git a/0205-Backport-SME-aarch64-Add-support-for-__arm_locally_s.patch b/0212-Backport-SME-aarch64-Add-support-for-__arm_locally_s.patch similarity index 100% rename from 0205-Backport-SME-aarch64-Add-support-for-__arm_locally_s.patch rename to 0212-Backport-SME-aarch64-Add-support-for-__arm_locally_s.patch diff --git a/0206-Backport-SME-aarch64-Handle-PSTATE.SM-across-abnorma.patch b/0213-Backport-SME-aarch64-Handle-PSTATE.SM-across-abnorma.patch similarity index 100% rename from 0206-Backport-SME-aarch64-Handle-PSTATE.SM-across-abnorma.patch rename to 0213-Backport-SME-aarch64-Handle-PSTATE.SM-across-abnorma.patch diff --git a/0207-Backport-SME-aarch64-Enforce-inlining-restrictions-f.patch b/0214-Backport-SME-aarch64-Enforce-inlining-restrictions-f.patch similarity index 100% rename from 0207-Backport-SME-aarch64-Enforce-inlining-restrictions-f.patch rename to 0214-Backport-SME-aarch64-Enforce-inlining-restrictions-f.patch diff --git a/0208-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch b/0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch similarity index 100% rename from 0208-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch rename to 0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch diff --git a/0209-Backport-SME-libgcc-aarch64-Configure-check-for-.var.patch b/0216-Backport-SME-libgcc-aarch64-Configure-check-for-.var.patch similarity index 100% rename from 0209-Backport-SME-libgcc-aarch64-Configure-check-for-.var.patch rename to 0216-Backport-SME-libgcc-aarch64-Configure-check-for-.var.patch diff --git a/0210-Backport-SME-libgcc-aarch64-Configure-check-for-__ge.patch b/0217-Backport-SME-libgcc-aarch64-Configure-check-for-__ge.patch similarity index 100% rename from 0210-Backport-SME-libgcc-aarch64-Configure-check-for-__ge.patch rename to 0217-Backport-SME-libgcc-aarch64-Configure-check-for-__ge.patch diff --git a/0211-Backport-SME-libgcc-aarch64-Add-SME-runtime-support.patch b/0218-Backport-SME-libgcc-aarch64-Add-SME-runtime-support.patch similarity index 100% rename from 0211-Backport-SME-libgcc-aarch64-Add-SME-runtime-support.patch rename to 0218-Backport-SME-libgcc-aarch64-Add-SME-runtime-support.patch diff --git a/0212-Backport-SME-libgcc-aarch64-Add-SME-unwinder-support.patch b/0219-Backport-SME-libgcc-aarch64-Add-SME-unwinder-support.patch similarity index 100% rename from 0212-Backport-SME-libgcc-aarch64-Add-SME-unwinder-support.patch rename to 0219-Backport-SME-libgcc-aarch64-Add-SME-unwinder-support.patch diff --git a/0213-Backport-SME-libgcc-Fix-config.in.patch b/0220-Backport-SME-libgcc-Fix-config.in.patch similarity index 100% rename from 0213-Backport-SME-libgcc-Fix-config.in.patch rename to 0220-Backport-SME-libgcc-Fix-config.in.patch diff --git a/0214-Backport-SME-aarch64-Add-funwind-tables-to-some-test.patch b/0221-Backport-SME-aarch64-Add-funwind-tables-to-some-test.patch similarity index 100% rename from 0214-Backport-SME-aarch64-Add-funwind-tables-to-some-test.patch rename to 0221-Backport-SME-aarch64-Add-funwind-tables-to-some-test.patch diff --git a/0215-Backport-SME-aarch64-Skip-some-SME-register-save-tes.patch b/0222-Backport-SME-aarch64-Skip-some-SME-register-save-tes.patch similarity index 100% rename from 0215-Backport-SME-aarch64-Skip-some-SME-register-save-tes.patch rename to 0222-Backport-SME-aarch64-Skip-some-SME-register-save-tes.patch diff --git a/0216-Backport-SME-Add-OPTIONS_H_EXTRA-to-GTFILES.patch b/0223-Backport-SME-Add-OPTIONS_H_EXTRA-to-GTFILES.patch similarity index 100% rename from 0216-Backport-SME-Add-OPTIONS_H_EXTRA-to-GTFILES.patch rename to 0223-Backport-SME-Add-OPTIONS_H_EXTRA-to-GTFILES.patch diff --git a/0217-Backport-SME-aarch64-Add-V1DI-mode.patch b/0224-Backport-SME-aarch64-Add-V1DI-mode.patch similarity index 100% rename from 0217-Backport-SME-aarch64-Add-V1DI-mode.patch rename to 0224-Backport-SME-aarch64-Add-V1DI-mode.patch diff --git a/0218-Backport-SME-Allow-md-iterators-to-include-other-ite.patch b/0225-Backport-SME-Allow-md-iterators-to-include-other-ite.patch similarity index 100% rename from 0218-Backport-SME-Allow-md-iterators-to-include-other-ite.patch rename to 0225-Backport-SME-Allow-md-iterators-to-include-other-ite.patch diff --git a/0219-Backport-SME-riscv-Add-support-for-strlen-inline-exp.patch b/0226-Backport-SME-riscv-Add-support-for-strlen-inline-exp.patch similarity index 100% rename from 0219-Backport-SME-riscv-Add-support-for-strlen-inline-exp.patch rename to 0226-Backport-SME-riscv-Add-support-for-strlen-inline-exp.patch diff --git a/0220-Backport-SME-attribs-Add-overloads-with-namespace-na.patch b/0227-Backport-SME-attribs-Add-overloads-with-namespace-na.patch similarity index 100% rename from 0220-Backport-SME-attribs-Add-overloads-with-namespace-na.patch rename to 0227-Backport-SME-attribs-Add-overloads-with-namespace-na.patch diff --git a/0221-Backport-SME-vec-Add-array_slice-constructors-from-n.patch b/0228-Backport-SME-vec-Add-array_slice-constructors-from-n.patch similarity index 100% rename from 0221-Backport-SME-vec-Add-array_slice-constructors-from-n.patch rename to 0228-Backport-SME-vec-Add-array_slice-constructors-from-n.patch diff --git a/0222-Backport-SME-A-couple-of-va_gc_atomic-tweaks.patch b/0229-Backport-SME-A-couple-of-va_gc_atomic-tweaks.patch similarity index 100% rename from 0222-Backport-SME-A-couple-of-va_gc_atomic-tweaks.patch rename to 0229-Backport-SME-A-couple-of-va_gc_atomic-tweaks.patch diff --git a/0223-Backport-SME-middle-end-Fix-issue-of-poly_uint16-1-1.patch b/0230-Backport-SME-middle-end-Fix-issue-of-poly_uint16-1-1.patch similarity index 100% rename from 0223-Backport-SME-middle-end-Fix-issue-of-poly_uint16-1-1.patch rename to 0230-Backport-SME-middle-end-Fix-issue-of-poly_uint16-1-1.patch diff --git a/0224-SME-Add-missing-header-file-in-aarch64.cc.patch b/0231-SME-Add-missing-header-file-in-aarch64.cc.patch similarity index 100% rename from 0224-SME-Add-missing-header-file-in-aarch64.cc.patch rename to 0231-SME-Add-missing-header-file-in-aarch64.cc.patch diff --git a/0225-Backport-SME-c-Add-support-for-__extension__.patch b/0232-Backport-SME-c-Add-support-for-__extension__.patch similarity index 100% rename from 0225-Backport-SME-c-Add-support-for-__extension__.patch rename to 0232-Backport-SME-c-Add-support-for-__extension__.patch diff --git a/0226-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch b/0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch similarity index 100% rename from 0226-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch rename to 0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch diff --git a/0227-Backport-SME-c-Support-C2x-empty-initializer-braces.patch b/0234-Backport-SME-c-Support-C2x-empty-initializer-braces.patch similarity index 100% rename from 0227-Backport-SME-c-Support-C2x-empty-initializer-braces.patch rename to 0234-Backport-SME-c-Support-C2x-empty-initializer-braces.patch diff --git a/0228-Backport-SME-aarch64-Update-sizeless-tests-for-recen.patch b/0235-Backport-SME-aarch64-Update-sizeless-tests-for-recen.patch similarity index 100% rename from 0228-Backport-SME-aarch64-Update-sizeless-tests-for-recen.patch rename to 0235-Backport-SME-aarch64-Update-sizeless-tests-for-recen.patch diff --git a/0229-Backport-SME-attribs-Namespace-aware-lookup_attribut.patch b/0236-Backport-SME-attribs-Namespace-aware-lookup_attribut.patch similarity index 100% rename from 0229-Backport-SME-attribs-Namespace-aware-lookup_attribut.patch rename to 0236-Backport-SME-attribs-Namespace-aware-lookup_attribut.patch diff --git a/0230-Backport-SME-c-family-ICE-with-gnu-nocf_check-PR1069.patch b/0237-Backport-SME-c-family-ICE-with-gnu-nocf_check-PR1069.patch similarity index 100% rename from 0230-Backport-SME-c-family-ICE-with-gnu-nocf_check-PR1069.patch rename to 0237-Backport-SME-c-family-ICE-with-gnu-nocf_check-PR1069.patch diff --git a/0231-Backport-SME-AArch64-Fix-assert-in-aarch64_move_imm-.patch b/0238-Backport-SME-AArch64-Fix-assert-in-aarch64_move_imm-.patch similarity index 100% rename from 0231-Backport-SME-AArch64-Fix-assert-in-aarch64_move_imm-.patch rename to 0238-Backport-SME-AArch64-Fix-assert-in-aarch64_move_imm-.patch diff --git a/0232-Backport-SME-testsuite-Only-run-fcf-protection-test-.patch b/0239-Backport-SME-testsuite-Only-run-fcf-protection-test-.patch similarity index 100% rename from 0232-Backport-SME-testsuite-Only-run-fcf-protection-test-.patch rename to 0239-Backport-SME-testsuite-Only-run-fcf-protection-test-.patch diff --git a/0233-Backport-SME-Fix-PRs-106764-106765-and-107307-all-IC.patch b/0240-Backport-SME-Fix-PRs-106764-106765-and-107307-all-IC.patch similarity index 100% rename from 0233-Backport-SME-Fix-PRs-106764-106765-and-107307-all-IC.patch rename to 0240-Backport-SME-Fix-PRs-106764-106765-and-107307-all-IC.patch diff --git a/0234-Backport-SME-aarch64-Remove-expected-error-for-compo.patch b/0241-Backport-SME-aarch64-Remove-expected-error-for-compo.patch similarity index 100% rename from 0234-Backport-SME-aarch64-Remove-expected-error-for-compo.patch rename to 0241-Backport-SME-aarch64-Remove-expected-error-for-compo.patch diff --git a/0235-Backport-SME-aarch64-Remove-redundant-builtins-code.patch b/0242-Backport-SME-aarch64-Remove-redundant-builtins-code.patch similarity index 100% rename from 0235-Backport-SME-aarch64-Remove-redundant-builtins-code.patch rename to 0242-Backport-SME-aarch64-Remove-redundant-builtins-code.patch diff --git a/0236-Backport-SME-AArch64-Fix-Armv9-a-warnings-that-get-e.patch b/0243-Backport-SME-AArch64-Fix-Armv9-a-warnings-that-get-e.patch similarity index 100% rename from 0236-Backport-SME-AArch64-Fix-Armv9-a-warnings-that-get-e.patch rename to 0243-Backport-SME-AArch64-Fix-Armv9-a-warnings-that-get-e.patch diff --git a/0237-Backport-SME-Canonicalize-X-Y-as-X-Y-in-match.pd-whe.patch b/0244-Backport-SME-Canonicalize-X-Y-as-X-Y-in-match.pd-whe.patch similarity index 100% rename from 0237-Backport-SME-Canonicalize-X-Y-as-X-Y-in-match.pd-whe.patch rename to 0244-Backport-SME-Canonicalize-X-Y-as-X-Y-in-match.pd-whe.patch diff --git a/0238-Backport-SME-middle-end-Add-new-tbranch-optab-to-add.patch b/0245-Backport-SME-middle-end-Add-new-tbranch-optab-to-add.patch similarity index 100% rename from 0238-Backport-SME-middle-end-Add-new-tbranch-optab-to-add.patch rename to 0245-Backport-SME-middle-end-Add-new-tbranch-optab-to-add.patch diff --git a/0239-Backport-SME-explow-Allow-dynamic-allocations-after-.patch b/0246-Backport-SME-explow-Allow-dynamic-allocations-after-.patch similarity index 100% rename from 0239-Backport-SME-explow-Allow-dynamic-allocations-after-.patch rename to 0246-Backport-SME-explow-Allow-dynamic-allocations-after-.patch diff --git a/0240-Backport-SME-PR105169-Fix-references-to-discarded-se.patch b/0247-Backport-SME-PR105169-Fix-references-to-discarded-se.patch similarity index 100% rename from 0240-Backport-SME-PR105169-Fix-references-to-discarded-se.patch rename to 0247-Backport-SME-PR105169-Fix-references-to-discarded-se.patch diff --git a/0241-Backport-SME-RISC-V-autovec-Verify-that-GET_MODE_NUN.patch b/0248-Backport-SME-RISC-V-autovec-Verify-that-GET_MODE_NUN.patch similarity index 100% rename from 0241-Backport-SME-RISC-V-autovec-Verify-that-GET_MODE_NUN.patch rename to 0248-Backport-SME-RISC-V-autovec-Verify-that-GET_MODE_NUN.patch diff --git a/0242-Backport-SME-Add-operator-to-gimple_stmt_iterator-an.patch b/0249-Backport-SME-Add-operator-to-gimple_stmt_iterator-an.patch similarity index 100% rename from 0242-Backport-SME-Add-operator-to-gimple_stmt_iterator-an.patch rename to 0249-Backport-SME-Add-operator-to-gimple_stmt_iterator-an.patch diff --git a/0243-Backport-SME-tree-optimization-110221-SLP-and-loop-m.patch b/0250-Backport-SME-tree-optimization-110221-SLP-and-loop-m.patch similarity index 100% rename from 0243-Backport-SME-tree-optimization-110221-SLP-and-loop-m.patch rename to 0250-Backport-SME-tree-optimization-110221-SLP-and-loop-m.patch diff --git a/0244-SME-Adapt-some-testsuites.patch b/0251-SME-Adapt-some-testsuites.patch similarity index 100% rename from 0244-SME-Adapt-some-testsuites.patch rename to 0251-SME-Adapt-some-testsuites.patch diff --git a/0245-SME-Fix-error-by-backported-patches-and-IPA-prefetch.patch b/0252-SME-Fix-error-by-backported-patches-and-IPA-prefetch.patch similarity index 100% rename from 0245-SME-Fix-error-by-backported-patches-and-IPA-prefetch.patch rename to 0252-SME-Fix-error-by-backported-patches-and-IPA-prefetch.patch diff --git a/0246-aarch64-Fix-return-register-handling-in-untyped_call.patch b/0253-aarch64-Fix-return-register-handling-in-untyped_call.patch similarity index 100% rename from 0246-aarch64-Fix-return-register-handling-in-untyped_call.patch rename to 0253-aarch64-Fix-return-register-handling-in-untyped_call.patch diff --git a/0247-aarch64-Fix-loose-ldpstp-check.patch b/0254-aarch64-Fix-loose-ldpstp-check.patch similarity index 100% rename from 0247-aarch64-Fix-loose-ldpstp-check.patch rename to 0254-aarch64-Fix-loose-ldpstp-check.patch diff --git a/0255-x86-Add-a-new-option-mdaz-ftz-to-enable-FTZ-and-DAZ-.patch b/0255-x86-Add-a-new-option-mdaz-ftz-to-enable-FTZ-and-DAZ-.patch new file mode 100644 index 0000000000000000000000000000000000000000..d96f5522cbd50867bcc32a75bebd762023166466 --- /dev/null +++ b/0255-x86-Add-a-new-option-mdaz-ftz-to-enable-FTZ-and-DAZ-.patch @@ -0,0 +1,135 @@ +From 1649f9fbbc5267de2a675336d3ac665528a03db8 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Wed, 10 May 2023 15:16:58 +0800 +Subject: [PATCH 01/28] x86: Add a new option -mdaz-ftz to enable FTZ and DAZ + flags in MXCSR. + + if (mdaz-ftz) + link crtfastmath.o + else if ((Ofast || ffast-math || funsafe-math-optimizations) + && !mno-daz-ftz) + link crtfastmath.o + else + Don't link crtfastmath.o + +gcc/ChangeLog: + + * config/i386/cygwin.h (ENDFILE_SPEC): Link crtfastmath.o + whenever -mdaz-ftz is specified. Don't link crtfastmath.o + when -mno-daz-ftz is specified. + * config/i386/darwin.h (ENDFILE_SPEC): Ditto. + * config/i386/gnu-user-common.h + (GNU_USER_TARGET_MATHFILE_SPEC): Ditto. + * config/i386/mingw32.h (ENDFILE_SPEC): Ditto. + * config/i386/i386.opt (mdaz-ftz): New option. + * doc/invoke.texi (x86 options): Document mftz-daz. +--- + gcc/config/i386/cygwin.h | 2 +- + gcc/config/i386/darwin.h | 4 ++-- + gcc/config/i386/gnu-user-common.h | 2 +- + gcc/config/i386/i386.opt | 4 ++++ + gcc/config/i386/mingw32.h | 2 +- + gcc/doc/invoke.texi | 11 ++++++++++- + 6 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h +index d06eda369..5412c5d44 100644 +--- a/gcc/config/i386/cygwin.h ++++ b/gcc/config/i386/cygwin.h +@@ -57,7 +57,7 @@ along with GCC; see the file COPYING3. If not see + + #undef ENDFILE_SPEC + #define ENDFILE_SPEC \ +- "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s}\ ++ "%{mdaz-ftz:crtfastmath.o%s;Ofast|ffast-math|funsafe-math-optimizations:%{!mno-daz-ftz:crtfastmath.o%s}} \ + %{!shared:%:if-exists(default-manifest.o%s)}\ + %{fvtable-verify=none:%s; \ + fvtable-verify=preinit:vtv_end.o%s; \ +diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h +index a55f6b2b8..2f773924d 100644 +--- a/gcc/config/i386/darwin.h ++++ b/gcc/config/i386/darwin.h +@@ -109,8 +109,8 @@ along with GCC; see the file COPYING3. If not see + "%{!force_cpusubtype_ALL:-force_cpusubtype_ALL} " + + #undef ENDFILE_SPEC +-#define ENDFILE_SPEC \ +- "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \ ++#define ENDFILE_SPEC ++\ "%{mdaz-ftz:crtfastmath.o%s;Ofast|ffast-math|funsafe-math-optimizations:%{!mno-daz-ftz:crtfastmath.o%s}} \ + %{mpc32:crtprec32.o%s} \ + %{mpc64:crtprec64.o%s} \ + %{mpc80:crtprec80.o%s}" TM_DESTRUCTOR +diff --git a/gcc/config/i386/gnu-user-common.h b/gcc/config/i386/gnu-user-common.h +index 23b54c5be..3d2a33f17 100644 +--- a/gcc/config/i386/gnu-user-common.h ++++ b/gcc/config/i386/gnu-user-common.h +@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see + + /* Similar to standard GNU userspace, but adding -ffast-math support. */ + #define GNU_USER_TARGET_MATHFILE_SPEC \ +- "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \ ++ "%{mdaz-ftz:crtfastmath.o%s;Ofast|ffast-math|funsafe-math-optimizations:%{!mno-daz-ftz:crtfastmath.o%s}} \ + %{mpc32:crtprec32.o%s} \ + %{mpc64:crtprec64.o%s} \ + %{mpc80:crtprec80.o%s}" +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index fc1b944ac..498fb454d 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -420,6 +420,10 @@ mpc80 + Target RejectNegative + Set 80387 floating-point precision to 80-bit. + ++mdaz-ftz ++Target ++Set the FTZ and DAZ Flags. ++ + mpreferred-stack-boundary= + Target RejectNegative Joined UInteger Var(ix86_preferred_stack_boundary_arg) + Attempt to keep stack aligned to this power of 2. +diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h +index d3ca0cd02..ddbe6a405 100644 +--- a/gcc/config/i386/mingw32.h ++++ b/gcc/config/i386/mingw32.h +@@ -197,7 +197,7 @@ along with GCC; see the file COPYING3. If not see + + #undef ENDFILE_SPEC + #define ENDFILE_SPEC \ +- "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \ ++ "%{mdaz-ftz:crtfastmath.o%s;Ofast|ffast-math|funsafe-math-optimizations:%{!mno-daz-ftz:crtfastmath.o%s}} \ + %{!shared:%:if-exists(default-manifest.o%s)}\ + %{fvtable-verify=none:%s; \ + fvtable-verify=preinit:vtv_end.o%s; \ +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 2b376e0e9..3a48655e5 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1437,7 +1437,7 @@ See RS/6000 and PowerPC Options. + -m96bit-long-double -mlong-double-64 -mlong-double-80 -mlong-double-128 @gol + -mregparm=@var{num} -msseregparm @gol + -mveclibabi=@var{type} -mvect8-ret-in-mem @gol +--mpc32 -mpc64 -mpc80 -mstackrealign @gol ++-mpc32 -mpc64 -mpc80 -mdaz-ftz -mstackrealign @gol + -momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol + -mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol + -m32 -m64 -mx32 -m16 -miamcu -mlarge-data-threshold=@var{num} @gol +@@ -32122,6 +32122,15 @@ are enabled by default; routines in such libraries could suffer significant + loss of accuracy, typically through so-called ``catastrophic cancellation'', + when this option is used to set the precision to less than extended precision. + ++@item -mdaz-ftz ++@opindex mdaz-ftz ++ ++The flush-to-zero (FTZ) and denormals-are-zero (DAZ) flags in the MXCSR register ++are used to control floating-point calculations.SSE and AVX instructions ++including scalar and vector instructions could benefit from enabling the FTZ ++and DAZ flags when @option{-mdaz-ftz} is specified. Don't set FTZ/DAZ flags ++when @option{-mno-daz-ftz} is specified. ++ + @item -mstackrealign + @opindex mstackrealign + Realign the stack at entry. On the x86, the @option{-mstackrealign} +-- +2.31.1 + diff --git a/0256-Explicitly-view_convert_expr-mask-to-signed-type-whe.patch b/0256-Explicitly-view_convert_expr-mask-to-signed-type-whe.patch new file mode 100644 index 0000000000000000000000000000000000000000..39c89169c317fc2f55c2a5458bf3db55cb332b66 --- /dev/null +++ b/0256-Explicitly-view_convert_expr-mask-to-signed-type-whe.patch @@ -0,0 +1,65 @@ +From e70fa730dcfcb3a7b1d56a2e166752d4299f0504 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Mon, 5 Jun 2023 12:38:41 +0800 +Subject: [PATCH 02/28] Explicitly view_convert_expr mask to signed type when + folding pblendvb builtins. + +Since mask < 0 will be always false for vector char when +-funsigned-char, but vpblendvb needs to check the most significant +bit. The patch explicitly VCE to vector signed char. + +gcc/ChangeLog: + + PR target/110108 + * config/i386/i386.cc (ix86_gimple_fold_builtin): Explicitly + view_convert_expr mask to signed type when folding pblendvb + builtins. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/pr110108-2.c: New test. +--- + gcc/config/i386/i386.cc | 4 +++- + gcc/testsuite/gcc.target/i386/pr110108-2.c | 14 ++++++++++++++ + 2 files changed, 17 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/i386/pr110108-2.c + +diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc +index 462dce10e..479fc6010 100644 +--- a/gcc/config/i386/i386.cc ++++ b/gcc/config/i386/i386.cc +@@ -18396,8 +18396,10 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi) + tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode + ? intSI_type_node : intDI_type_node; + type = get_same_sized_vectype (itype, type); +- arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2); + } ++ else ++ type = signed_type_for (type); ++ arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2); + tree zero_vec = build_zero_cst (type); + tree cmp_type = truth_type_for (type); + tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec); +diff --git a/gcc/testsuite/gcc.target/i386/pr110108-2.c b/gcc/testsuite/gcc.target/i386/pr110108-2.c +new file mode 100644 +index 000000000..2d1d2fd49 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr110108-2.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mavx2 -O2 -funsigned-char" } */ ++/* { dg-final { scan-assembler-times "vpblendvb" 2 } } */ ++ ++#include ++__m128i do_stuff_128(__m128i X0, __m128i X1, __m128i X2) { ++ __m128i Result = _mm_blendv_epi8(X0, X1, X2); ++ return Result; ++} ++ ++__m256i do_stuff_256(__m256i X0, __m256i X1, __m256i X2) { ++ __m256i Result = _mm256_blendv_epi8(X0, X1, X2); ++ return Result; ++} +-- +2.31.1 + diff --git a/0257-Make-option-mvzeroupper-independent-of-optimization-.patch b/0257-Make-option-mvzeroupper-independent-of-optimization-.patch new file mode 100644 index 0000000000000000000000000000000000000000..ffdffb163293589aa92a1bc71bb4e1f38e48f289 --- /dev/null +++ b/0257-Make-option-mvzeroupper-independent-of-optimization-.patch @@ -0,0 +1,138 @@ +From 48715f03ad08f185153bfb0ff4c0802ab2d9579c Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Mon, 26 Jun 2023 09:50:25 +0800 +Subject: [PATCH 03/28] Make option mvzeroupper independent of optimization + level. + +pass_insert_vzeroupper is under condition + +TARGET_AVX && TARGET_VZEROUPPER +&& flag_expensive_optimizations && !optimize_size + +But the document of mvzeroupper doesn't mention the insertion +required -O2 and above, it may confuse users when they explicitly +use -Os -mvzeroupper. + +------------ +mvzeroupper +Target Mask(VZEROUPPER) Save +Generate vzeroupper instruction before a transfer of control flow out of +the function. +------------ + +The patch moves flag_expensive_optimizations && !optimize_size to +ix86_option_override_internal. It makes -mvzeroupper independent of +optimization level, but still keeps the behavior of architecture +tuning(emit_vzeroupper) unchanged. + +gcc/ChangeLog: + + * config/i386/i386-features.cc (pass_insert_vzeroupper:gate): + Move flag_expensive_optimizations && !optimize_size to .. + * config/i386/i386-options.cc (ix86_option_override_internal): + .. this, it makes -mvzeroupper independent of optimization + level, but still keeps the behavior of architecture + tuning(emit_vzeroupper) unchanged. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/avx-vzeroupper-29.c: New testcase. + * gcc.target/i386/avx-vzeroupper-12.c: Adjust testcase. + * gcc.target/i386/avx-vzeroupper-7.c: Ditto. + * gcc.target/i386/avx-vzeroupper-9.c: Ditto. +--- + gcc/config/i386/i386-features.cc | 3 +-- + gcc/config/i386/i386-options.cc | 4 +++- + gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c | 3 ++- + gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c | 14 ++++++++++++++ + gcc/testsuite/gcc.target/i386/avx-vzeroupper-7.c | 3 ++- + gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c | 3 ++- + 6 files changed, 24 insertions(+), 6 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c + +diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc +index 6fe41c3c2..6a2444eb6 100644 +--- a/gcc/config/i386/i386-features.cc ++++ b/gcc/config/i386/i386-features.cc +@@ -1875,8 +1875,7 @@ public: + /* opt_pass methods: */ + virtual bool gate (function *) + { +- return TARGET_AVX && TARGET_VZEROUPPER +- && flag_expensive_optimizations && !optimize_size; ++ return TARGET_AVX && TARGET_VZEROUPPER; + } + + virtual unsigned int execute (function *) +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index ff44ad4e0..74e969b68 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -2702,7 +2702,9 @@ ix86_option_override_internal (bool main_args_p, + sorry ("%<-mcall-ms2sysv-xlogues%> isn%'t currently supported with SEH"); + + if (!(opts_set->x_target_flags & MASK_VZEROUPPER) +- && TARGET_EMIT_VZEROUPPER) ++ && TARGET_EMIT_VZEROUPPER ++ && flag_expensive_optimizations ++ && !optimize_size) + opts->x_target_flags |= MASK_VZEROUPPER; + if (!(opts_set->x_target_flags & MASK_STV)) + opts->x_target_flags |= MASK_STV; +diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c +index e694d4048..5a40e8783 100644 +--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c ++++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c +@@ -16,5 +16,6 @@ foo () + _mm256_zeroupper (); + } + +-/* { dg-final { scan-assembler-times "avx_vzeroupper" 4 } } */ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 4 { target ia32 } } } */ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 5 { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler-times "\\*avx_vzeroall" 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c +new file mode 100644 +index 000000000..4af637757 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-29.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O0 -mavx -mtune=generic -mvzeroupper -dp" } */ ++ ++#include ++ ++extern __m256 x, y; ++ ++void ++foo () ++{ ++ x = y; ++} ++ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-7.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-7.c +index ab6d68779..75fe58897 100644 +--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-7.c ++++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-7.c +@@ -12,4 +12,5 @@ foo () + _mm256_zeroupper (); + } + +-/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 { target ia32 } } } */ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 2 { target { ! ia32 } } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c +index 974e1626a..fa0a6dfca 100644 +--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c ++++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c +@@ -15,4 +15,5 @@ foo () + _mm256_zeroupper (); + } + +-/* { dg-final { scan-assembler-times "avx_vzeroupper" 4 } } */ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 4 { target ia32 } } } */ ++/* { dg-final { scan-assembler-times "avx_vzeroupper" 5 { target { ! ia32 } } } } */ +-- +2.31.1 + diff --git a/0258-i386-Sync-tune_string-with-arch_string-for-target-at.patch b/0258-i386-Sync-tune_string-with-arch_string-for-target-at.patch new file mode 100644 index 0000000000000000000000000000000000000000..d36524685ae33d03009fdf5b4f1316dedb1677d9 --- /dev/null +++ b/0258-i386-Sync-tune_string-with-arch_string-for-target-at.patch @@ -0,0 +1,68 @@ +From 8039d773354360ed8ff2f25c63843fc637eacc67 Mon Sep 17 00:00:00 2001 +From: Hongyu Wang +Date: Sun, 25 Jun 2023 09:50:21 +0800 +Subject: [PATCH 04/28] i386: Sync tune_string with arch_string for target + attribute + +arch=* + +For function with target attribute arch=*, current logic will set its +tune to -mtune from command line so all target_clones will get same +tuning flags which would affect the performance for each clone. Override +tune with arch if tune was not explicitly specified to get proper tuning +flags for target_clones. + +gcc/ChangeLog: + + * config/i386/i386-options.cc (ix86_valid_target_attribute_tree): + Override tune_string with arch_string if tune_string is not + explicitly specified. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/mvc17.c: New test. + +(cherry picked from commit 2916278d14e9ac28c361c396a67256acbebda6e8) +--- + gcc/config/i386/i386-options.cc | 6 +++++- + gcc/testsuite/gcc.target/i386/mvc17.c | 11 +++++++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/i386/mvc17.c + +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 74e969b68..fb2ed942f 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -1378,7 +1378,11 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args, + if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]) + opts->x_ix86_tune_string + = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]); +- else if (orig_tune_defaulted) ++ /* If we have explicit arch string and no tune string specified, set ++ tune_string to NULL and later it will be overriden by arch_string ++ so target clones can get proper optimization. */ ++ else if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH] ++ || orig_tune_defaulted) + opts->x_ix86_tune_string = NULL; + + /* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */ +diff --git a/gcc/testsuite/gcc.target/i386/mvc17.c b/gcc/testsuite/gcc.target/i386/mvc17.c +new file mode 100644 +index 000000000..8b83c1aec +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/mvc17.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-require-ifunc "" } */ ++/* { dg-options "-O2 -march=x86-64" } */ ++/* { dg-final { scan-assembler-times "rep mov" 1 } } */ ++ ++__attribute__((target_clones("default","arch=icelake-server"))) ++void ++foo (char *a, char *b, int size) ++{ ++ __builtin_memcpy (a, b, size & 0x7F); ++} +-- +2.31.1 + diff --git a/0259-Refine-maskloadmn-pattern-with-UNSPEC_MASKLOAD.patch b/0259-Refine-maskloadmn-pattern-with-UNSPEC_MASKLOAD.patch new file mode 100644 index 0000000000000000000000000000000000000000..2918d3e883fbd6a916fe97803e03c270a02fc4a0 --- /dev/null +++ b/0259-Refine-maskloadmn-pattern-with-UNSPEC_MASKLOAD.patch @@ -0,0 +1,111 @@ +From fbcb1a5899b1bd3964aed78ed74041121e618d36 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Tue, 20 Jun 2023 15:41:00 +0800 +Subject: [PATCH 05/28] Refine maskloadmn pattern with UNSPEC_MASKLOAD. + +If mem_addr points to a memory region with less than whole vector size +bytes of accessible memory and k is a mask that would prevent reading +the inaccessible bytes from mem_addr, add UNSPEC_MASKLOAD to prevent +it to be transformed to vpblendd. + +gcc/ChangeLog: + + PR target/110309 + * config/i386/sse.md (maskload): + Refine pattern with UNSPEC_MASKLOAD. + (maskload): Ditto. + (*_load_mask): Extend mode iterator to + VI12HF_AVX512VL. + (*_load): Ditto. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/pr110309.c: New test. +--- + gcc/config/i386/sse.md | 32 +++++++++++++----------- + gcc/testsuite/gcc.target/i386/pr110309.c | 10 ++++++++ + 2 files changed, 28 insertions(+), 14 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/pr110309.c + +diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md +index eb767e56c..b30e96cb1 100644 +--- a/gcc/config/i386/sse.md ++++ b/gcc/config/i386/sse.md +@@ -1411,12 +1411,12 @@ + }) + + (define_insn "*_load_mask" +- [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v") +- (vec_merge:VI12_AVX512VL +- (unspec:VI12_AVX512VL +- [(match_operand:VI12_AVX512VL 1 "memory_operand" "m")] ++ [(set (match_operand:VI12HF_AVX512VL 0 "register_operand" "=v") ++ (vec_merge:VI12HF_AVX512VL ++ (unspec:VI12HF_AVX512VL ++ [(match_operand:VI12HF_AVX512VL 1 "memory_operand" "m")] + UNSPEC_MASKLOAD) +- (match_operand:VI12_AVX512VL 2 "nonimm_or_0_operand" "0C") ++ (match_operand:VI12HF_AVX512VL 2 "nonimm_or_0_operand" "0C") + (match_operand: 3 "register_operand" "Yk")))] + "TARGET_AVX512BW" + "vmovdqu\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}" +@@ -1425,9 +1425,9 @@ + (set_attr "mode" "")]) + + (define_insn_and_split "*_load" +- [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v") +- (unspec:VI12_AVX512VL +- [(match_operand:VI12_AVX512VL 1 "memory_operand" "m")] ++ [(set (match_operand:VI12HF_AVX512VL 0 "register_operand" "=v") ++ (unspec:VI12HF_AVX512VL ++ [(match_operand:VI12HF_AVX512VL 1 "memory_operand" "m")] + UNSPEC_MASKLOAD))] + "TARGET_AVX512BW" + "#" +@@ -25973,17 +25973,21 @@ + "TARGET_AVX") + + (define_expand "maskload" +- [(set (match_operand:V48H_AVX512VL 0 "register_operand") +- (vec_merge:V48H_AVX512VL +- (match_operand:V48H_AVX512VL 1 "memory_operand") ++ [(set (match_operand:V48_AVX512VL 0 "register_operand") ++ (vec_merge:V48_AVX512VL ++ (unspec:V48_AVX512VL ++ [(match_operand:V48_AVX512VL 1 "memory_operand")] ++ UNSPEC_MASKLOAD) + (match_dup 0) + (match_operand: 2 "register_operand")))] + "TARGET_AVX512F") + + (define_expand "maskload" +- [(set (match_operand:VI12_AVX512VL 0 "register_operand") +- (vec_merge:VI12_AVX512VL +- (match_operand:VI12_AVX512VL 1 "memory_operand") ++ [(set (match_operand:VI12HF_AVX512VL 0 "register_operand") ++ (vec_merge:VI12HF_AVX512VL ++ (unspec:VI12HF_AVX512VL ++ [(match_operand:VI12HF_AVX512VL 1 "memory_operand")] ++ UNSPEC_MASKLOAD) + (match_dup 0) + (match_operand: 2 "register_operand")))] + "TARGET_AVX512BW") +diff --git a/gcc/testsuite/gcc.target/i386/pr110309.c b/gcc/testsuite/gcc.target/i386/pr110309.c +new file mode 100644 +index 000000000..f6e9e9c3c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr110309.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 --param vect-partial-vector-usage=1 -march=znver4 -mprefer-vector-width=256" } */ ++/* { dg-final { scan-assembler-not {(?n)vpblendd.*ymm} } } */ ++ ++ ++void foo (int * __restrict a, int *b) ++{ ++ for (int i = 0; i < 6; ++i) ++ a[i] = b[i] + 42; ++} +-- +2.31.1 + diff --git a/0260-Refine-maskstore-patterns-with-UNSPEC_MASKMOV.patch b/0260-Refine-maskstore-patterns-with-UNSPEC_MASKMOV.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0546c3b73ece06acdb38e181e6f457a656ff281 --- /dev/null +++ b/0260-Refine-maskstore-patterns-with-UNSPEC_MASKMOV.patch @@ -0,0 +1,126 @@ +From 5ad28ef4010c1248b4d94396d03f863705f7b0db Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Mon, 26 Jun 2023 21:07:09 +0800 +Subject: [PATCH 06/28] Refine maskstore patterns with UNSPEC_MASKMOV. + +Similar like r14-2070-gc79476da46728e + +If mem_addr points to a memory region with less than whole vector size +bytes of accessible memory and k is a mask that would prevent reading +the inaccessible bytes from mem_addr, add UNSPEC_MASKMOV to prevent +it to be transformed to any other whole memory access instructions. + +gcc/ChangeLog: + + PR rtl-optimization/110237 + * config/i386/sse.md (_store_mask): Refine with + UNSPEC_MASKMOV. + (maskstore_store_mask): New define_insn, it's renamed + from original _store_mask. +--- + gcc/config/i386/sse.md | 69 ++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 12 deletions(-) + +diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md +index b30e96cb1..3af159896 100644 +--- a/gcc/config/i386/sse.md ++++ b/gcc/config/i386/sse.md +@@ -1554,7 +1554,7 @@ + (set_attr "prefix" "evex") + (set_attr "mode" "")]) + +-(define_insn "_store_mask" ++(define_insn "*_store_mask" + [(set (match_operand:V48_AVX512VL 0 "memory_operand" "=m") + (vec_merge:V48_AVX512VL + (match_operand:V48_AVX512VL 1 "register_operand" "v") +@@ -1582,7 +1582,7 @@ + (set_attr "memory" "store") + (set_attr "mode" "")]) + +-(define_insn "_store_mask" ++(define_insn "*_store_mask" + [(set (match_operand:VI12HF_AVX512VL 0 "memory_operand" "=m") + (vec_merge:VI12HF_AVX512VL + (match_operand:VI12HF_AVX512VL 1 "register_operand" "v") +@@ -26002,21 +26002,66 @@ + "TARGET_AVX") + + (define_expand "maskstore" +- [(set (match_operand:V48H_AVX512VL 0 "memory_operand") +- (vec_merge:V48H_AVX512VL +- (match_operand:V48H_AVX512VL 1 "register_operand") +- (match_dup 0) +- (match_operand: 2 "register_operand")))] ++ [(set (match_operand:V48_AVX512VL 0 "memory_operand") ++ (unspec:V48_AVX512VL ++ [(match_operand:V48_AVX512VL 1 "register_operand") ++ (match_dup 0) ++ (match_operand: 2 "register_operand")] ++ UNSPEC_MASKMOV))] + "TARGET_AVX512F") + + (define_expand "maskstore" +- [(set (match_operand:VI12_AVX512VL 0 "memory_operand") +- (vec_merge:VI12_AVX512VL +- (match_operand:VI12_AVX512VL 1 "register_operand") +- (match_dup 0) +- (match_operand: 2 "register_operand")))] ++ [(set (match_operand:VI12HF_AVX512VL 0 "memory_operand") ++ (unspec:VI12HF_AVX512VL ++ [(match_operand:VI12HF_AVX512VL 1 "register_operand") ++ (match_dup 0) ++ (match_operand: 2 "register_operand")] ++ UNSPEC_MASKMOV))] + "TARGET_AVX512BW") + ++(define_insn "_store_mask" ++ [(set (match_operand:V48_AVX512VL 0 "memory_operand" "=m") ++ (unspec:V48_AVX512VL ++ [(match_operand:V48_AVX512VL 1 "register_operand" "v") ++ (match_dup 0) ++ (match_operand: 2 "register_operand" "Yk")] ++ UNSPEC_MASKMOV))] ++ "TARGET_AVX512F" ++{ ++ if (FLOAT_MODE_P (GET_MODE_INNER (mode))) ++ { ++ if (misaligned_operand (operands[0], mode)) ++ return "vmovu\t{%1, %0%{%2%}|%0%{%2%}, %1}"; ++ else ++ return "vmova\t{%1, %0%{%2%}|%0%{%2%}, %1}"; ++ } ++ else ++ { ++ if (misaligned_operand (operands[0], mode)) ++ return "vmovdqu\t{%1, %0%{%2%}|%0%{%2%}, %1}"; ++ else ++ return "vmovdqa\t{%1, %0%{%2%}|%0%{%2%}, %1}"; ++ } ++} ++ [(set_attr "type" "ssemov") ++ (set_attr "prefix" "evex") ++ (set_attr "memory" "store") ++ (set_attr "mode" "")]) ++ ++(define_insn "_store_mask" ++ [(set (match_operand:VI12HF_AVX512VL 0 "memory_operand" "=m") ++ (unspec:VI12HF_AVX512VL ++ [(match_operand:VI12HF_AVX512VL 1 "register_operand" "v") ++ (match_dup 0) ++ (match_operand: 2 "register_operand" "Yk")] ++ UNSPEC_MASKMOV))] ++ "TARGET_AVX512BW" ++ "vmovdqu\t{%1, %0%{%2%}|%0%{%2%}, %1}" ++ [(set_attr "type" "ssemov") ++ (set_attr "prefix" "evex") ++ (set_attr "memory" "store") ++ (set_attr "mode" "")]) ++ + (define_expand "cbranch4" + [(set (reg:CC FLAGS_REG) + (compare:CC (match_operand:VI48_AVX 1 "register_operand") +-- +2.31.1 + diff --git a/0261-x86-Update-model-values-for-Alderlake-and-Rocketlake.patch b/0261-x86-Update-model-values-for-Alderlake-and-Rocketlake.patch new file mode 100644 index 0000000000000000000000000000000000000000..889bbdc79c94762611b0c58321e0348536e9f67d --- /dev/null +++ b/0261-x86-Update-model-values-for-Alderlake-and-Rocketlake.patch @@ -0,0 +1,38 @@ +From 50757adc93ef32a97a8a1083f5d53a9c00da6ac8 Mon Sep 17 00:00:00 2001 +From: "Cui, Lili" +Date: Thu, 29 Jun 2023 03:10:35 +0000 +Subject: [PATCH 07/28] x86: Update model values for Alderlake and Rocketlake. + +Update model values for Alderlake and Rocketlake according to SDM. + +gcc/ChangeLog + + * common/config/i386/cpuinfo.h (get_intel_cpu): Remove model value 0xa8 + from Rocketlake, remove model value 0xbf from Alderlake. +--- + gcc/common/config/i386/cpuinfo.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 0333da56b..28b2ff0b0 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -435,7 +435,6 @@ get_intel_cpu (struct __processor_model *cpu_model, + cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE; + break; + case 0xa7: +- case 0xa8: + /* Rocket Lake. */ + cpu = "rocketlake"; + CHECK___builtin_cpu_is ("corei7"); +@@ -508,7 +507,6 @@ get_intel_cpu (struct __processor_model *cpu_model, + break; + case 0x97: + case 0x9a: +- case 0xbf: + /* Alder Lake. */ + cpu = "alderlake"; + CHECK___builtin_cpu_is ("corei7"); +-- +2.31.1 + diff --git a/0262-Workaround-possible-CPUID-bug-in-Sandy-Bridge.patch b/0262-Workaround-possible-CPUID-bug-in-Sandy-Bridge.patch new file mode 100644 index 0000000000000000000000000000000000000000..046351c61d9d3948304b4c92837d81a909559ef3 --- /dev/null +++ b/0262-Workaround-possible-CPUID-bug-in-Sandy-Bridge.patch @@ -0,0 +1,78 @@ +From 60364b439a80c217174e1830e0b7507d6f4538c4 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Fri, 4 Aug 2023 09:27:39 +0800 +Subject: [PATCH 08/28] Workaround possible CPUID bug in Sandy Bridge. + +Don't access leaf 7 subleaf 1 unless subleaf 0 says it is +supported via EAX. + +Intel documentation says invalid subleaves return 0. We had been +relying on that behavior instead of checking the max sublef number. + +It appears that some Sandy Bridge CPUs return at least the subleaf 0 +EDX value for subleaf 1. Best guess is that this is a bug in a +microcode patch since all of the bits we're seeing set in EDX were +introduced after Sandy Bridge was originally released. + +This is causing avxvnniint16 to be incorrectly enabled with +-march=native on these CPUs. + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h (get_available_features): Check + max_subleaf_level for valid subleaf before use CPUID. +--- + gcc/common/config/i386/cpuinfo.h | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 28b2ff0b0..316ad3cb3 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -647,7 +647,9 @@ get_available_features (struct __processor_model *cpu_model, + /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */ + if (max_cpuid_level >= 7) + { +- __cpuid_count (7, 0, eax, ebx, ecx, edx); ++ unsigned int max_subleaf_level; ++ ++ __cpuid_count (7, 0, max_subleaf_level, ebx, ecx, edx); + if (ebx & bit_BMI) + set_feature (FEATURE_BMI); + if (ebx & bit_SGX) +@@ -759,18 +761,21 @@ get_available_features (struct __processor_model *cpu_model, + set_feature (FEATURE_AVX512FP16); + } + +- __cpuid_count (7, 1, eax, ebx, ecx, edx); +- if (eax & bit_HRESET) +- set_feature (FEATURE_HRESET); +- if (avx_usable) +- { +- if (eax & bit_AVXVNNI) +- set_feature (FEATURE_AVXVNNI); +- } +- if (avx512_usable) ++ if (max_subleaf_level >= 1) + { +- if (eax & bit_AVX512BF16) +- set_feature (FEATURE_AVX512BF16); ++ __cpuid_count (7, 1, eax, ebx, ecx, edx); ++ if (eax & bit_HRESET) ++ set_feature (FEATURE_HRESET); ++ if (avx_usable) ++ { ++ if (eax & bit_AVXVNNI) ++ set_feature (FEATURE_AVXVNNI); ++ } ++ if (avx512_usable) ++ { ++ if (eax & bit_AVX512BF16) ++ set_feature (FEATURE_AVX512BF16); ++ } + } + } + +-- +2.31.1 + diff --git a/0263-Software-mitigation-Disable-gather-generation-in-vec.patch b/0263-Software-mitigation-Disable-gather-generation-in-vec.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a1e4e7928d606a9096cae0329d568cee39fccd2 --- /dev/null +++ b/0263-Software-mitigation-Disable-gather-generation-in-vec.patch @@ -0,0 +1,220 @@ +From cfffbec938afdc45c31db5ec282ce21ad1ba2dc7 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Thu, 10 Aug 2023 11:41:39 +0800 +Subject: [PATCH 09/28] Software mitigation: Disable gather generation in + vectorization for GDS affected Intel Processors. + +For more details of GDS (Gather Data Sampling), refer to +https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/gather-data-sampling.html + +After microcode update, there's performance regression. To avoid that, +the patch disables gather generation in autovectorization but uses +gather scalar emulation instead. + +gcc/ChangeLog: + + * config/i386/i386-options.cc (m_GDS): New macro. + * config/i386/x86-tune.def (X86_TUNE_USE_GATHER_2PARTS): Don't + enable for m_GDS. + (X86_TUNE_USE_GATHER_4PARTS): Ditto. + (X86_TUNE_USE_GATHER): Ditto. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/avx2-gather-2.c: Adjust options to keep + gather vectorization. + * gcc.target/i386/avx2-gather-6.c: Ditto. + * gcc.target/i386/avx512f-pr88464-1.c: Ditto. + * gcc.target/i386/avx512f-pr88464-5.c: Ditto. + * gcc.target/i386/avx512vl-pr88464-1.c: Ditto. + * gcc.target/i386/avx512vl-pr88464-11.c: Ditto. + * gcc.target/i386/avx512vl-pr88464-3.c: Ditto. + * gcc.target/i386/avx512vl-pr88464-9.c: Ditto. + * gcc.target/i386/pr88531-1b.c: Ditto. + * gcc.target/i386/pr88531-1c.c: Ditto. + +(cherry picked from commit 3064d1f5c48cb6ce1b4133570dd08ecca8abb52d) +--- + gcc/config/i386/i386-options.cc | 5 +++++ + gcc/config/i386/x86-tune.def | 9 ++++++--- + gcc/testsuite/gcc.target/i386/avx2-gather-2.c | 2 +- + gcc/testsuite/gcc.target/i386/avx2-gather-6.c | 2 +- + gcc/testsuite/gcc.target/i386/avx512f-pr88464-1.c | 2 +- + gcc/testsuite/gcc.target/i386/avx512f-pr88464-5.c | 2 +- + gcc/testsuite/gcc.target/i386/avx512vl-pr88464-1.c | 2 +- + gcc/testsuite/gcc.target/i386/avx512vl-pr88464-11.c | 2 +- + gcc/testsuite/gcc.target/i386/avx512vl-pr88464-3.c | 2 +- + gcc/testsuite/gcc.target/i386/avx512vl-pr88464-9.c | 2 +- + gcc/testsuite/gcc.target/i386/pr88531-1b.c | 2 +- + gcc/testsuite/gcc.target/i386/pr88531-1c.c | 2 +- + 12 files changed, 21 insertions(+), 13 deletions(-) + +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index fb2ed942f..9617fc162 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -137,6 +137,11 @@ along with GCC; see the file COPYING3. If not see + #define m_GOLDMONT_PLUS (HOST_WIDE_INT_1U< +Date: Thu, 10 Aug 2023 16:26:13 +0800 +Subject: [PATCH 10/28] Support -m[no-]gather -m[no-]scatter to enable/disable + vectorization for all gather/scatter instructions + +Rename original use_gather to use_gather_8parts, Support +-mtune-ctrl={,^}use_gather to set/clear tune features +use_gather_{2parts, 4parts, 8parts}. Support the new option -mgather +as alias of -mtune-ctrl=, use_gather, ^use_gather. + +Similar for use_scatter. + +gcc/ChangeLog: + + * config/i386/i386-builtins.cc + (ix86_vectorize_builtin_gather): Adjust for use_gather_8parts. + * config/i386/i386-options.cc (parse_mtune_ctrl_str): + Set/Clear tune features use_{gather,scatter}_{2parts, 4parts, + 8parts} for -mtune-crtl={,^}{use_gather,use_scatter}. + * config/i386/i386.cc (ix86_vectorize_builtin_scatter): Adjust + for use_scatter_8parts + * config/i386/i386.h (TARGET_USE_GATHER): Rename to .. + (TARGET_USE_GATHER_8PARTS): .. this. + (TARGET_USE_SCATTER): Rename to .. + (TARGET_USE_SCATTER_8PARTS): .. this. + * config/i386/x86-tune.def (X86_TUNE_USE_GATHER): Rename to + (X86_TUNE_USE_GATHER_8PARTS): .. this. + (X86_TUNE_USE_SCATTER): Rename to + (X86_TUNE_USE_SCATTER_8PARTS): .. this. + * config/i386/i386.opt: Add new options mgather, mscatter. + +(cherry picked from commit b2a927fb5343db363ea4361da0d6bcee227b6737) +--- + gcc/config/i386/i386-builtins.cc | 2 +- + gcc/config/i386/i386-options.cc | 54 +++++++++++++++++++++++--------- + gcc/config/i386/i386.cc | 2 +- + gcc/config/i386/i386.h | 8 ++--- + gcc/config/i386/i386.opt | 4 +++ + gcc/config/i386/x86-tune.def | 4 +-- + 6 files changed, 52 insertions(+), 22 deletions(-) + +diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc +index 050c6228a..8ed32e14f 100644 +--- a/gcc/config/i386/i386-builtins.cc ++++ b/gcc/config/i386/i386-builtins.cc +@@ -1790,7 +1790,7 @@ ix86_vectorize_builtin_gather (const_tree mem_vectype, + ? !TARGET_USE_GATHER_2PARTS + : (known_eq (TYPE_VECTOR_SUBPARTS (mem_vectype), 4u) + ? !TARGET_USE_GATHER_4PARTS +- : !TARGET_USE_GATHER))) ++ : !TARGET_USE_GATHER_8PARTS))) + return NULL_TREE; + + if ((TREE_CODE (index_type) != INTEGER_TYPE +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 9617fc162..3df1f0c41 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -1705,20 +1705,46 @@ parse_mtune_ctrl_str (struct gcc_options *opts, bool dump) + curr_feature_string++; + clear = true; + } +- for (i = 0; i < X86_TUNE_LAST; i++) +- { +- if (!strcmp (curr_feature_string, ix86_tune_feature_names[i])) +- { +- ix86_tune_features[i] = !clear; +- if (dump) +- fprintf (stderr, "Explicitly %s feature %s\n", +- clear ? "clear" : "set", ix86_tune_feature_names[i]); +- break; +- } +- } +- if (i == X86_TUNE_LAST) +- error ("unknown parameter to option %<-mtune-ctrl%>: %s", +- clear ? curr_feature_string - 1 : curr_feature_string); ++ ++ if (!strcmp (curr_feature_string, "use_gather")) ++ { ++ ix86_tune_features[X86_TUNE_USE_GATHER_2PARTS] = !clear; ++ ix86_tune_features[X86_TUNE_USE_GATHER_4PARTS] = !clear; ++ ix86_tune_features[X86_TUNE_USE_GATHER_8PARTS] = !clear; ++ if (dump) ++ fprintf (stderr, "Explicitly %s features use_gather_2parts," ++ " use_gather_4parts, use_gather_8parts\n", ++ clear ? "clear" : "set"); ++ ++ } ++ else if (!strcmp (curr_feature_string, "use_scatter")) ++ { ++ ix86_tune_features[X86_TUNE_USE_SCATTER_2PARTS] = !clear; ++ ix86_tune_features[X86_TUNE_USE_SCATTER_4PARTS] = !clear; ++ ix86_tune_features[X86_TUNE_USE_SCATTER_8PARTS] = !clear; ++ if (dump) ++ fprintf (stderr, "Explicitly %s features use_scatter_2parts," ++ " use_scatter_4parts, use_scatter_8parts\n", ++ clear ? "clear" : "set"); ++ } ++ else ++ { ++ for (i = 0; i < X86_TUNE_LAST; i++) ++ { ++ if (!strcmp (curr_feature_string, ix86_tune_feature_names[i])) ++ { ++ ix86_tune_features[i] = !clear; ++ if (dump) ++ fprintf (stderr, "Explicitly %s feature %s\n", ++ clear ? "clear" : "set", ix86_tune_feature_names[i]); ++ break; ++ } ++ } ++ ++ if (i == X86_TUNE_LAST) ++ error ("unknown parameter to option %<-mtune-ctrl%>: %s", ++ clear ? curr_feature_string - 1 : curr_feature_string); ++ } + curr_feature_string = next_feature_string; + } + while (curr_feature_string); +diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc +index 479fc6010..e75d37023 100644 +--- a/gcc/config/i386/i386.cc ++++ b/gcc/config/i386/i386.cc +@@ -18937,7 +18937,7 @@ ix86_vectorize_builtin_scatter (const_tree vectype, + ? !TARGET_USE_SCATTER_2PARTS + : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u) + ? !TARGET_USE_SCATTER_4PARTS +- : !TARGET_USE_SCATTER)) ++ : !TARGET_USE_SCATTER_8PARTS)) + return NULL_TREE; + + if ((TREE_CODE (index_type) != INTEGER_TYPE +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 688aaabd3..aaa136ba0 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -403,10 +403,10 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST]; + ix86_tune_features[X86_TUNE_USE_GATHER_4PARTS] + #define TARGET_USE_SCATTER_4PARTS \ + ix86_tune_features[X86_TUNE_USE_SCATTER_4PARTS] +-#define TARGET_USE_GATHER \ +- ix86_tune_features[X86_TUNE_USE_GATHER] +-#define TARGET_USE_SCATTER \ +- ix86_tune_features[X86_TUNE_USE_SCATTER] ++#define TARGET_USE_GATHER_8PARTS \ ++ ix86_tune_features[X86_TUNE_USE_GATHER_8PARTS] ++#define TARGET_USE_SCATTER_8PARTS \ ++ ix86_tune_features[X86_TUNE_USE_SCATTER_8PARTS] + #define TARGET_FUSE_CMP_AND_BRANCH_32 \ + ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH_32] + #define TARGET_FUSE_CMP_AND_BRANCH_64 \ +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 498fb454d..b154110d8 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1222,3 +1222,7 @@ Instructions number above which STFL stall penalty can be compensated. + munroll-only-small-loops + Target Var(ix86_unroll_only_small_loops) Init(0) Save + Enable conservative small loop unrolling. ++ ++mscatter ++Target Alias(mtune-ctrl=, use_scatter, ^use_scatter) ++Enable vectorization for scatter instruction. +diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def +index 4392709fc..bdb455d20 100644 +--- a/gcc/config/i386/x86-tune.def ++++ b/gcc/config/i386/x86-tune.def +@@ -488,13 +488,13 @@ DEF_TUNE (X86_TUNE_USE_SCATTER_4PARTS, "use_scatter_4parts", + + /* X86_TUNE_USE_GATHER: Use gather instructions for vectors with 8 or more + elements. */ +-DEF_TUNE (X86_TUNE_USE_GATHER, "use_gather", ++DEF_TUNE (X86_TUNE_USE_GATHER_8PARTS, "use_gather_8parts", + ~(m_ZNVER1 | m_ZNVER2 | m_ZNVER4 | m_ALDERLAKE + | m_GENERIC | m_GDS)) + + /* X86_TUNE_USE_SCATTER: Use scater instructions for vectors with 8 or more + elements. */ +-DEF_TUNE (X86_TUNE_USE_SCATTER, "use_scatter", ++DEF_TUNE (X86_TUNE_USE_SCATTER_8PARTS, "use_scatter_8parts", + ~(m_ZNVER4)) + + /* X86_TUNE_AVOID_128FMA_CHAINS: Avoid creating loops with tight 128bit or +-- +2.31.1 + diff --git a/0265-Remove-constraint-modifier-for-fcmaddcph-fmaddcph-fc.patch b/0265-Remove-constraint-modifier-for-fcmaddcph-fmaddcph-fc.patch new file mode 100644 index 0000000000000000000000000000000000000000..e2084f6e88c0d07d076589219446c76b84f5ec1c --- /dev/null +++ b/0265-Remove-constraint-modifier-for-fcmaddcph-fmaddcph-fc.patch @@ -0,0 +1,129 @@ +From 764518a35e90a3e13c469275da9c3c7002fe1982 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Fri, 8 Sep 2023 09:22:43 +0800 +Subject: [PATCH 11/28] Remove constraint modifier % for + fcmaddcph/fmaddcph/fcmulcph since there're not commutative. + +gcc/ChangeLog: + + PR target/111306 + PR target/111335 + * config/i386/sse.md (int_comm): New int_attr. + (fma__): + Remove % for Complex conjugate operations since they're not + commutative. + (fma___pair): Ditto. + (___mask): Ditto. + (cmul3): Ditto. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/pr111306.c: New test. + +(cherry picked from commit f197392a16ffb1327f1d12ff8ff05f9295e015cb) +--- + gcc/config/i386/sse.md | 16 ++++++++--- + gcc/testsuite/gcc.target/i386/pr111306.c | 36 ++++++++++++++++++++++++ + 2 files changed, 48 insertions(+), 4 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/pr111306.c + +diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md +index 3af159896..f25dd5f2b 100644 +--- a/gcc/config/i386/sse.md ++++ b/gcc/config/i386/sse.md +@@ -6318,6 +6318,14 @@ + [(UNSPEC_COMPLEX_FMA_PAIR "fmaddc") + (UNSPEC_COMPLEX_FCMA_PAIR "fcmaddc")]) + ++(define_int_attr int_comm ++ [(UNSPEC_COMPLEX_FMA "") ++ (UNSPEC_COMPLEX_FMA_PAIR "") ++ (UNSPEC_COMPLEX_FCMA "") ++ (UNSPEC_COMPLEX_FCMA_PAIR "") ++ (UNSPEC_COMPLEX_FMUL "%") ++ (UNSPEC_COMPLEX_FCMUL "")]) ++ + (define_int_attr conj_op + [(UNSPEC_COMPLEX_FMA "") + (UNSPEC_COMPLEX_FCMA "_conj") +@@ -6431,7 +6439,7 @@ + (define_insn "fma__" + [(set (match_operand:VF_AVX512FP16VL 0 "register_operand" "=&v") + (unspec:VF_AVX512FP16VL +- [(match_operand:VF_AVX512FP16VL 1 "" "%v") ++ [(match_operand:VF_AVX512FP16VL 1 "" "v") + (match_operand:VF_AVX512FP16VL 2 "" "") + (match_operand:VF_AVX512FP16VL 3 "" "0")] + UNSPEC_COMPLEX_F_C_MA))] +@@ -6495,7 +6503,7 @@ + (define_insn "fma___pair" + [(set (match_operand:VF1_AVX512VL 0 "register_operand" "=&v") + (unspec:VF1_AVX512VL +- [(match_operand:VF1_AVX512VL 1 "vector_operand" "%v") ++ [(match_operand:VF1_AVX512VL 1 "vector_operand" "v") + (match_operand:VF1_AVX512VL 2 "bcst_vector_operand" "vmBr") + (match_operand:VF1_AVX512VL 3 "vector_operand" "0")] + UNSPEC_COMPLEX_F_C_MA_PAIR))] +@@ -6562,7 +6570,7 @@ + [(set (match_operand:VF_AVX512FP16VL 0 "register_operand" "=&v") + (vec_merge:VF_AVX512FP16VL + (unspec:VF_AVX512FP16VL +- [(match_operand:VF_AVX512FP16VL 1 "nonimmediate_operand" "%v") ++ [(match_operand:VF_AVX512FP16VL 1 "nonimmediate_operand" "v") + (match_operand:VF_AVX512FP16VL 2 "nonimmediate_operand" "") + (match_operand:VF_AVX512FP16VL 3 "register_operand" "0")] + UNSPEC_COMPLEX_F_C_MA) +@@ -6586,7 +6594,7 @@ + (define_insn "__" + [(set (match_operand:VF_AVX512FP16VL 0 "register_operand" "=&v") + (unspec:VF_AVX512FP16VL +- [(match_operand:VF_AVX512FP16VL 1 "nonimmediate_operand" "%v") ++ [(match_operand:VF_AVX512FP16VL 1 "nonimmediate_operand" "v") + (match_operand:VF_AVX512FP16VL 2 "nonimmediate_operand" "")] + UNSPEC_COMPLEX_F_C_MUL))] + "TARGET_AVX512FP16 && " +diff --git a/gcc/testsuite/gcc.target/i386/pr111306.c b/gcc/testsuite/gcc.target/i386/pr111306.c +new file mode 100644 +index 000000000..541725ebd +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr111306.c +@@ -0,0 +1,36 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 -mavx512fp16 -mavx512vl" } */ ++/* { dg-require-effective-target avx512fp16 } */ ++ ++#define AVX512FP16 ++#include "avx512f-helper.h" ++ ++__attribute__((optimize("O2"),noipa)) ++void func1(_Float16 *a, _Float16 *b, int n, _Float16 *c) { ++ __m512h rA = _mm512_loadu_ph(a); ++ for (int i = 0; i < n; i += 32) { ++ __m512h rB = _mm512_loadu_ph(b + i); ++ _mm512_storeu_ph(c + i, _mm512_fcmul_pch(rB, rA)); ++ } ++} ++ ++void ++test_512 (void) ++{ ++ int n = 32; ++ _Float16 a[n], b[n], c[n]; ++ _Float16 exp[n]; ++ for (int i = 1; i <= n; i++) { ++ a[i - 1] = i & 1 ? -i : i; ++ b[i - 1] = i; ++ } ++ ++ func1(a, b, n, c); ++ for (int i = 0; i < n / 32; i += 2) { ++ if (c[i] != a[i] * b[i] + a[i+1] * b[i+1] ++ || c[i+1] != a[i] * b[i+1] - a[i+1]*b[i]) ++ __builtin_abort (); ++ } ++} ++ ++ +-- +2.31.1 + diff --git a/0266-Disparage-slightly-for-the-alternative-which-move-DF.patch b/0266-Disparage-slightly-for-the-alternative-which-move-DF.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e8bd6773bbf1b2f5a3344bd6b7bdc33a2486d97 --- /dev/null +++ b/0266-Disparage-slightly-for-the-alternative-which-move-DF.patch @@ -0,0 +1,106 @@ +From afd539adfe762adb57863299a11987b7e20e7987 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Wed, 5 Jul 2023 13:45:11 +0800 +Subject: [PATCH 12/28] Disparage slightly for the alternative which move + DFmode between SSE_REGS and GENERAL_REGS. + +For testcase + +void __cond_swap(double* __x, double* __y) { + bool __r = (*__x < *__y); + auto __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + +GCC-14 with -O2 and -march=x86-64 options generates the following code: + +__cond_swap(double*, double*): + movsd xmm1, QWORD PTR [rdi] + movsd xmm0, QWORD PTR [rsi] + comisd xmm0, xmm1 + jbe .L2 + movq rax, xmm1 + movapd xmm1, xmm0 + movq xmm0, rax +.L2: + movsd QWORD PTR [rsi], xmm1 + movsd QWORD PTR [rdi], xmm0 + ret + +rax is used to save and restore DFmode value. In RA both GENERAL_REGS +and SSE_REGS cost zero since we didn't disparage the +alternative in movdf_internal pattern, according to register +allocation order, GENERAL_REGS is allocated. The patch add ? for +alternative (r,v) and (v,r) just like we did for movsf/hf/bf_internal +pattern, after that we get optimal RA. + +__cond_swap: +.LFB0: + .cfi_startproc + movsd (%rdi), %xmm1 + movsd (%rsi), %xmm0 + comisd %xmm1, %xmm0 + jbe .L2 + movapd %xmm1, %xmm2 + movapd %xmm0, %xmm1 + movapd %xmm2, %xmm0 +.L2: + movsd %xmm1, (%rsi) + movsd %xmm0, (%rdi) + ret + +gcc/ChangeLog: + + PR target/110170 + * config/i386/i386.md (movdf_internal): Disparage slightly for + 2 alternatives (r,v) and (v,r) by adding constraint modifier + '?'. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/pr110170-3.c: New test. + +(cherry picked from commit 37a231cc7594d12ba0822077018aad751a6fb94e) +--- + gcc/config/i386/i386.md | 4 ++-- + gcc/testsuite/gcc.target/i386/pr110170-3.c | 11 +++++++++++ + 2 files changed, 13 insertions(+), 2 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/pr110170-3.c + +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index be07be10d..71691f598 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -3582,9 +3582,9 @@ + ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7. + (define_insn "*movdf_internal" + [(set (match_operand:DF 0 "nonimmediate_operand" +- "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m") ++ "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m") + (match_operand:DF 1 "general_operand" +- "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))] ++ "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x, v, r,roF,rF,rmF,rC"))] + "!(MEM_P (operands[0]) && MEM_P (operands[1])) + && (lra_in_progress || reload_completed + || !CONST_DOUBLE_P (operands[1]) +diff --git a/gcc/testsuite/gcc.target/i386/pr110170-3.c b/gcc/testsuite/gcc.target/i386/pr110170-3.c +new file mode 100644 +index 000000000..70daa89e9 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr110170-3.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-O2 -fno-if-conversion -fno-if-conversion2" } */ ++/* { dg-final { scan-assembler-not {(?n)movq.*r} } } */ ++ ++void __cond_swap(double* __x, double* __y) { ++ _Bool __r = (*__x < *__y); ++ double __tmp = __r ? *__x : *__y; ++ *__y = __r ? *__y : *__x; ++ *__x = __tmp; ++} ++ +-- +2.31.1 + diff --git a/0267-Fix-wrong-code-due-to-vec_merge-pcmp-to-blendvb-spli.patch b/0267-Fix-wrong-code-due-to-vec_merge-pcmp-to-blendvb-spli.patch new file mode 100644 index 0000000000000000000000000000000000000000..32ce46d7816d8b2f7ee8dd465fe9f59a369e847d --- /dev/null +++ b/0267-Fix-wrong-code-due-to-vec_merge-pcmp-to-blendvb-spli.patch @@ -0,0 +1,163 @@ +From 88516507757932c1e67ce99d240596935971d2d0 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Thu, 9 Nov 2023 13:20:05 +0800 +Subject: [PATCH 13/28] Fix wrong code due to vec_merge + pcmp to blendvb + splitter. + +gcc/ChangeLog: + + PR target/112443 + * config/i386/sse.md (*avx2_pcmp3_4): Fix swap condition + from LT to GT since there's not in the pattern. + (*avx2_pcmp3_5): Ditto. + +gcc/testsuite/ChangeLog: + + * g++.target/i386/pr112443.C: New test. + +(cherry picked from commit 9a0cc04b9c9b02426762892b88efc5c44ba546bd) +--- + gcc/config/i386/sse.md | 4 +- + gcc/testsuite/g++.target/i386/pr112443.C | 108 +++++++++++++++++++++++ + 2 files changed, 110 insertions(+), 2 deletions(-) + create mode 100644 gcc/testsuite/g++.target/i386/pr112443.C + +diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md +index f25dd5f2b..23b858ab2 100644 +--- a/gcc/config/i386/sse.md ++++ b/gcc/config/i386/sse.md +@@ -16358,7 +16358,7 @@ + (match_dup 4))] + UNSPEC_BLENDV))] + { +- if (INTVAL (operands[5]) == 1) ++ if (INTVAL (operands[5]) == 5) + std::swap (operands[1], operands[2]); + operands[3] = gen_lowpart (mode, operands[3]); + }) +@@ -16388,7 +16388,7 @@ + (match_dup 4))] + UNSPEC_BLENDV))] + { +- if (INTVAL (operands[5]) == 1) ++ if (INTVAL (operands[5]) == 5) + std::swap (operands[1], operands[2]); + }) + +diff --git a/gcc/testsuite/g++.target/i386/pr112443.C b/gcc/testsuite/g++.target/i386/pr112443.C +new file mode 100644 +index 000000000..ebfa9b4a7 +--- /dev/null ++++ b/gcc/testsuite/g++.target/i386/pr112443.C +@@ -0,0 +1,108 @@ ++/* { dg-do run } */ ++/* { dg-require-effective-target avx512bw } */ ++/* { dg-require-effective-target avx512vl } */ ++/* { dg-options "-O2 -std=c++17 -mavx512bw -mavx512vl" } */ ++ ++#include ++#include ++#include ++#include ++ ++#define AVX512BW ++#define AVX512VL ++ ++#include "avx512f-helper.h" ++ ++struct TensorIteratorBase{ ++ char* in; ++ char* out; ++ ++ void for_each(std::function loop){ ++ loop(out, in, 32); ++ } ++}; ++ ++class Vectorized { ++protected: ++ __m256i values; ++ ++ static inline __m256i invert(const __m256i& v) { ++ const auto ones = _mm256_set1_epi64x(-1); ++ return _mm256_xor_si256(ones, v); ++ } ++public: ++ operator __m256i() const { ++ return values; ++ } ++ ++ static constexpr int size() { ++ return 32; ++ } ++ ++ Vectorized() {} ++ Vectorized(__m256i v) : values(v) {} ++ Vectorized(uint8_t v) { values = _mm256_set1_epi8(v); } ++ static Vectorized blendv(const Vectorized& a, const Vectorized& b, ++ const Vectorized& mask) { ++ return _mm256_blendv_epi8(a, b, mask); ++ } ++ static Vectorized loadu(const void* ptr) { ++ return _mm256_loadu_si256(reinterpret_cast(ptr)); ++ } ++ void store(void* ptr) const { ++ _mm256_storeu_si256(reinterpret_cast<__m256i*>(ptr), values); ++ } ++ ++ Vectorized operator<(const Vectorized& other) const { ++ __m256i max = _mm256_max_epu8(values, other); ++ return invert(_mm256_cmpeq_epi8(max, values)); ++ } ++ Vectorized operator-(const Vectorized& b) { ++ return _mm256_sub_epi8(values, b); ++ } ++}; ++ ++std::ostream& operator<<(std::ostream& stream, const Vectorized& vec) { ++ uint8_t buf[Vectorized::size()]; ++ vec.store(buf); ++ stream << "vec["; ++ for (int i = 0; i != Vectorized::size(); i++) { ++ if (i != 0) ++ stream << ", "; ++ stream << buf[i]*1; ++ } ++ stream << "]"; ++ return stream; ++} ++ ++void run(TensorIteratorBase iter){ ++ Vectorized zero_vec(0); ++ Vectorized one_vec(1); ++ ++ iter.for_each([=](char* out, char* in, int64_t size) { ++ for (int64_t i = 0; i <= size - Vectorized::size(); i += Vectorized::size()) { ++ auto self_vec = Vectorized::loadu(in + i); ++ auto left = Vectorized::blendv(zero_vec, one_vec, zero_vec < self_vec); ++ auto right = Vectorized::blendv(zero_vec, one_vec, self_vec < zero_vec); ++ auto outv = left - right; ++ outv.store(out + i); ++ } ++ }); ++} ++ ++void ++test_256 (){ ++ char in[32]; ++ char out[32]; ++ for(auto& x: in) x = 1; ++ run(TensorIteratorBase{in, out}); ++ Vectorized::loadu (out); ++ for (int i = 0; i != 32; i++) ++ if (out[i] != 1) ++ __builtin_abort (); ++} ++ ++void ++test_128 () ++{ ++} +-- +2.31.1 + diff --git a/0268-Don-t-assume-it-s-AVX_U128_CLEAN-after-call_insn-who.patch b/0268-Don-t-assume-it-s-AVX_U128_CLEAN-after-call_insn-who.patch new file mode 100644 index 0000000000000000000000000000000000000000..3d2f9bb0d765b894e1d7f5a17fc964d2e914f9cc --- /dev/null +++ b/0268-Don-t-assume-it-s-AVX_U128_CLEAN-after-call_insn-who.patch @@ -0,0 +1,151 @@ +From 204ffa7f503411ccac0161c951726274648b6374 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Thu, 7 Dec 2023 09:17:27 +0800 +Subject: [PATCH 14/28] Don't assume it's AVX_U128_CLEAN after call_insn whose + abi.mode_clobber(V4DImode) deosn't contains all SSE_REGS. + +If the function desn't clobber any sse registers or only clobber +128-bit part, then vzeroupper isn't issued before the function exit. +the status not CLEAN but ANY after the function. + +Also for sibling_call, it's safe to issue an vzeroupper. Also there +could be missing vzeroupper since there's no mode_exit for +sibling_call_p. + +gcc/ChangeLog: + + PR target/112891 + * config/i386/i386.cc (ix86_avx_u128_mode_after): Return + AVX_U128_ANY if callee_abi doesn't clobber all_sse_regs to + align with ix86_avx_u128_mode_needed. + (ix86_avx_u128_mode_needed): Return AVX_U128_ClEAN for + sibling_call. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/pr112891.c: New test. + * gcc.target/i386/pr112891-2.c: New test. + +(cherry picked from commit fc189a08f5b7ad5889bd4c6b320c1dd99dd5d642) +--- + gcc/config/i386/i386.cc | 22 +++++++++++++--- + gcc/testsuite/gcc.target/i386/pr112891-2.c | 30 ++++++++++++++++++++++ + gcc/testsuite/gcc.target/i386/pr112891.c | 29 +++++++++++++++++++++ + 3 files changed, 78 insertions(+), 3 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/pr112891-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/pr112891.c + +diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc +index e75d37023..60f3296b0 100644 +--- a/gcc/config/i386/i386.cc ++++ b/gcc/config/i386/i386.cc +@@ -14416,8 +14416,12 @@ ix86_avx_u128_mode_needed (rtx_insn *insn) + modes wider than 256 bits. It's only safe to issue a + vzeroupper if all SSE registers are clobbered. */ + const function_abi &abi = insn_callee_abi (insn); +- if (!hard_reg_set_subset_p (reg_class_contents[SSE_REGS], +- abi.mode_clobbers (V4DImode))) ++ /* Should be safe to issue an vzeroupper before sibling_call_p. ++ Also there not mode_exit for sibling_call, so there could be ++ missing vzeroupper for that. */ ++ if (!(SIBLING_CALL_P (insn) ++ || hard_reg_set_subset_p (reg_class_contents[SSE_REGS], ++ abi.mode_clobbers (V4DImode)))) + return AVX_U128_ANY; + + return AVX_U128_CLEAN; +@@ -14555,7 +14559,19 @@ ix86_avx_u128_mode_after (int mode, rtx_insn *insn) + bool avx_upper_reg_found = false; + note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found); + +- return avx_upper_reg_found ? AVX_U128_DIRTY : AVX_U128_CLEAN; ++ if (avx_upper_reg_found) ++ return AVX_U128_DIRTY; ++ ++ /* If the function desn't clobber any sse registers or only clobber ++ 128-bit part, Then vzeroupper isn't issued before the function exit. ++ the status not CLEAN but ANY after the function. */ ++ const function_abi &abi = insn_callee_abi (insn); ++ if (!(SIBLING_CALL_P (insn) ++ || hard_reg_set_subset_p (reg_class_contents[SSE_REGS], ++ abi.mode_clobbers (V4DImode)))) ++ return AVX_U128_ANY; ++ ++ return AVX_U128_CLEAN; + } + + /* Otherwise, return current mode. Remember that if insn +diff --git a/gcc/testsuite/gcc.target/i386/pr112891-2.c b/gcc/testsuite/gcc.target/i386/pr112891-2.c +new file mode 100644 +index 000000000..164c3985d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr112891-2.c +@@ -0,0 +1,30 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mavx2 -O3" } */ ++/* { dg-final { scan-assembler-times "vzeroupper" 1 } } */ ++ ++void ++__attribute__((noinline)) ++bar (double* a) ++{ ++ a[0] = 1.0; ++ a[1] = 2.0; ++} ++ ++double ++__attribute__((noinline)) ++foo (double* __restrict a, double* b) ++{ ++ a[0] += b[0]; ++ a[1] += b[1]; ++ a[2] += b[2]; ++ a[3] += b[3]; ++ bar (b); ++ return a[5] + b[5]; ++} ++ ++double ++foo1 (double* __restrict a, double* b) ++{ ++ double c = foo (a, b); ++ return __builtin_exp (c); ++} +diff --git a/gcc/testsuite/gcc.target/i386/pr112891.c b/gcc/testsuite/gcc.target/i386/pr112891.c +new file mode 100644 +index 000000000..dbf6c6794 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/pr112891.c +@@ -0,0 +1,29 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mavx2 -O3" } */ ++/* { dg-final { scan-assembler-times "vzeroupper" 1 } } */ ++ ++void ++__attribute__((noinline)) ++bar (double* a) ++{ ++ a[0] = 1.0; ++ a[1] = 2.0; ++} ++ ++void ++__attribute__((noinline)) ++foo (double* __restrict a, double* b) ++{ ++ a[0] += b[0]; ++ a[1] += b[1]; ++ a[2] += b[2]; ++ a[3] += b[3]; ++ bar (b); ++} ++ ++double ++foo1 (double* __restrict a, double* b) ++{ ++ foo (a, b); ++ return __builtin_exp (b[1]); ++} +-- +2.31.1 + diff --git a/0269-Disable-FMADD-in-chains-for-Zen4-and-generic.patch b/0269-Disable-FMADD-in-chains-for-Zen4-and-generic.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0de50431d13f24788162d4d8c595ba5c4db5e92 --- /dev/null +++ b/0269-Disable-FMADD-in-chains-for-Zen4-and-generic.patch @@ -0,0 +1,142 @@ +From 19ee37b11702c86d7ed271e9e1d00e23cc4ab93c Mon Sep 17 00:00:00 2001 +From: Jan Hubicka +Date: Fri, 29 Dec 2023 23:51:03 +0100 +Subject: [PATCH 15/28] Disable FMADD in chains for Zen4 and generic + +this patch disables use of FMA in matrix multiplication loop for generic (for +x86-64-v3) and zen4. I tested this on zen4 and Xenon Gold Gold 6212U. + +For Intel this is neutral both on the matrix multiplication microbenchmark +(attached) and spec2k17 where the difference was within noise for Core. + +On core the micro-benchmark runs as follows: + +With FMA: + + 578,500,241 cycles:u # 3.645 GHz + ( +- 0.12% ) + 753,318,477 instructions:u # 1.30 insn per +cycle ( +- 0.00% ) + 125,417,701 branches:u # 790.227 M/sec + ( +- 0.00% ) + 0.159146 +- 0.000363 seconds time elapsed ( +- 0.23% ) + +No FMA: + + 577,573,960 cycles:u # 3.514 GHz + ( +- 0.15% ) + 878,318,479 instructions:u # 1.52 insn per +cycle ( +- 0.00% ) + 125,417,702 branches:u # 763.035 M/sec + ( +- 0.00% ) + 0.164734 +- 0.000321 seconds time elapsed ( +- 0.19% ) + +So the cycle count is unchanged and discrete multiply+add takes same time as +FMA. + +While on zen: + +With FMA: + 484875179 cycles:u # 3.599 GHz + ( +- 0.05% ) (82.11%) + 752031517 instructions:u # 1.55 insn per +cycle + 125106525 branches:u # 928.712 M/sec + ( +- 0.03% ) (85.09%) + 128356 branch-misses:u # 0.10% of all +branches ( +- 0.06% ) (83.58%) + +No FMA: + 375875209 cycles:u # 3.592 GHz + ( +- 0.08% ) (80.74%) + 875725341 instructions:u # 2.33 insn per +cycle + 124903825 branches:u # 1.194 G/sec + ( +- 0.04% ) (84.59%) + 0.105203 +- 0.000188 seconds time elapsed ( +- 0.18% ) + +The diffrerence is that Cores understand the fact that fmadd does not need +all three parameters to start computation, while Zen cores doesn't. + +Since this seems noticeable win on zen and not loss on Core it seems like good +default for generic. + +float a[SIZE][SIZE]; +float b[SIZE][SIZE]; +float c[SIZE][SIZE]; + +void init(void) +{ + int i, j, k; + for(i=0; i +Date: Fri, 16 Sep 2022 13:59:01 +0800 +Subject: [PATCH 16/28] Initial Raptorlake Support + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h: + (get_intel_cpu): Handle Raptorlake. + * common/config/i386/i386-common.cc: + (processor_alias_table): Add Raptorlake. + +(cherry picked from commit 470a0659b508d684148f362c4dc0eccf5a83a23e) +--- + gcc/common/config/i386/cpuinfo.h | 2 ++ + gcc/common/config/i386/i386-common.cc | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 316ad3cb3..13d0f4cd8 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -508,6 +508,8 @@ get_intel_cpu (struct __processor_model *cpu_model, + case 0x97: + case 0x9a: + /* Alder Lake. */ ++ case 0xb7: ++ /* Raptor Lake. */ + cpu = "alderlake"; + CHECK___builtin_cpu_is ("corei7"); + CHECK___builtin_cpu_is ("alderlake"); +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index f650e255f..c1d700f89 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -1939,6 +1939,8 @@ const pta processor_alias_table[] = + M_CPU_SUBTYPE (INTEL_COREI7_SAPPHIRERAPIDS), P_PROC_AVX512F}, + {"alderlake", PROCESSOR_ALDERLAKE, CPU_HASWELL, PTA_ALDERLAKE, + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, ++ {"raptorlake", PROCESSOR_ALDERLAKE, CPU_HASWELL, PTA_ALDERLAKE, ++ M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, + {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, + M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, + {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, +-- +2.31.1 + diff --git a/0271-Initial-Meteorlake-Support.patch b/0271-Initial-Meteorlake-Support.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2e825b4f0a7a1c95120ddb3a8b803a2dfbfe2f2 --- /dev/null +++ b/0271-Initial-Meteorlake-Support.patch @@ -0,0 +1,49 @@ +From 87cea29ede520f4a5af01dff7071ab1d23bd47b5 Mon Sep 17 00:00:00 2001 +From: "Hu, Lin1" +Date: Fri, 16 Sep 2022 11:25:13 +0800 +Subject: [PATCH 17/28] Initial Meteorlake Support + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h: + (get_intel_cpu): Handle Meteorlake. + * common/config/i386/i386-common.cc: + (processor_alias_table): Add Meteorlake. + +(cherry picked from commit fd206f0e95fb6f41b96eaaaab1dc0c30378e5e08) +--- + gcc/common/config/i386/cpuinfo.h | 4 ++++ + gcc/common/config/i386/i386-common.cc | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 13d0f4cd8..37af92d6b 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -510,6 +510,10 @@ get_intel_cpu (struct __processor_model *cpu_model, + /* Alder Lake. */ + case 0xb7: + /* Raptor Lake. */ ++ case 0xb5: ++ case 0xaa: ++ case 0xac: ++ /* Meteor Lake. */ + cpu = "alderlake"; + CHECK___builtin_cpu_is ("corei7"); + CHECK___builtin_cpu_is ("alderlake"); +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index c1d700f89..cfee672fb 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -1941,6 +1941,8 @@ const pta processor_alias_table[] = + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, + {"raptorlake", PROCESSOR_ALDERLAKE, CPU_HASWELL, PTA_ALDERLAKE, + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, ++ {"meteorlake", PROCESSOR_ALDERLAKE, CPU_HASWELL, PTA_ALDERLAKE, ++ M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, + {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, + M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, + {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, +-- +2.31.1 + diff --git a/0272-Support-Intel-AMX-FP16-ISA.patch b/0272-Support-Intel-AMX-FP16-ISA.patch new file mode 100644 index 0000000000000000000000000000000000000000..67eda4d955a252c35efc8e024351082d7c005584 --- /dev/null +++ b/0272-Support-Intel-AMX-FP16-ISA.patch @@ -0,0 +1,691 @@ +From c11301c7780213ddf46a0bcdb06079af485f431c Mon Sep 17 00:00:00 2001 +From: Hongyu Wang +Date: Fri, 4 Nov 2022 15:50:55 +0800 +Subject: [PATCH 18/28] Support Intel AMX-FP16 ISA + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h (get_available_features): Detect + amx-fp16. + * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_AMX_FP16_SET, + OPTION_MASK_ISA2_AMX_FP16_UNSET): New macros. + (ix86_handle_option): Handle -mamx-fp16. + * common/config/i386/i386-cpuinfo.h (enum processor_features): + Add FEATURE_AMX_FP16. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for + amx-fp16. + * config.gcc: Add amxfp16intrin.h. + * config/i386/cpuid.h (bit_AMX_FP16): New. + * config/i386/i386-c.cc (ix86_target_macros_internal): Define + __AMX_FP16__. + * config/i386/i386-isa.def: Add DEF_PTA for AMX_FP16. + * config/i386/i386-options.cc (isa2_opts): Add -mamx-fp16. + (ix86_valid_target_attribute_inner_p): Add new ATTR. + (ix86_option_override_internal): Handle AMX-FP16. + * config/i386/i386.opt: Add -mamx-fp16. + * config/i386/immintrin.h: Include amxfp16intrin.h. + * doc/extend.texi: Document -mamx-fp16. + * doc/invoke.texi: Document amx-fp16. + * doc/sourcebuild.texi: Document amx_fp16. + * config/i386/amxfp16intrin.h: New file. + +gcc/testsuite/ChangeLog: + + * g++.dg/other/i386-2.C: Add -mamx-fp16. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/sse-12.c: Ditto. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Ditto. + * gcc.target/i386/sse-23.c: Ditto. + * lib/target-supports.exp: (check_effective_target_amx_fp16): + New proc. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * gcc.target/i386/amx-check.h: Add AMX_FP16. + * gcc.target/i386/amx-helper.h: New file to support amx-fp16. + * gcc.target/i386/amxfp16-asmatt-1.c: New test. + * gcc.target/i386/amxfp16-asmintel-1.c: Ditto. + * gcc.target/i386/amxfp16-dpfp16ps-2.c: Ditto. + +Co-authored-by: Haochen Jiang + +(cherry picked from commit 2b4a03962a0fe18cadc944d90f1fb85a40004226) +--- + gcc/common/config/i386/cpuinfo.h | 5 ++ + gcc/common/config/i386/i386-common.cc | 15 +++++ + gcc/common/config/i386/i386-cpuinfo.h | 1 + + gcc/common/config/i386/i386-isas.h | 1 + + gcc/config.gcc | 3 +- + gcc/config/i386/amxfp16intrin.h | 46 ++++++++++++++ + gcc/config/i386/cpuid.h | 1 + + gcc/config/i386/i386-c.cc | 2 + + gcc/config/i386/i386-isa.def | 1 + + gcc/config/i386/i386-options.cc | 4 +- + gcc/config/i386/i386.opt | 4 ++ + gcc/config/i386/immintrin.h | 2 + + gcc/doc/extend.texi | 5 ++ + gcc/doc/invoke.texi | 9 ++- + gcc/doc/sourcebuild.texi | 3 + + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- + gcc/testsuite/g++.dg/other/i386-3.C | 2 +- + gcc/testsuite/gcc.target/i386/amx-check.h | 3 + + gcc/testsuite/gcc.target/i386/amx-helper.h | 61 +++++++++++++++++++ + .../gcc.target/i386/amxfp16-asmatt-1.c | 13 ++++ + .../gcc.target/i386/amxfp16-asmintel-1.c | 10 +++ + .../gcc.target/i386/amxfp16-dpfp16ps-2.c | 57 +++++++++++++++++ + gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + + gcc/testsuite/gcc.target/i386/sse-12.c | 2 +- + gcc/testsuite/gcc.target/i386/sse-13.c | 2 +- + gcc/testsuite/gcc.target/i386/sse-14.c | 2 +- + gcc/testsuite/gcc.target/i386/sse-22.c | 4 +- + gcc/testsuite/gcc.target/i386/sse-23.c | 2 +- + gcc/testsuite/lib/target-supports.exp | 11 ++++ + 29 files changed, 262 insertions(+), 13 deletions(-) + create mode 100644 gcc/config/i386/amxfp16intrin.h + create mode 100644 gcc/testsuite/gcc.target/i386/amx-helper.h + create mode 100644 gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 37af92d6b..5951a30aa 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -783,6 +783,11 @@ get_available_features (struct __processor_model *cpu_model, + set_feature (FEATURE_AVX512BF16); + } + } ++ if (amx_usable) ++ { ++ if (eax & bit_AMX_FP16) ++ set_feature (FEATURE_AMX_FP16); ++ } + } + + /* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */ +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index cfee672fb..922db33ee 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -107,6 +107,7 @@ along with GCC; see the file COPYING3. If not see + #define OPTION_MASK_ISA2_AMX_TILE_SET OPTION_MASK_ISA2_AMX_TILE + #define OPTION_MASK_ISA2_AMX_INT8_SET OPTION_MASK_ISA2_AMX_INT8 + #define OPTION_MASK_ISA2_AMX_BF16_SET OPTION_MASK_ISA2_AMX_BF16 ++#define OPTION_MASK_ISA2_AMX_FP16_SET OPTION_MASK_ISA2_AMX_FP16 + + /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same + as -msse4.2. */ +@@ -275,6 +276,7 @@ along with GCC; see the file COPYING3. If not see + #define OPTION_MASK_ISA2_KL_UNSET \ + (OPTION_MASK_ISA2_KL | OPTION_MASK_ISA2_WIDEKL_UNSET) + #define OPTION_MASK_ISA2_WIDEKL_UNSET OPTION_MASK_ISA2_WIDEKL ++#define OPTION_MASK_ISA2_AMX_FP16_UNSET OPTION_MASK_ISA2_AMX_FP16 + + /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same + as -mno-sse4.1. */ +@@ -1125,6 +1127,19 @@ ix86_handle_option (struct gcc_options *opts, + } + return true; + ++ case OPT_mamx_fp16: ++ if (value) ++ { ++ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AMX_FP16_SET; ++ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_FP16_SET; ++ } ++ else ++ { ++ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AMX_FP16_UNSET; ++ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_FP16_UNSET; ++ } ++ return true; ++ + case OPT_mfma: + if (value) + { +diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h +index 82996ebb3..8f22897de 100644 +--- a/gcc/common/config/i386/i386-cpuinfo.h ++++ b/gcc/common/config/i386/i386-cpuinfo.h +@@ -240,6 +240,7 @@ enum processor_features + FEATURE_X86_64_V2, + FEATURE_X86_64_V3, + FEATURE_X86_64_V4, ++ FEATURE_AMX_FP16, + CPU_FEATURE_MAX + }; + +diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h +index 2d0646a68..95bab6da2 100644 +--- a/gcc/common/config/i386/i386-isas.h ++++ b/gcc/common/config/i386/i386-isas.h +@@ -175,4 +175,5 @@ ISA_NAMES_TABLE_START + ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_X86_64_V2, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_X86_64_V3, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_X86_64_V4, NULL) ++ ISA_NAMES_TABLE_ENTRY("amx-fp16", FEATURE_AMX_FP16, P_NONE, "-mamx-fp16") + ISA_NAMES_TABLE_END +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 4a0ae9328..e2b4a23dc 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -423,7 +423,8 @@ i[34567]86-*-* | x86_64-*-*) + tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h + amxbf16intrin.h x86gprintrin.h uintrintrin.h + hresetintrin.h keylockerintrin.h avxvnniintrin.h +- mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h" ++ mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h ++ amxfp16intrin.h" + ;; + ia64-*-*) + extra_headers=ia64intrin.h +diff --git a/gcc/config/i386/amxfp16intrin.h b/gcc/config/i386/amxfp16intrin.h +new file mode 100644 +index 000000000..6a114741a +--- /dev/null ++++ b/gcc/config/i386/amxfp16intrin.h +@@ -0,0 +1,46 @@ ++/* Copyright (C) 2020 Free Software Foundation, Inc. ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ GCC is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++#if !defined _IMMINTRIN_H_INCLUDED ++#error "Never use directly; include instead." ++#endif ++ ++#ifndef _AMXFP16INTRIN_H_INCLUDED ++#define _AMXFP16INTRIN_H_INCLUDED ++ ++#if defined(__x86_64__) ++#define _tile_dpfp16ps_internal(dst,src1,src2) \ ++ __asm__ volatile \ ++ ("{tdpfp16ps\t%%tmm"#src2", %%tmm"#src1", %%tmm"#dst"|tdpfp16ps\t%%tmm"#dst", %%tmm"#src1", %%tmm"#src2"}" ::) ++ ++#define _tile_dpfp16ps(dst,src1,src2) \ ++ _tile_dpfp16ps_internal (dst,src1,src2) ++ ++#endif ++ ++#ifdef __DISABLE_AMX_FP16__ ++#undef __DISABLE_AMX_FP16__ ++#pragma GCC pop_options ++#endif /* __DISABLE_AMX_FP16__ */ ++ ++#endif /* _AMXFP16INTRIN_H_INCLUDED */ +diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h +index 8b3dc2b1d..d6cd8d1bf 100644 +--- a/gcc/config/i386/cpuid.h ++++ b/gcc/config/i386/cpuid.h +@@ -27,6 +27,7 @@ + /* %eax */ + #define bit_AVXVNNI (1 << 4) + #define bit_AVX512BF16 (1 << 5) ++#define bit_AMX_FP16 (1 << 21) + #define bit_HRESET (1 << 22) + + /* %ecx */ +diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc +index 3fec4c7e2..4269f29e6 100644 +--- a/gcc/config/i386/i386-c.cc ++++ b/gcc/config/i386/i386-c.cc +@@ -633,6 +633,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + def_or_undef (parse_in, "__WIDEKL__"); + if (isa_flag2 & OPTION_MASK_ISA2_AVXVNNI) + def_or_undef (parse_in, "__AVXVNNI__"); ++ if (isa_flag2 & OPTION_MASK_ISA2_AMX_FP16) ++ def_or_undef (parse_in, "__AMX_FP16__"); + if (TARGET_IAMCU) + { + def_or_undef (parse_in, "__iamcu"); +diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def +index 83659d0be..c7305c01b 100644 +--- a/gcc/config/i386/i386-isa.def ++++ b/gcc/config/i386/i386-isa.def +@@ -109,3 +109,4 @@ DEF_PTA(KL) + DEF_PTA(WIDEKL) + DEF_PTA(AVXVNNI) + DEF_PTA(AVX512FP16) ++DEF_PTA(AMX_FP16) +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 3df1f0c41..3edb7094e 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -230,7 +230,8 @@ static struct ix86_target_opts isa2_opts[] = + { "-mkl", OPTION_MASK_ISA2_KL }, + { "-mwidekl", OPTION_MASK_ISA2_WIDEKL }, + { "-mavxvnni", OPTION_MASK_ISA2_AVXVNNI }, +- { "-mavx512fp16", OPTION_MASK_ISA2_AVX512FP16 } ++ { "-mavx512fp16", OPTION_MASK_ISA2_AVX512FP16 }, ++ { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 } + }; + static struct ix86_target_opts isa_opts[] = + { +@@ -1074,6 +1075,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], + IX86_ATTR_ISA ("hreset", OPT_mhreset), + IX86_ATTR_ISA ("avxvnni", OPT_mavxvnni), + IX86_ATTR_ISA ("avx512fp16", OPT_mavx512fp16), ++ IX86_ATTR_ISA ("amx-fp16", OPT_mamx_fp16), + + /* enum options */ + IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index b154110d8..52c6f02ee 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1226,3 +1226,7 @@ Enable conservative small loop unrolling. + mscatter + Target Alias(mtune-ctrl=, use_scatter, ^use_scatter) + Enable vectorization for scatter instruction. ++ ++mamx-fp16 ++Target Mask(ISA2_AMX_FP16) Var(ix86_isa_flags2) Save ++Support AMX-FP16 built-in functions and code generation. +diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h +index 6afd78c2b..0447ca4b2 100644 +--- a/gcc/config/i386/immintrin.h ++++ b/gcc/config/i386/immintrin.h +@@ -128,4 +128,6 @@ + + #include + ++#include ++ + #endif /* _IMMINTRIN_H_INCLUDED */ +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 33a776a79..4ba9d34cd 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -7038,6 +7038,11 @@ Enable/disable the generation of the WIDEKL instructions. + @cindex @code{target("avxvnni")} function attribute, x86 + Enable/disable the generation of the AVXVNNI instructions. + ++@item amx-fp16 ++@itemx no-amx-fp16 ++@cindex @code{target("amx-fp16")} function attribute, x86 ++Enable/disable the generation of the AMX-FP16 instructions. ++ + @item cld + @itemx no-cld + @cindex @code{target("cld")} function attribute, x86 +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 3a48655e5..d25f13217 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1428,7 +1428,7 @@ See RS/6000 and PowerPC Options. + -mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol + -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol + -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni@gol +--mavx512fp16 @gol ++-mavx512fp16 -mamx-fp16 @gol + -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol + -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol + -mkl -mwidekl @gol +@@ -32442,6 +32442,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. + @need 200 + @itemx -mwidekl + @opindex mwidekl ++@need 200 ++@itemx -mamx-fp16 ++@opindex mamx-fp16 + These switches enable the use of instructions in the MMX, SSE, + SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF, + AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, +@@ -32451,8 +32454,8 @@ WBNOINVD, FMA4, PREFETCHW, RDPID, PREFETCHWT1, RDSEED, SGX, XOP, LWP, + XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2, + GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, + ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, +-UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16 +-or CLDEMOTE extended instruction sets. Each has a corresponding ++UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, ++AMX-FP16 or CLDEMOTE extended instruction sets. Each has a corresponding + @option{-mno-} option to disable use of these instructions. + + These extensions are also available as built-in functions: see +diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi +index 71c04841d..b64b62dee 100644 +--- a/gcc/doc/sourcebuild.texi ++++ b/gcc/doc/sourcebuild.texi +@@ -2472,6 +2472,9 @@ Target supports the execution of @code{amx-int8} instructions. + @item amx_bf16 + Target supports the execution of @code{amx-bf16} instructions. + ++@item amx_fp16 ++Target supports the execution of @code{amx-fp16} instructions. ++ + @item cell_hw + Test system can execute AltiVec and Cell PPU instructions. + +diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C +index fba3d1ac6..57a6357aa 100644 +--- a/gcc/testsuite/g++.dg/other/i386-2.C ++++ b/gcc/testsuite/g++.dg/other/i386-2.C +@@ -1,5 +1,5 @@ + /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +-/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16" } */ ++/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ + + /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, + xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, +diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C +index 5cc0fa834..1947547d6 100644 +--- a/gcc/testsuite/g++.dg/other/i386-3.C ++++ b/gcc/testsuite/g++.dg/other/i386-3.C +@@ -1,5 +1,5 @@ + /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +-/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16" } */ ++/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ + + /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, + xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, +diff --git a/gcc/testsuite/gcc.target/i386/amx-check.h b/gcc/testsuite/gcc.target/i386/amx-check.h +index 6fff5ff46..27dd37bf9 100644 +--- a/gcc/testsuite/gcc.target/i386/amx-check.h ++++ b/gcc/testsuite/gcc.target/i386/amx-check.h +@@ -213,6 +213,9 @@ main () + #ifdef AMX_BF16 + && __builtin_cpu_supports ("amx-bf16") + #endif ++#ifdef AMX_FP16 ++ && __builtin_cpu_supports ("amx-fp16") ++#endif + #ifdef __linux__ + && request_perm_xtile_data () + #endif +diff --git a/gcc/testsuite/gcc.target/i386/amx-helper.h b/gcc/testsuite/gcc.target/i386/amx-helper.h +new file mode 100644 +index 000000000..fe24d7067 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amx-helper.h +@@ -0,0 +1,61 @@ ++#ifndef AMX_HELPER_H_INCLUDED ++#define AMX_HELPER_H_INCLUDED ++#if defined(AMX_FP16) ++#include ++#include ++#endif ++#include "amx-check.h" ++ ++typedef union ++{ ++ _Float16 f16; ++ uint16_t u; ++} union16f_uw; ++ ++#if defined(AMX_FP16) ++/* Transformation functions between fp16/float */ ++static uint16_t make_f32_fp16 (float f) ++{ ++ union16f_uw tmp; ++ __m128 b = _mm_set_ss (f); ++ __m128h a; ++ tmp.f16 = _mm_cvtsh_h (_mm_cvtss_sh (a, b)); ++ return tmp.u; ++} ++ ++static float make_fp16_f32 (uint16_t fp) ++{ ++ union16f_uw tmp; ++ tmp.u = fp; ++ __m128h b = _mm_set_sh (tmp.f16); ++ __m128 a; ++ return _mm_cvtss_f32 (_mm_cvtsh_ss (a, b)); ++} ++ ++/* Init tile buffer with fp16 pairs */ ++void init_fp16_max_tile_buffer (uint8_t* buf) ++{ ++ int i, j; ++ uint16_t* ptr = (uint16_t *) buf; ++ ++ for (i = 0; i < 16; i++) ++ for (j = 0; j < 32; j++) ++ { ++ float f = 2.5f * i + 1.25f * j; ++ ptr[i * 32 + j] = make_f32_fp16 (f); ++ } ++} ++ ++/* Init tile fp16 pair buffer with zero */ ++void init_fp16_max_tile_zero_buffer (uint8_t* buf) ++{ ++ int i, j; ++ uint16_t* ptr = (uint16_t *) buf; ++ ++ for (i = 0; i < 16; i++) ++ for (j = 0; j < 32; j++) ++ ptr[i * 32 + j] = make_f32_fp16 (0.0f); ++} ++#endif ++ ++#endif +diff --git a/gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c b/gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c +new file mode 100644 +index 000000000..09ae6d408 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxfp16-asmatt-1.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-O2 -mamx-fp16" } */ ++/* { dg-final { scan-assembler "tdpfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */ ++#include ++ ++#define TMM1 1 ++#define TMM2 2 ++#define TMM3 3 ++ ++void TEST () ++{ ++ _tile_dpfp16ps (TMM1, TMM2, TMM3); ++} +diff --git a/gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c b/gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c +new file mode 100644 +index 000000000..a8dff945f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxfp16-asmintel-1.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-require-effective-target masm_intel } */ ++/* { dg-options "-O2 -mamx-fp16 -masm=intel" } */ ++/* { dg-final { scan-assembler "tdpfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */ ++#include ++ ++void TEST () ++{ ++ _tile_dpfp16ps (1, 2, 3); ++} +diff --git a/gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c b/gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c +new file mode 100644 +index 000000000..2d359a689 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxfp16-dpfp16ps-2.c +@@ -0,0 +1,57 @@ ++/* { dg-do run { target { ! ia32 } } } */ ++/* { dg-require-effective-target amx_tile } */ ++/* { dg-require-effective-target amx_fp16 } */ ++/* { dg-require-effective-target avx512fp16 } */ ++/* { dg-options "-O2 -mamx-tile -mamx-fp16 -mavx512fp16" } */ ++#define AMX_FP16 ++#define DO_TEST test_amx_fp16_dpfp16ps ++void test_amx_fp16_dpfp16ps (); ++#include "amx-helper.h" ++ ++void calc_matrix_dpfp16ps (__tile *dst, __tile *src1, __tile *src2) ++{ ++ uint16_t *src1_buf = (uint16_t *)src1->buf; ++ uint16_t *src2_buf = (uint16_t *)src2->buf; ++ float *dst_buf = (float *)dst->buf; ++ ++ int M = src1->rows; ++ int N = src1->colsb / 4; ++ int K = src2->colsb / 4; ++ int i, j, k, t; ++ ++ for (i = 0; i < M; i++) ++ for (j = 0; j < N; j++) ++ for (k = 0; k < K; k++) ++ for (t = 0; t < 2; t+=2) ++ { ++ dst_buf[i * K + k] += ++ (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t]) * ++ make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t])) + ++ (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t + 1]) * ++ make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t + 1])); ++ } ++ ++} ++ ++void test_amx_fp16_dpfp16ps () ++{ ++ __tilecfg_u cfg; ++ __tile dst, dst_ref, src1, src2; ++ uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024]; ++ ++ init_fp16_max_tile_buffer (tmp_dst_buf); ++ init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf); ++ ++ init_tile_config (&cfg); ++ init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf); ++ init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf); ++ init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf); ++ ++ calc_matrix_dpfp16ps (&dst, &src1, &src2); ++ ++ _tile_dpfp16ps (1, 2, 3); ++ _tile_stored (1, dst_ref.buf, _STRIDE); ++ ++ if (!check_float_tile_register (&dst_ref, &dst)) ++ abort (); ++} +diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +index f34e7a977..b00cfff03 100644 +--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc ++++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +@@ -80,6 +80,7 @@ extern void test_keylocker (void) __attribute__((__target__("kl"))); + extern void test_widekl (void) __attribute__((__target__("widekl"))); + extern void test_avxvnni (void) __attribute__((__target__("avxvnni"))); + extern void test_avx512fp16 (void) __attribute__((__target__("avx512fp16"))); ++extern void test_amx_fp16 (void) __attribute__((__target__("amx-fp16"))); + + extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); + extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); +@@ -161,6 +162,7 @@ extern void test_no_keylocker (void) __attribute__((__target__("no-kl"))); + extern void test_no_widekl (void) __attribute__((__target__("no-widekl"))); + extern void test_no_avxvnni (void) __attribute__((__target__("no-avxvnni"))); + extern void test_no_avx512fp16 (void) __attribute__((__target__("no-avx512fp16"))); ++extern void test_no_amx_fp16 (void) __attribute__((__target__("no-amx-fp16"))); + + extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); + extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); +diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c +index 375d4d1b4..9ab4a7e0c 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-12.c ++++ b/gcc/testsuite/gcc.target/i386/sse-12.c +@@ -3,7 +3,7 @@ + popcntintrin.h gfniintrin.h and mm_malloc.h are usable + with -O -std=c89 -pedantic-errors. */ + /* { dg-do compile } */ +-/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni" } */ ++/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mamx-fp16" } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c +index e285c307d..a1e453a98 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-13.c ++++ b/gcc/testsuite/gcc.target/i386/sse-13.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16" } */ ++/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ + /* { dg-add-options bind_pic_locally } */ + + #include +diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c +index f41493b93..eaa1a8d81 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-14.c ++++ b/gcc/testsuite/gcc.target/i386/sse-14.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16" } */ ++/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ + /* { dg-add-options bind_pic_locally } */ + + #include +diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c +index 31492ef36..19afe639d 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-22.c ++++ b/gcc/testsuite/gcc.target/i386/sse-22.c +@@ -103,7 +103,7 @@ + + + #ifndef DIFFERENT_PRAGMAS +-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16") ++#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16") + #endif + + /* Following intrinsics require immediate arguments. They +@@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1) + + /* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */ + #ifdef DIFFERENT_PRAGMAS +-#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16") ++#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16") + #endif + #include + test_1 (_cvtss_sh, unsigned short, float, 1) +diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c +index b398fd144..151201d97 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-23.c ++++ b/gcc/testsuite/gcc.target/i386/sse-23.c +@@ -843,6 +843,6 @@ + #define __builtin_ia32_vpclmulqdq_v2di(A, B, C) __builtin_ia32_vpclmulqdq_v2di(A, B, 1) + #define __builtin_ia32_vpclmulqdq_v8di(A, B, C) __builtin_ia32_vpclmulqdq_v8di(A, B, 1) + +-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16") ++#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16") + + #include +diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp +index c858bd93b..0d83c780c 100644 +--- a/gcc/testsuite/lib/target-supports.exp ++++ b/gcc/testsuite/lib/target-supports.exp +@@ -9972,6 +9972,17 @@ proc check_effective_target_amx_bf16 { } { + } "-mamx-bf16" ] + } + ++# Return 1 if amx-fp16 instructions can be compiled. ++proc check_effective_target_amx_fp16 { } { ++ return [check_no_compiler_messages amx_fp16 object { ++ void ++ foo () ++ { ++ __asm__ volatile ("tdpfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::); ++ } ++ } "-mamx-fp16" ] ++} ++ + # Return 1 if vpclmulqdq instructions can be compiled. + proc check_effective_target_vpclmulqdq { } { + return [check_no_compiler_messages vpclmulqdq object { +-- +2.31.1 + diff --git a/0273-Support-Intel-prefetchit0-t1.patch b/0273-Support-Intel-prefetchit0-t1.patch new file mode 100644 index 0000000000000000000000000000000000000000..a6c777f5159518432f6dae2f5ec52f9173865edc --- /dev/null +++ b/0273-Support-Intel-prefetchit0-t1.patch @@ -0,0 +1,902 @@ +From 42a38c8abaa28f67e26b9af3f434fe0107894e7d Mon Sep 17 00:00:00 2001 +From: Haochen Jiang +Date: Fri, 4 Nov 2022 15:01:05 +0800 +Subject: [PATCH 19/28] Support Intel prefetchit0/t1 + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h (get_available_features): + Detect PREFETCHI. + * common/config/i386/i386-common.cc + (OPTION_MASK_ISA2_PREFETCHI_SET, + OPTION_MASK_ISA2_PREFETCHI_UNSET): New. + (ix86_handle_option): Handle -mprefetchi. + * common/config/i386/i386-cpuinfo.h + (enum processor_features): Add FEATURE_PREFETCHI. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY + for prefetchi. + * config.gcc: Add prfchiintrin.h. + * config/i386/cpuid.h (bit_PREFETCHI): New. + * config/i386/i386-builtin-types.def: + Add DEF_FUNCTION_TYPE (VOID, PCVOID, INT) + and DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT). + * config/i386/i386-builtin.def (BDESC): Add new builtins. + * config/i386/i386-c.cc (ix86_target_macros_internal): + Define __PREFETCHI__. + * config/i386/i386-expand.cc: Handle new builtins. + * config/i386/i386-isa.def (PREFETCHI): + Add DEF_PTA(PREFETCHI). + * config/i386/i386-options.cc + (ix86_valid_target_attribute_inner_p): Handle prefetchi. + * config/i386/i386.md (prefetchi): New define_insn. + * config/i386/i386.opt: Add option -mprefetchi. + * config/i386/predicates.md (local_func_symbolic_operand): + New predicates. + * config/i386/x86gprintrin.h: Include prfchiintrin.h. + * config/i386/xmmintrin.h (enum _mm_hint): New enum for + prefetchi. + (_mm_prefetch): Handle the highest bit of enum. + * doc/extend.texi: Document prefetchi. + * doc/invoke.texi: Document -mprefetchi. + * doc/sourcebuild.texi: Document target prefetchi. + * config/i386/prfchiintrin.h: New file. + +gcc/testsuite/ChangeLog: + + * g++.dg/other/i386-2.C: Add -mprefetchi. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/avx-1.c: Ditto. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * gcc.target/i386/sse-13.c: Add -mprefetchi. + * gcc.target/i386/sse-23.c: Ditto. + * gcc.target/i386/x86gprintrin-1.c: Ditto. + * gcc.target/i386/x86gprintrin-2.c: Ditto. + * gcc.target/i386/x86gprintrin-3.c: Ditto. + * gcc.target/i386/x86gprintrin-4.c: Ditto. + * gcc.target/i386/x86gprintrin-5.c: Ditto. + * gcc.target/i386/prefetchi-1.c: New test. + * gcc.target/i386/prefetchi-2.c: Ditto. + * gcc.target/i386/prefetchi-3.c: Ditto. + * gcc.target/i386/prefetchi-4.c: Ditto. + +Co-authored-by: Hongtao Liu +--- + gcc/common/config/i386/cpuinfo.h | 2 + + gcc/common/config/i386/i386-common.cc | 15 ++++ + gcc/common/config/i386/i386-cpuinfo.h | 1 + + gcc/common/config/i386/i386-isas.h | 1 + + gcc/config.gcc | 2 +- + gcc/config/i386/cpuid.h | 1 + + gcc/config/i386/i386-builtin-types.def | 4 + + gcc/config/i386/i386-builtin.def | 4 + + gcc/config/i386/i386-c.cc | 2 + + gcc/config/i386/i386-expand.cc | 77 +++++++++++++++++++ + gcc/config/i386/i386-isa.def | 1 + + gcc/config/i386/i386-options.cc | 4 +- + gcc/config/i386/i386.md | 23 ++++++ + gcc/config/i386/i386.opt | 4 + + gcc/config/i386/predicates.md | 15 ++++ + gcc/config/i386/prfchiintrin.h | 49 ++++++++++++ + gcc/config/i386/x86gprintrin.h | 2 + + gcc/config/i386/xmmintrin.h | 7 +- + gcc/doc/extend.texi | 5 ++ + gcc/doc/invoke.texi | 7 +- + gcc/doc/sourcebuild.texi | 3 + + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- + gcc/testsuite/g++.dg/other/i386-3.C | 2 +- + gcc/testsuite/gcc.target/i386/avx-1.c | 4 +- + gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + + gcc/testsuite/gcc.target/i386/prefetchi-1.c | 40 ++++++++++ + gcc/testsuite/gcc.target/i386/prefetchi-2.c | 26 +++++++ + gcc/testsuite/gcc.target/i386/prefetchi-3.c | 20 +++++ + gcc/testsuite/gcc.target/i386/prefetchi-4.c | 19 +++++ + gcc/testsuite/gcc.target/i386/sse-13.c | 4 +- + gcc/testsuite/gcc.target/i386/sse-23.c | 4 +- + .../gcc.target/i386/x86gprintrin-1.c | 2 +- + .../gcc.target/i386/x86gprintrin-2.c | 2 +- + .../gcc.target/i386/x86gprintrin-3.c | 2 +- + .../gcc.target/i386/x86gprintrin-4.c | 2 +- + .../gcc.target/i386/x86gprintrin-5.c | 2 +- + 36 files changed, 343 insertions(+), 19 deletions(-) + create mode 100644 gcc/config/i386/prfchiintrin.h + create mode 100644 gcc/testsuite/gcc.target/i386/prefetchi-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/prefetchi-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/prefetchi-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/prefetchi-4.c + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 5951a30aa..f17e88144 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -772,6 +772,8 @@ get_available_features (struct __processor_model *cpu_model, + __cpuid_count (7, 1, eax, ebx, ecx, edx); + if (eax & bit_HRESET) + set_feature (FEATURE_HRESET); ++ if (edx & bit_PREFETCHI) ++ set_feature (FEATURE_PREFETCHI); + if (avx_usable) + { + if (eax & bit_AVXVNNI) +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index 922db33ee..c8cf532cf 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -108,6 +108,7 @@ along with GCC; see the file COPYING3. If not see + #define OPTION_MASK_ISA2_AMX_INT8_SET OPTION_MASK_ISA2_AMX_INT8 + #define OPTION_MASK_ISA2_AMX_BF16_SET OPTION_MASK_ISA2_AMX_BF16 + #define OPTION_MASK_ISA2_AMX_FP16_SET OPTION_MASK_ISA2_AMX_FP16 ++#define OPTION_MASK_ISA2_PREFETCHI_SET OPTION_MASK_ISA2_PREFETCHI + + /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same + as -msse4.2. */ +@@ -277,6 +278,7 @@ along with GCC; see the file COPYING3. If not see + (OPTION_MASK_ISA2_KL | OPTION_MASK_ISA2_WIDEKL_UNSET) + #define OPTION_MASK_ISA2_WIDEKL_UNSET OPTION_MASK_ISA2_WIDEKL + #define OPTION_MASK_ISA2_AMX_FP16_UNSET OPTION_MASK_ISA2_AMX_FP16 ++#define OPTION_MASK_ISA2_PREFETCHI_UNSET OPTION_MASK_ISA2_PREFETCHI + + /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same + as -mno-sse4.1. */ +@@ -1140,6 +1142,19 @@ ix86_handle_option (struct gcc_options *opts, + } + return true; + ++ case OPT_mprefetchi: ++ if (value) ++ { ++ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_PREFETCHI_SET; ++ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_PREFETCHI_SET; ++ } ++ else ++ { ++ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_PREFETCHI_UNSET; ++ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_PREFETCHI_UNSET; ++ } ++ return true; ++ + case OPT_mfma: + if (value) + { +diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h +index 8f22897de..95b078acf 100644 +--- a/gcc/common/config/i386/i386-cpuinfo.h ++++ b/gcc/common/config/i386/i386-cpuinfo.h +@@ -241,6 +241,7 @@ enum processor_features + FEATURE_X86_64_V3, + FEATURE_X86_64_V4, + FEATURE_AMX_FP16, ++ FEATURE_PREFETCHI, + CPU_FEATURE_MAX + }; + +diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h +index 95bab6da2..6caf06249 100644 +--- a/gcc/common/config/i386/i386-isas.h ++++ b/gcc/common/config/i386/i386-isas.h +@@ -176,4 +176,5 @@ ISA_NAMES_TABLE_START + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_X86_64_V3, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_X86_64_V4, NULL) + ISA_NAMES_TABLE_ENTRY("amx-fp16", FEATURE_AMX_FP16, P_NONE, "-mamx-fp16") ++ ISA_NAMES_TABLE_ENTRY("prefetchi", FEATURE_PREFETCHI, P_NONE, "-mprefetchi") + ISA_NAMES_TABLE_END +diff --git a/gcc/config.gcc b/gcc/config.gcc +index e2b4a23dc..81012c651 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -424,7 +424,7 @@ i[34567]86-*-* | x86_64-*-*) + amxbf16intrin.h x86gprintrin.h uintrintrin.h + hresetintrin.h keylockerintrin.h avxvnniintrin.h + mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h +- amxfp16intrin.h" ++ amxfp16intrin.h prfchiintrin.h" + ;; + ia64-*-*) + extra_headers=ia64intrin.h +diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h +index d6cd8d1bf..21100149a 100644 +--- a/gcc/config/i386/cpuid.h ++++ b/gcc/config/i386/cpuid.h +@@ -50,6 +50,7 @@ + + /* %edx */ + #define bit_CMPXCHG8B (1 << 8) ++#define bit_PREFETCHI (1 << 14) + #define bit_CMOV (1 << 15) + #define bit_MMX (1 << 23) + #define bit_FXSAVE (1 << 24) +diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def +index e33f06ab3..ff3b0af84 100644 +--- a/gcc/config/i386/i386-builtin-types.def ++++ b/gcc/config/i386/i386-builtin-types.def +@@ -1387,3 +1387,7 @@ DEF_FUNCTION_TYPE (V32HF, V32HF) + DEF_FUNCTION_TYPE_ALIAS (V8HF_FTYPE_V8HF, ROUND) + DEF_FUNCTION_TYPE_ALIAS (V16HF_FTYPE_V16HF, ROUND) + DEF_FUNCTION_TYPE_ALIAS (V32HF_FTYPE_V32HF, ROUND) ++ ++# PREFETCHI builtins ++DEF_FUNCTION_TYPE (VOID, PCVOID, INT) ++DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT) +diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def +index 2b1d6c733..d3ab21eea 100644 +--- a/gcc/config/i386/i386-builtin.def ++++ b/gcc/config/i386/i386-builtin.def +@@ -469,6 +469,10 @@ BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesdecwide2 + BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesencwide128kl_u8", IX86_BUILTIN_AESENCWIDE128KLU8, UNKNOWN, (int) UINT8_FTYPE_PV2DI_PCV2DI_PCVOID) + BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesencwide256kl_u8", IX86_BUILTIN_AESENCWIDE256KLU8, UNKNOWN, (int) UINT8_FTYPE_PV2DI_PCV2DI_PCVOID) + ++/* PREFETCHI */ ++BDESC (0, 0, CODE_FOR_prefetchi, "__builtin_ia32_prefetchi", IX86_BUILTIN_PREFETCHI, UNKNOWN, (int) VOID_FTYPE_PCVOID_INT) ++BDESC (0, 0, CODE_FOR_nothing, "__builtin_ia32_prefetch", IX86_BUILTIN_PREFETCH, UNKNOWN, (int) VOID_FTYPE_PCVOID_INT_INT_INT) ++ + BDESC_END (SPECIAL_ARGS, PURE_ARGS) + + /* AVX */ +diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc +index 4269f29e6..00880bd17 100644 +--- a/gcc/config/i386/i386-c.cc ++++ b/gcc/config/i386/i386-c.cc +@@ -635,6 +635,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + def_or_undef (parse_in, "__AVXVNNI__"); + if (isa_flag2 & OPTION_MASK_ISA2_AMX_FP16) + def_or_undef (parse_in, "__AMX_FP16__"); ++ if (isa_flag2 & OPTION_MASK_ISA2_PREFETCHI) ++ def_or_undef (parse_in, "__PREFETCHI__"); + if (TARGET_IAMCU) + { + def_or_undef (parse_in, "__iamcu"); +diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc +index 77dda5dd4..bc2e61980 100644 +--- a/gcc/config/i386/i386-expand.cc ++++ b/gcc/config/i386/i386-expand.cc +@@ -12850,6 +12850,83 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, + return target; + } + ++ case IX86_BUILTIN_PREFETCH: ++ { ++ arg0 = CALL_EXPR_ARG (exp, 0); // const void * ++ arg1 = CALL_EXPR_ARG (exp, 1); // const int ++ arg2 = CALL_EXPR_ARG (exp, 2); // const int ++ arg3 = CALL_EXPR_ARG (exp, 3); // const int ++ ++ op0 = expand_normal (arg0); ++ op1 = expand_normal (arg1); ++ op2 = expand_normal (arg2); ++ op3 = expand_normal (arg3); ++ ++ if (!CONST_INT_P (op1) || !CONST_INT_P (op2) || !CONST_INT_P (op3)) ++ { ++ error ("second, third and fourth argument must be a const"); ++ return const0_rtx; ++ } ++ ++ if (INTVAL (op3) == 1) ++ { ++ if (TARGET_64BIT ++ && local_func_symbolic_operand (op0, GET_MODE (op0))) ++ emit_insn (gen_prefetchi (op0, op2)); ++ else ++ { ++ warning (0, "instruction prefetch applies when in 64-bit mode" ++ " with RIP-relative addressing and" ++ " option %<-mprefetchi%>;" ++ " they stay NOPs otherwise"); ++ emit_insn (gen_nop ()); ++ } ++ } ++ else ++ { ++ if (!address_operand (op0, VOIDmode)) ++ { ++ op0 = convert_memory_address (Pmode, op0); ++ op0 = copy_addr_to_reg (op0); ++ } ++ emit_insn (gen_prefetch (op0, op1, op2)); ++ } ++ ++ return 0; ++ } ++ ++ case IX86_BUILTIN_PREFETCHI: ++ { ++ arg0 = CALL_EXPR_ARG (exp, 0); // const void * ++ arg1 = CALL_EXPR_ARG (exp, 1); // const int ++ ++ op0 = expand_normal (arg0); ++ op1 = expand_normal (arg1); ++ ++ if (!CONST_INT_P (op1)) ++ { ++ error ("second argument must be a const"); ++ return const0_rtx; ++ } ++ ++ /* GOT/PLT_PIC should not be available for instruction prefetch. ++ It must be real instruction address. */ ++ if (TARGET_64BIT ++ && local_func_symbolic_operand (op0, GET_MODE (op0))) ++ emit_insn (gen_prefetchi (op0, op1)); ++ else ++ { ++ /* Ignore the hint. */ ++ warning (0, "instruction prefetch applies when in 64-bit mode" ++ " with RIP-relative addressing and" ++ " option %<-mprefetchi%>;" ++ " they stay NOPs otherwise"); ++ emit_insn (gen_nop ()); ++ } ++ ++ return 0; ++ } ++ + case IX86_BUILTIN_VEC_INIT_V2SI: + case IX86_BUILTIN_VEC_INIT_V4HI: + case IX86_BUILTIN_VEC_INIT_V8QI: +diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def +index c7305c01b..744a7df85 100644 +--- a/gcc/config/i386/i386-isa.def ++++ b/gcc/config/i386/i386-isa.def +@@ -110,3 +110,4 @@ DEF_PTA(WIDEKL) + DEF_PTA(AVXVNNI) + DEF_PTA(AVX512FP16) + DEF_PTA(AMX_FP16) ++DEF_PTA(PREFETCHI) +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 3edb7094e..724375f02 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -231,7 +231,8 @@ static struct ix86_target_opts isa2_opts[] = + { "-mwidekl", OPTION_MASK_ISA2_WIDEKL }, + { "-mavxvnni", OPTION_MASK_ISA2_AVXVNNI }, + { "-mavx512fp16", OPTION_MASK_ISA2_AVX512FP16 }, +- { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 } ++ { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 }, ++ { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI } + }; + static struct ix86_target_opts isa_opts[] = + { +@@ -1076,6 +1077,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], + IX86_ATTR_ISA ("avxvnni", OPT_mavxvnni), + IX86_ATTR_ISA ("avx512fp16", OPT_mavx512fp16), + IX86_ATTR_ISA ("amx-fp16", OPT_mamx_fp16), ++ IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi), + + /* enum options */ + IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index 71691f598..f08c2cfb1 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -329,6 +329,9 @@ + + ;; For HRESET support + UNSPECV_HRESET ++ ++ ;; For PREFETCHI support ++ UNSPECV_PREFETCHI + ]) + + ;; Constants to represent rounding modes in the ROUND instruction +@@ -22907,6 +22910,26 @@ + (symbol_ref "memory_address_length (operands[0], false)")) + (set_attr "memory" "none")]) + ++(define_insn "prefetchi" ++ [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p") ++ (match_operand:SI 1 "const_int_operand")] ++ UNSPECV_PREFETCHI)] ++ "TARGET_PREFETCHI && TARGET_64BIT" ++{ ++ static const char * const patterns[2] = { ++ "prefetchit1\t%0", "prefetchit0\t%0" ++ }; ++ ++ int locality = INTVAL (operands[1]); ++ gcc_assert (IN_RANGE (locality, 2, 3)); ++ ++ return patterns[locality - 2]; ++} ++ [(set_attr "type" "sse") ++ (set (attr "length_address") ++ (symbol_ref "memory_address_length (operands[0], false)")) ++ (set_attr "memory" "none")]) ++ + (define_expand "stack_protect_set" + [(match_operand 0 "memory_operand") + (match_operand 1 "memory_operand")] +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 52c6f02ee..50cd114f6 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1230,3 +1230,7 @@ Enable vectorization for scatter instruction. + mamx-fp16 + Target Mask(ISA2_AMX_FP16) Var(ix86_isa_flags2) Save + Support AMX-FP16 built-in functions and code generation. ++ ++mprefetchi ++Target Mask(ISA2_PREFETCHI) Var(ix86_isa_flags2) Save ++Support PREFETCHI built-in functions and code generation. +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md +index ac02c61ac..774178b78 100644 +--- a/gcc/config/i386/predicates.md ++++ b/gcc/config/i386/predicates.md +@@ -610,6 +610,21 @@ + return false; + }) + ++(define_predicate "local_func_symbolic_operand" ++ (match_operand 0 "local_symbolic_operand") ++{ ++ if (GET_CODE (op) == CONST ++ && GET_CODE (XEXP (op, 0)) == PLUS ++ && CONST_INT_P (XEXP (XEXP (op, 0), 1))) ++ op = XEXP (XEXP (op, 0), 0); ++ ++ if (GET_CODE (op) == SYMBOL_REF ++ && !SYMBOL_REF_FUNCTION_P (op)) ++ return false; ++ ++ return true; ++}) ++ + ;; Test for a legitimate @GOTOFF operand. + ;; + ;; VxWorks does not impose a fixed gap between segments; the run-time +diff --git a/gcc/config/i386/prfchiintrin.h b/gcc/config/i386/prfchiintrin.h +new file mode 100644 +index 000000000..06deef488 +--- /dev/null ++++ b/gcc/config/i386/prfchiintrin.h +@@ -0,0 +1,49 @@ ++/* Copyright (C) 2022 Free Software Foundation, Inc. ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ GCC is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++#if !defined _X86GPRINTRIN_H_INCLUDED ++# error "Never use directly; include instead." ++#endif ++ ++#ifndef _PRFCHIINTRIN_H_INCLUDED ++#define _PRFCHIINTRIN_H_INCLUDED ++ ++#ifdef __x86_64__ ++ ++extern __inline void ++__attribute__((__gnu_inline__, __always_inline__, __artificial__)) ++_m_prefetchit0 (void* __P) ++{ ++ __builtin_ia32_prefetchi (__P, 3); ++} ++ ++extern __inline void ++__attribute__((__gnu_inline__, __always_inline__, __artificial__)) ++_m_prefetchit1 (void* __P) ++{ ++ __builtin_ia32_prefetchi (__P, 2); ++} ++ ++#endif ++ ++#endif /* _PRFCHIINTRIN_H_INCLUDED */ +diff --git a/gcc/config/i386/x86gprintrin.h b/gcc/config/i386/x86gprintrin.h +index e0be01d5e..0768aa0d7 100644 +--- a/gcc/config/i386/x86gprintrin.h ++++ b/gcc/config/i386/x86gprintrin.h +@@ -72,6 +72,8 @@ + + #include + ++#include ++ + #include + + #include +diff --git a/gcc/config/i386/xmmintrin.h b/gcc/config/i386/xmmintrin.h +index f1c704a2d..7fb179430 100644 +--- a/gcc/config/i386/xmmintrin.h ++++ b/gcc/config/i386/xmmintrin.h +@@ -36,6 +36,8 @@ + /* Constants for use with _mm_prefetch. */ + enum _mm_hint + { ++ _MM_HINT_IT0 = 19, ++ _MM_HINT_IT1 = 18, + /* _MM_HINT_ET is _MM_HINT_T with set 3rd bit. */ + _MM_HINT_ET0 = 7, + _MM_HINT_ET1 = 6, +@@ -51,11 +53,12 @@ enum _mm_hint + extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + _mm_prefetch (const void *__P, enum _mm_hint __I) + { +- __builtin_prefetch (__P, (__I & 0x4) >> 2, __I & 0x3); ++ __builtin_ia32_prefetch (__P, (__I & 0x4) >> 2, ++ __I & 0x3, (__I & 0x10) >> 4); + } + #else + #define _mm_prefetch(P, I) \ +- __builtin_prefetch ((P), ((I & 0x4) >> 2), (I & 0x3)) ++ __builtin_ia32_prefetch ((P), ((I) & 0x4) >> 2, ((I) & 0x3), ((I) & 0x10) >> 4) + #endif + + #ifndef __SSE__ +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 4ba9d34cd..cb987f469 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -7043,6 +7043,11 @@ Enable/disable the generation of the AVXVNNI instructions. + @cindex @code{target("amx-fp16")} function attribute, x86 + Enable/disable the generation of the AMX-FP16 instructions. + ++@item prefetchi ++@itemx no-prefetchi ++@cindex @code{target("prefetchi")} function attribute, x86 ++Enable/disable the generation of the PREFETCHI instructions. ++ + @item cld + @itemx no-cld + @cindex @code{target("cld")} function attribute, x86 +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index d25f13217..211b970c0 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1428,7 +1428,7 @@ See RS/6000 and PowerPC Options. + -mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol + -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol + -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni@gol +--mavx512fp16 -mamx-fp16 @gol ++-mavx512fp16 -mamx-fp16 -mprefetchi @gol + -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol + -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol + -mkl -mwidekl @gol +@@ -32445,6 +32445,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. + @need 200 + @itemx -mamx-fp16 + @opindex mamx-fp16 ++@need 200 ++@itemx -mprefetchi ++@opindex mprefetchi + These switches enable the use of instructions in the MMX, SSE, + SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF, + AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, +@@ -32455,7 +32458,7 @@ XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2, + GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, + ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, + UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, +-AMX-FP16 or CLDEMOTE extended instruction sets. Each has a corresponding ++AMX-FP16, PREFETCHI or CLDEMOTE extended instruction sets. Each has a corresponding + @option{-mno-} option to disable use of these instructions. + + These extensions are also available as built-in functions: see +diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi +index b64b62dee..c68e492dc 100644 +--- a/gcc/doc/sourcebuild.texi ++++ b/gcc/doc/sourcebuild.texi +@@ -2496,6 +2496,9 @@ Target does not require strict alignment. + @item pie_copyreloc + The x86-64 target linker supports PIE with copy reloc. + ++@item prefetchi ++Target supports the execution of @code{prefetchi} instructions. ++ + @item rdrand + Target supports x86 @code{rdrand} instruction. + +diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C +index 57a6357aa..72ed5fed0 100644 +--- a/gcc/testsuite/g++.dg/other/i386-2.C ++++ b/gcc/testsuite/g++.dg/other/i386-2.C +@@ -1,5 +1,5 @@ + /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +-/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ ++/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi" } */ + + /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, + xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, +diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C +index 1947547d6..9dd53653f 100644 +--- a/gcc/testsuite/g++.dg/other/i386-3.C ++++ b/gcc/testsuite/g++.dg/other/i386-3.C +@@ -1,5 +1,5 @@ + /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +-/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ ++/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi" } */ + + /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, + xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, +diff --git a/gcc/testsuite/gcc.target/i386/avx-1.c b/gcc/testsuite/gcc.target/i386/avx-1.c +index 154e7b3b1..2b46e1b87 100644 +--- a/gcc/testsuite/gcc.target/i386/avx-1.c ++++ b/gcc/testsuite/gcc.target/i386/avx-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -m3dnow -mavx -mavx2 -maes -mpclmul -mgfni -mavx512bw -mavx512fp16 -mavx512vl" } */ ++/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -m3dnow -mavx -mavx2 -maes -mpclmul -mgfni -mavx512bw -mavx512fp16 -mavx512vl -mprefetchi" } */ + /* { dg-add-options bind_pic_locally } */ + + #include +@@ -153,7 +153,7 @@ + #define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0) + + /* xmmintrin.h */ +-#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, 0, _MM_HINT_NTA) ++#define __builtin_ia32_prefetch(A, B, C, D) __builtin_ia32_prefetch(A, 0, 3, 0) + #define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0) + #define __builtin_ia32_vec_set_v4hi(A, D, N) \ + __builtin_ia32_vec_set_v4hi(A, D, 0) +diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +index b00cfff03..9f073f78c 100644 +--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc ++++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +@@ -81,6 +81,7 @@ extern void test_widekl (void) __attribute__((__target__("widekl"))); + extern void test_avxvnni (void) __attribute__((__target__("avxvnni"))); + extern void test_avx512fp16 (void) __attribute__((__target__("avx512fp16"))); + extern void test_amx_fp16 (void) __attribute__((__target__("amx-fp16"))); ++extern void test_prefetchi (void) __attribute__((__target__("prefetchi"))); + + extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); + extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); +@@ -163,6 +164,7 @@ extern void test_no_widekl (void) __attribute__((__target__("no-widekl"))); + extern void test_no_avxvnni (void) __attribute__((__target__("no-avxvnni"))); + extern void test_no_avx512fp16 (void) __attribute__((__target__("no-avx512fp16"))); + extern void test_no_amx_fp16 (void) __attribute__((__target__("no-amx-fp16"))); ++extern void test_no_prefetchi (void) __attribute__((__target__("no-prefetchi"))); + + extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); + extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); +diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-1.c b/gcc/testsuite/gcc.target/i386/prefetchi-1.c +new file mode 100644 +index 000000000..80f25e70e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/prefetchi-1.c +@@ -0,0 +1,40 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-mprefetchi -O2" } */ ++/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+" 2 } } */ ++/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+" 2 } } */ ++ ++#include ++ ++int ++bar (int a) ++{ ++ return a + 1; ++} ++ ++int ++foo1 (int b) ++{ ++ _mm_prefetch (bar, _MM_HINT_IT0); ++ return bar (b) + 1; ++} ++ ++int ++foo2 (int b) ++{ ++ _mm_prefetch (bar, _MM_HINT_IT1); ++ return bar (b) + 1; ++} ++ ++int ++foo3 (int b) ++{ ++ _m_prefetchit0 (bar); ++ return bar (b) + 1; ++} ++ ++int ++foo4 (int b) ++{ ++ _m_prefetchit1 (bar); ++ return bar (b) + 1; ++} +diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-2.c b/gcc/testsuite/gcc.target/i386/prefetchi-2.c +new file mode 100644 +index 000000000..e05ce9c73 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/prefetchi-2.c +@@ -0,0 +1,26 @@ ++/* { dg-do compile { target { ia32 } } } */ ++/* { dg-options "-mprefetchi -O2" } */ ++/* { dg-final { scan-assembler-not "\[ \\t\]+prefetchit0" } } */ ++/* { dg-final { scan-assembler-not "\[ \\t\]+prefetchit1" } } */ ++ ++#include ++ ++int ++bar (int a) ++{ ++ return a + 1; ++} ++ ++int ++foo1 (int b) ++{ ++ __builtin_ia32_prefetch (bar, 0, 3, 1); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ ++ return bar (b) + 1; ++} ++ ++int ++foo2 (int b) ++{ ++ __builtin_ia32_prefetchi (bar, 2); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ ++ return bar (b) + 1; ++} +diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-3.c b/gcc/testsuite/gcc.target/i386/prefetchi-3.c +new file mode 100644 +index 000000000..f0a4173d2 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/prefetchi-3.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mprefetchi -O2" } */ ++/* { dg-final { scan-assembler-not "prefetchit0" } } */ ++/* { dg-final { scan-assembler-not "prefetchit1" } } */ ++ ++#include ++ ++void* p; ++ ++void extern ++prefetchi_test1 (void) ++{ ++ __builtin_ia32_prefetchi (p, 2); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ ++} ++ ++void extern ++prefetchi_test2 (void) ++{ ++ __builtin_ia32_prefetch (p, 0, 3, 1); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-4.c b/gcc/testsuite/gcc.target/i386/prefetchi-4.c +new file mode 100644 +index 000000000..73ae596d1 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/prefetchi-4.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O0" } */ ++ ++#include ++ ++void* p; ++ ++void extern ++prefetch_test (void) ++{ ++ __builtin_ia32_prefetch (p, 0, 3, 0); ++ __builtin_ia32_prefetch (p, 0, 2, 0); ++ __builtin_ia32_prefetch (p, 0, 1, 0); ++ __builtin_ia32_prefetch (p, 0, 0, 0); ++ __builtin_ia32_prefetch (p, 1, 3, 0); ++ __builtin_ia32_prefetch (p, 1, 2, 0); ++ __builtin_ia32_prefetch (p, 1, 1, 0); ++ __builtin_ia32_prefetch (p, 1, 0, 0); ++} +diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c +index a1e453a98..db7c0fc7a 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-13.c ++++ b/gcc/testsuite/gcc.target/i386/sse-13.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ ++/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi" } */ + /* { dg-add-options bind_pic_locally } */ + + #include +@@ -125,7 +125,7 @@ + #define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0) + + /* xmmintrin.h */ +-#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, 0, _MM_HINT_NTA) ++#define __builtin_ia32_prefetch(A, B, C, D) __builtin_ia32_prefetch(A, 0, 3, 0) + #define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0) + #define __builtin_ia32_vec_set_v4hi(A, D, N) \ + __builtin_ia32_vec_set_v4hi(A, D, 0) +diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c +index 151201d97..741694e87 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-23.c ++++ b/gcc/testsuite/gcc.target/i386/sse-23.c +@@ -94,7 +94,7 @@ + #define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0) + + /* xmmintrin.h */ +-#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, 0, _MM_HINT_NTA) ++#define __builtin_ia32_prefetch(A, B, C, D) __builtin_ia32_prefetch(A, 0, 3, 0) + #define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0) + #define __builtin_ia32_vec_set_v4hi(A, D, N) \ + __builtin_ia32_vec_set_v4hi(A, D, 0) +@@ -843,6 +843,6 @@ + #define __builtin_ia32_vpclmulqdq_v2di(A, B, C) __builtin_ia32_vpclmulqdq_v2di(A, B, 1) + #define __builtin_ia32_vpclmulqdq_v8di(A, B, C) __builtin_ia32_vpclmulqdq_v8di(A, B, 1) + +-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16") ++#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16,prefetchi") + + #include +diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c +index 293be094b..efe7df13b 100644 +--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c ++++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c +@@ -1,7 +1,7 @@ + /* Test that is usable with -O -std=c89 -pedantic-errors. */ + /* { dg-do compile } */ + /* { dg-options "-O -std=c89 -pedantic-errors -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */ +-/* { dg-additional-options "-muintr" { target { ! ia32 } } } */ ++/* { dg-additional-options "-muintr -mprefetchi" { target { ! ia32 } } } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c +index c63302757..5f6970df6 100644 +--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c ++++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c +@@ -1,7 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */ + /* { dg-add-options bind_pic_locally } */ +-/* { dg-additional-options "-muintr" { target { ! ia32 } } } */ ++/* { dg-additional-options "-muintr -mprefetchi" { target { ! ia32 } } } */ + + /* Test that the intrinsics in compile with optimization. + All of them are defined as inline functions that reference the proper +diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c +index 3a7e1f4a1..5c075c375 100644 +--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c ++++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c +@@ -1,7 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O0 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */ + /* { dg-add-options bind_pic_locally } */ +-/* { dg-additional-options "-muintr" { target { ! ia32 } } } */ ++/* { dg-additional-options "-muintr -mprefetchi" { target { ! ia32 } } } */ + + /* Test that the intrinsics in compile without optimization. + All of them are defined as inline functions that reference the proper +diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c +index d8a6126e5..bda4ecea3 100644 +--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c ++++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c +@@ -15,7 +15,7 @@ + + #ifndef DIFFERENT_PRAGMAS + #ifdef __x86_64__ +-#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt") ++#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,prefetchi,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt") + #else + #pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,xsaveopt") + #endif +diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c +index 9ef66fdad..4aadfd0b3 100644 +--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c ++++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c +@@ -28,7 +28,7 @@ + #define __builtin_ia32_xabort(M) __builtin_ia32_xabort(1) + + #ifdef __x86_64__ +-#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd") ++#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,prefetchi,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd") + #else + #pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,xsavec,xsaveopt,xsaves,wbnoinvd") + #endif +-- +2.31.1 + diff --git a/0274-Initial-Granite-Rapids-Support.patch b/0274-Initial-Granite-Rapids-Support.patch new file mode 100644 index 0000000000000000000000000000000000000000..db7832924816e555145426fb16d700b4fd47629e --- /dev/null +++ b/0274-Initial-Granite-Rapids-Support.patch @@ -0,0 +1,277 @@ +From 7f0f8b585cf60b4c09bca42b5339995c2cc74633 Mon Sep 17 00:00:00 2001 +From: Haochen Jiang +Date: Mon, 7 Nov 2022 11:04:57 +0800 +Subject: [PATCH 20/28] Initial Granite Rapids Support + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h + (get_intel_cpu): Handle Granite Rapids. + * common/config/i386/i386-common.cc: + (processor_names): Add graniterapids. + (processor_alias_table): Ditto. + * common/config/i386/i386-cpuinfo.h + (enum processor_subtypes): Add INTEL_GRANTIERAPIDS. + * config.gcc: Add -march=graniterapids. + * config/i386/driver-i386.cc (host_detect_local_cpu): + Handle graniterapids. + * config/i386/i386-c.cc (ix86_target_macros_internal): + Ditto. + * config/i386/i386-options.cc (m_GRANITERAPIDS): New. + (processor_cost_table): Add graniterapids. + * config/i386/i386.h (enum processor_type): + Add PROCESSOR_GRANITERAPIDS. + (PTA_GRANITERAPIDS): Ditto. + * doc/extend.texi: Add graniterapids. + * doc/invoke.texi: Ditto. + +gcc/testsuite/ChangeLog: + + * g++.target/i386/mv16.C: Add graniterapids. + * gcc.target/i386/funcspec-56.inc: Handle new march. + +(cherry picked from commit 339ffc5a792dd66647392a235f2f7f6344c5359e) +--- + gcc/common/config/i386/cpuinfo.h | 9 +++++++++ + gcc/common/config/i386/i386-common.cc | 3 +++ + gcc/common/config/i386/i386-cpuinfo.h | 1 + + gcc/config.gcc | 2 +- + gcc/config/i386/driver-i386.cc | 5 ++++- + gcc/config/i386/i386-c.cc | 7 +++++++ + gcc/config/i386/i386-options.cc | 4 +++- + gcc/config/i386/i386.h | 3 +++ + gcc/doc/extend.texi | 3 +++ + gcc/doc/invoke.texi | 11 +++++++++++ + gcc/testsuite/g++.target/i386/mv16.C | 6 ++++++ + gcc/testsuite/gcc.target/i386/funcspec-56.inc | 1 + + 12 files changed, 52 insertions(+), 3 deletions(-) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index f17e88144..1f75ff1ca 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -528,6 +528,15 @@ get_intel_cpu (struct __processor_model *cpu_model, + cpu_model->__cpu_type = INTEL_COREI7; + cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS; + break; ++ case 0xad: ++ case 0xae: ++ /* Granite Rapids. */ ++ cpu = "graniterapids"; ++ CHECK___builtin_cpu_is ("corei7"); ++ CHECK___builtin_cpu_is ("graniterapids"); ++ cpu_model->__cpu_type = INTEL_COREI7; ++ cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS; ++ break; + case 0x17: + case 0x1d: + /* Penryn. */ +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index c8cf532cf..1aa163463 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -1855,6 +1855,7 @@ const char *const processor_names[] = + "sapphirerapids", + "alderlake", + "rocketlake", ++ "graniterapids", + "intel", + "geode", + "k6", +@@ -1973,6 +1974,8 @@ const pta processor_alias_table[] = + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, + {"meteorlake", PROCESSOR_ALDERLAKE, CPU_HASWELL, PTA_ALDERLAKE, + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, ++ {"graniterapids", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS, ++ M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS), P_PROC_AVX512F}, + {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, + M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, + {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, +diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h +index 95b078acf..7b2d4d242 100644 +--- a/gcc/common/config/i386/i386-cpuinfo.h ++++ b/gcc/common/config/i386/i386-cpuinfo.h +@@ -92,6 +92,7 @@ enum processor_subtypes + AMDFAM19H_ZNVER3, + INTEL_COREI7_ROCKETLAKE, + AMDFAM19H_ZNVER4, ++ INTEL_COREI7_GRANITERAPIDS, + CPU_SUBTYPE_MAX + }; + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 81012c651..9bad238e3 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -670,7 +670,7 @@ slm nehalem westmere sandybridge ivybridge haswell broadwell bonnell \ + silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \ + skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \ + sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \ +-nano-x2 eden-x4 nano-x4 x86-64 x86-64-v2 x86-64-v3 x86-64-v4 native" ++nano-x2 eden-x4 nano-x4 x86-64 x86-64-v2 x86-64-v3 x86-64-v4 graniterapids native" + + # Additional x86 processors supported by --with-cpu=. Each processor + # MUST be separated by exactly one space. +diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc +index 3b5161aed..ea8c3d8d1 100644 +--- a/gcc/config/i386/driver-i386.cc ++++ b/gcc/config/i386/driver-i386.cc +@@ -576,8 +576,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) + /* This is unknown family 0x6 CPU. */ + if (has_feature (FEATURE_AVX)) + { ++ /* Assume Granite Rapids. */ ++ if (has_feature (FEATURE_AMX_FP16)) ++ cpu = "graniterapids"; + /* Assume Tiger Lake */ +- if (has_feature (FEATURE_AVX512VP2INTERSECT)) ++ else if (has_feature (FEATURE_AVX512VP2INTERSECT)) + cpu = "tigerlake"; + /* Assume Sapphire Rapids. */ + else if (has_feature (FEATURE_TSXLDTRK)) +diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc +index 00880bd17..04f1dd682 100644 +--- a/gcc/config/i386/i386-c.cc ++++ b/gcc/config/i386/i386-c.cc +@@ -242,6 +242,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + def_or_undef (parse_in, "__sapphirerapids"); + def_or_undef (parse_in, "__sapphirerapids__"); + break; ++ case PROCESSOR_GRANITERAPIDS: ++ def_or_undef (parse_in, "__graniterapids"); ++ def_or_undef (parse_in, "__graniterapids__"); ++ break; + case PROCESSOR_ALDERLAKE: + def_or_undef (parse_in, "__alderlake"); + def_or_undef (parse_in, "__alderlake__"); +@@ -419,6 +423,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + case PROCESSOR_ROCKETLAKE: + def_or_undef (parse_in, "__tune_rocketlake__"); + break; ++ case PROCESSOR_GRANITERAPIDS: ++ def_or_undef (parse_in, "__tune_graniterapids__"); ++ break; + case PROCESSOR_INTEL: + case PROCESSOR_GENERIC: + break; +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 724375f02..6645e3259 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -127,10 +127,11 @@ along with GCC; see the file COPYING3. If not see + #define m_SAPPHIRERAPIDS (HOST_WIDE_INT_1U< +Date: Wed, 31 May 2023 10:45:00 +0800 +Subject: [PATCH 21/28] Support Intel AMX-COMPLEX + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h (get_available_features): + Detect AMX-COMPLEX. + * common/config/i386/i386-common.cc + (OPTION_MASK_ISA2_AMX_COMPLEX_SET, + OPTION_MASK_ISA2_AMX_COMPLEX_UNSET): New. + (ix86_handle_option): Handle -mamx-complex. + * common/config/i386/i386-cpuinfo.h (enum processor_features): + Add FEATURE_AMX_COMPLEX. + * common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for + amx-complex. + * config.gcc: Add amxcomplexintrin.h. + * config/i386/cpuid.h (bit_AMX_COMPLEX): New. + * config/i386/i386-c.cc (ix86_target_macros_internal): Define + __AMX_COMPLEX__. + * config/i386/i386-isa.def (AMX_COMPLEX): Add DEF_PTA(AMX_COMPLEX). + * config/i386/i386-options.cc (ix86_valid_target_attribute_inner_p): + Handle amx-complex. + * config/i386/i386.opt: Add option -mamx-complex. + * config/i386/immintrin.h: Include amxcomplexintrin.h. + * doc/extend.texi: Document amx-complex. + * doc/invoke.texi: Document -mamx-complex. + * doc/sourcebuild.texi: Document target amx-complex. + * config/i386/amxcomplexintrin.h: New file. + +gcc/testsuite/ChangeLog: + + * g++.dg/other/i386-2.C: Add -mamx-complex. + * g++.dg/other/i386-3.C: Ditto. + * gcc.target/i386/amx-check.h: Add cpu check for AMX-COMPLEX. + * gcc.target/i386/amx-helper.h: Add amx-complex support. + * gcc.target/i386/funcspec-56.inc: Add new target attribute. + * gcc.target/i386/sse-12.c: Add -mamx-complex. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Add amx-complex. + * gcc.target/i386/sse-23.c: Ditto. + * lib/target-supports.exp (check_effective_target_amx_complex): New. + * gcc.target/i386/amxcomplex-asmatt-1.c: New test. + * gcc.target/i386/amxcomplex-asmintel-1.c: Ditto. + * gcc.target/i386/amxcomplex-cmmimfp16ps-2.c: Ditto. + * gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c: Ditto. +--- + gcc/common/config/i386/cpuinfo.h | 2 + + gcc/common/config/i386/i386-common.cc | 19 +++++- + gcc/common/config/i386/i386-cpuinfo.h | 1 + + gcc/common/config/i386/i386-isas.h | 2 + + gcc/config.gcc | 2 +- + gcc/config/i386/amxcomplexintrin.h | 59 +++++++++++++++++++ + gcc/config/i386/cpuid.h | 1 + + gcc/config/i386/i386-c.cc | 2 + + gcc/config/i386/i386-isa.def | 1 + + gcc/config/i386/i386-options.cc | 4 +- + gcc/config/i386/i386.opt | 4 ++ + gcc/config/i386/immintrin.h | 2 + + gcc/doc/extend.texi | 5 ++ + gcc/doc/invoke.texi | 7 ++- + gcc/doc/sourcebuild.texi | 3 + + gcc/testsuite/g++.dg/other/i386-2.C | 2 +- + gcc/testsuite/g++.dg/other/i386-3.C | 2 +- + gcc/testsuite/gcc.target/i386/amx-check.h | 3 + + gcc/testsuite/gcc.target/i386/amx-helper.h | 4 +- + .../gcc.target/i386/amxcomplex-asmatt-1.c | 15 +++++ + .../gcc.target/i386/amxcomplex-asmintel-1.c | 12 ++++ + .../i386/amxcomplex-cmmimfp16ps-2.c | 53 +++++++++++++++++ + .../i386/amxcomplex-cmmrlfp16ps-2.c | 53 +++++++++++++++++ + gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + + gcc/testsuite/gcc.target/i386/sse-12.c | 2 +- + gcc/testsuite/gcc.target/i386/sse-13.c | 2 +- + gcc/testsuite/gcc.target/i386/sse-14.c | 2 +- + gcc/testsuite/gcc.target/i386/sse-22.c | 4 +- + gcc/testsuite/gcc.target/i386/sse-23.c | 2 +- + gcc/testsuite/lib/target-supports.exp | 11 ++++ + 30 files changed, 268 insertions(+), 15 deletions(-) + create mode 100644 gcc/config/i386/amxcomplexintrin.h + create mode 100644 gcc/testsuite/gcc.target/i386/amxcomplex-asmatt-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/amxcomplex-asmintel-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 1f75ff1ca..39d3351db 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -798,6 +798,8 @@ get_available_features (struct __processor_model *cpu_model, + { + if (eax & bit_AMX_FP16) + set_feature (FEATURE_AMX_FP16); ++ if (edx & bit_AMX_COMPLEX) ++ set_feature (FEATURE_AMX_COMPLEX); + } + } + +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index 1aa163463..87e8afe9b 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -109,6 +109,8 @@ along with GCC; see the file COPYING3. If not see + #define OPTION_MASK_ISA2_AMX_BF16_SET OPTION_MASK_ISA2_AMX_BF16 + #define OPTION_MASK_ISA2_AMX_FP16_SET OPTION_MASK_ISA2_AMX_FP16 + #define OPTION_MASK_ISA2_PREFETCHI_SET OPTION_MASK_ISA2_PREFETCHI ++#define OPTION_MASK_ISA2_AMX_COMPLEX_SET \ ++ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_COMPLEX) + + /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same + as -msse4.2. */ +@@ -269,7 +271,8 @@ along with GCC; see the file COPYING3. If not see + #define OPTION_MASK_ISA2_SERIALIZE_UNSET OPTION_MASK_ISA2_SERIALIZE + #define OPTION_MASK_ISA2_AVX512VP2INTERSECT_UNSET OPTION_MASK_ISA2_AVX512VP2INTERSECT + #define OPTION_MASK_ISA2_TSXLDTRK_UNSET OPTION_MASK_ISA2_TSXLDTRK +-#define OPTION_MASK_ISA2_AMX_TILE_UNSET OPTION_MASK_ISA2_AMX_TILE ++#define OPTION_MASK_ISA2_AMX_TILE_UNSET \ ++ (OPTION_MASK_ISA2_AMX_TILE | OPTION_MASK_ISA2_AMX_COMPLEX_UNSET) + #define OPTION_MASK_ISA2_AMX_INT8_UNSET OPTION_MASK_ISA2_AMX_INT8 + #define OPTION_MASK_ISA2_AMX_BF16_UNSET OPTION_MASK_ISA2_AMX_BF16 + #define OPTION_MASK_ISA2_UINTR_UNSET OPTION_MASK_ISA2_UINTR +@@ -279,6 +282,7 @@ along with GCC; see the file COPYING3. If not see + #define OPTION_MASK_ISA2_WIDEKL_UNSET OPTION_MASK_ISA2_WIDEKL + #define OPTION_MASK_ISA2_AMX_FP16_UNSET OPTION_MASK_ISA2_AMX_FP16 + #define OPTION_MASK_ISA2_PREFETCHI_UNSET OPTION_MASK_ISA2_PREFETCHI ++#define OPTION_MASK_ISA2_AMX_COMPLEX_UNSET OPTION_MASK_ISA2_AMX_COMPLEX + + /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same + as -mno-sse4.1. */ +@@ -1155,6 +1159,19 @@ ix86_handle_option (struct gcc_options *opts, + } + return true; + ++ case OPT_mamx_complex: ++ if (value) ++ { ++ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AMX_COMPLEX_SET; ++ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_COMPLEX_SET; ++ } ++ else ++ { ++ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AMX_COMPLEX_UNSET; ++ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AMX_COMPLEX_UNSET; ++ } ++ return true; ++ + case OPT_mfma: + if (value) + { +diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h +index 7b2d4d242..56020faac 100644 +--- a/gcc/common/config/i386/i386-cpuinfo.h ++++ b/gcc/common/config/i386/i386-cpuinfo.h +@@ -243,6 +243,7 @@ enum processor_features + FEATURE_X86_64_V4, + FEATURE_AMX_FP16, + FEATURE_PREFETCHI, ++ FEATURE_AMX_COMPLEX, + CPU_FEATURE_MAX + }; + +diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h +index 6caf06249..cbef68479 100644 +--- a/gcc/common/config/i386/i386-isas.h ++++ b/gcc/common/config/i386/i386-isas.h +@@ -177,4 +177,6 @@ ISA_NAMES_TABLE_START + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_X86_64_V4, NULL) + ISA_NAMES_TABLE_ENTRY("amx-fp16", FEATURE_AMX_FP16, P_NONE, "-mamx-fp16") + ISA_NAMES_TABLE_ENTRY("prefetchi", FEATURE_PREFETCHI, P_NONE, "-mprefetchi") ++ ISA_NAMES_TABLE_ENTRY("amx-complex", FEATURE_AMX_COMPLEX, ++ P_NONE, "-mamx-complex") + ISA_NAMES_TABLE_END +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 9bad238e3..ca5c8f8a0 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -424,7 +424,7 @@ i[34567]86-*-* | x86_64-*-*) + amxbf16intrin.h x86gprintrin.h uintrintrin.h + hresetintrin.h keylockerintrin.h avxvnniintrin.h + mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h +- amxfp16intrin.h prfchiintrin.h" ++ amxfp16intrin.h prfchiintrin.h amxcomplexintrin.h" + ;; + ia64-*-*) + extra_headers=ia64intrin.h +diff --git a/gcc/config/i386/amxcomplexintrin.h b/gcc/config/i386/amxcomplexintrin.h +new file mode 100644 +index 000000000..6ea1eca04 +--- /dev/null ++++ b/gcc/config/i386/amxcomplexintrin.h +@@ -0,0 +1,59 @@ ++/* Copyright (C) 2023 Free Software Foundation, Inc. ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ GCC is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ Under Section 7 of GPL version 3, you are granted additional ++ permissions described in the GCC Runtime Library Exception, version ++ 3.1, as published by the Free Software Foundation. ++ ++ You should have received a copy of the GNU General Public License and ++ a copy of the GCC Runtime Library Exception along with this program; ++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++ . */ ++ ++#if !defined _IMMINTRIN_H_INCLUDED ++#error "Never use directly; include instead." ++#endif ++ ++#ifndef _AMXCOMPLEXINTRIN_H_INCLUDED ++#define _AMXCOMPLEXINTRIN_H_INCLUDED ++ ++#if !defined(__AMX_COMPLEX__) ++#pragma GCC push_options ++#pragma GCC target("amx-complex") ++#define __DISABLE_AMX_COMPLEX__ ++#endif /* __AMX_COMPLEX__ */ ++ ++#if defined(__x86_64__) ++#define _tile_cmmimfp16ps_internal(src1_dst,src2,src3) \ ++ __asm__ volatile\ ++ ("{tcmmimfp16ps\t%%tmm"#src3", %%tmm"#src2", %%tmm"#src1_dst"|tcmmimfp16ps\t%%tmm"#src1_dst", %%tmm"#src2", %%tmm"#src3"}" ::) ++ ++#define _tile_cmmrlfp16ps_internal(src1_dst,src2,src3) \ ++ __asm__ volatile\ ++ ("{tcmmrlfp16ps\t%%tmm"#src3", %%tmm"#src2", %%tmm"#src1_dst"|tcmmrlfp16ps\t%%tmm"#src1_dst", %%tmm"#src2", %%tmm"#src3"}" ::) ++ ++#define _tile_cmmimfp16ps(src1_dst,src2,src3) \ ++ _tile_cmmimfp16ps_internal (src1_dst, src2, src3) ++ ++#define _tile_cmmrlfp16ps(src1_dst,src2,src3) \ ++ _tile_cmmrlfp16ps_internal (src1_dst, src2, src3) ++ ++#endif ++ ++#ifdef __DISABLE_AMX_COMPLEX__ ++#undef __DISABLE_AMX_COMPLEX__ ++#pragma GCC pop_options ++#endif /* __DISABLE_AMX_COMPLEX__ */ ++ ++#endif /* _AMXCOMPLEXINTRIN_H_INCLUDED */ +diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h +index 21100149a..530a45fad 100644 +--- a/gcc/config/i386/cpuid.h ++++ b/gcc/config/i386/cpuid.h +@@ -136,6 +136,7 @@ + #define bit_AMX_BF16 (1 << 22) + #define bit_AMX_TILE (1 << 24) + #define bit_AMX_INT8 (1 << 25) ++#define bit_AMX_COMPLEX (1 << 8) + + /* Extended State Enumeration Sub-leaf (%eax == 0xd, %ecx == 1) */ + #define bit_XSAVEOPT (1 << 0) +diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc +index 04f1dd682..5e0ac278c 100644 +--- a/gcc/config/i386/i386-c.cc ++++ b/gcc/config/i386/i386-c.cc +@@ -644,6 +644,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + def_or_undef (parse_in, "__AMX_FP16__"); + if (isa_flag2 & OPTION_MASK_ISA2_PREFETCHI) + def_or_undef (parse_in, "__PREFETCHI__"); ++ if (isa_flag2 & OPTION_MASK_ISA2_AMX_COMPLEX) ++ def_or_undef (parse_in, "__AMX_COMPLEX__"); + if (TARGET_IAMCU) + { + def_or_undef (parse_in, "__iamcu"); +diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def +index 744a7df85..7445b1bf7 100644 +--- a/gcc/config/i386/i386-isa.def ++++ b/gcc/config/i386/i386-isa.def +@@ -111,3 +111,4 @@ DEF_PTA(AVXVNNI) + DEF_PTA(AVX512FP16) + DEF_PTA(AMX_FP16) + DEF_PTA(PREFETCHI) ++DEF_PTA(AMX_COMPLEX) +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 6645e3259..7efd25084 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -233,7 +233,8 @@ static struct ix86_target_opts isa2_opts[] = + { "-mavxvnni", OPTION_MASK_ISA2_AVXVNNI }, + { "-mavx512fp16", OPTION_MASK_ISA2_AVX512FP16 }, + { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 }, +- { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI } ++ { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI }, ++ { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX } + }; + static struct ix86_target_opts isa_opts[] = + { +@@ -1080,6 +1081,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], + IX86_ATTR_ISA ("avx512fp16", OPT_mavx512fp16), + IX86_ATTR_ISA ("amx-fp16", OPT_mamx_fp16), + IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi), ++ IX86_ATTR_ISA ("amx-complex", OPT_mamx_complex), + + /* enum options */ + IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 50cd114f6..fba94f3f6 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1234,3 +1234,7 @@ Support AMX-FP16 built-in functions and code generation. + mprefetchi + Target Mask(ISA2_PREFETCHI) Var(ix86_isa_flags2) Save + Support PREFETCHI built-in functions and code generation. ++ ++mamx-complex ++Target Mask(ISA2_AMX_COMPLEX) Var(ix86_isa_flags2) Save ++Support AMX-COMPLEX built-in functions and code generation. +diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h +index 0447ca4b2..bd819c7f4 100644 +--- a/gcc/config/i386/immintrin.h ++++ b/gcc/config/i386/immintrin.h +@@ -124,6 +124,8 @@ + + #include + ++#include ++ + #include + + #include +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index ba9faf4b2..d7b0bc802 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -7048,6 +7048,11 @@ Enable/disable the generation of the AMX-FP16 instructions. + @cindex @code{target("prefetchi")} function attribute, x86 + Enable/disable the generation of the PREFETCHI instructions. + ++@cindex @code{target("amx-complex")} function attribute, x86 ++@item amx-complex ++@itemx no-amx-complex ++Enable/disable the generation of the AMX-COMPLEX instructions. ++ + @item cld + @itemx no-cld + @cindex @code{target("cld")} function attribute, x86 +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 8ca831dc1..186b33481 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1428,7 +1428,7 @@ See RS/6000 and PowerPC Options. + -mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol + -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol + -mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni@gol +--mavx512fp16 -mamx-fp16 -mprefetchi @gol ++-mavx512fp16 -mamx-fp16 -mprefetchi -mamx-complex @gol + -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol + -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol + -mkl -mwidekl @gol +@@ -32459,6 +32459,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. + @need 200 + @itemx -mprefetchi + @opindex mprefetchi ++@need 200 ++@opindex mamx-complex ++@itemx -mamx-complex + These switches enable the use of instructions in the MMX, SSE, + SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF, + AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, +@@ -32469,7 +32472,7 @@ XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2, + GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, + ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, + UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512-FP16, +-AMX-FP16, PREFETCHI or CLDEMOTE extended instruction sets. Each has a corresponding ++AMX-FP16, PREFETCHI, AMX-COMPLEX or CLDEMOTE extended instruction sets. Each has a corresponding + @option{-mno-} option to disable use of these instructions. + + These extensions are also available as built-in functions: see +diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi +index c68e492dc..454fae11a 100644 +--- a/gcc/doc/sourcebuild.texi ++++ b/gcc/doc/sourcebuild.texi +@@ -2472,6 +2472,9 @@ Target supports the execution of @code{amx-int8} instructions. + @item amx_bf16 + Target supports the execution of @code{amx-bf16} instructions. + ++@item amx_complex ++Target supports the execution of @code{amx-complex} instructions. ++ + @item amx_fp16 + Target supports the execution of @code{amx-fp16} instructions. + +diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C +index 72ed5fed0..ae1b8f632 100644 +--- a/gcc/testsuite/g++.dg/other/i386-2.C ++++ b/gcc/testsuite/g++.dg/other/i386-2.C +@@ -1,5 +1,5 @@ + /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +-/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi" } */ ++/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi -mamx-complex" } */ + + /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, + xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, +diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C +index 9dd53653f..783e35774 100644 +--- a/gcc/testsuite/g++.dg/other/i386-3.C ++++ b/gcc/testsuite/g++.dg/other/i386-3.C +@@ -1,5 +1,5 @@ + /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +-/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi" } */ ++/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi -mamx-complex" } */ + + /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, + xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, +diff --git a/gcc/testsuite/gcc.target/i386/amx-check.h b/gcc/testsuite/gcc.target/i386/amx-check.h +index 27dd37bf9..f1a04cf1f 100644 +--- a/gcc/testsuite/gcc.target/i386/amx-check.h ++++ b/gcc/testsuite/gcc.target/i386/amx-check.h +@@ -216,6 +216,9 @@ main () + #ifdef AMX_FP16 + && __builtin_cpu_supports ("amx-fp16") + #endif ++#ifdef AMX_COMPLEX ++ && __builtin_cpu_supports ("amx-complex") ++#endif + #ifdef __linux__ + && request_perm_xtile_data () + #endif +diff --git a/gcc/testsuite/gcc.target/i386/amx-helper.h b/gcc/testsuite/gcc.target/i386/amx-helper.h +index fe24d7067..6ed9f5eb3 100644 +--- a/gcc/testsuite/gcc.target/i386/amx-helper.h ++++ b/gcc/testsuite/gcc.target/i386/amx-helper.h +@@ -1,6 +1,6 @@ + #ifndef AMX_HELPER_H_INCLUDED + #define AMX_HELPER_H_INCLUDED +-#if defined(AMX_FP16) ++#if defined(AMX_FP16) || defined(AMX_COMPLEX) + #include + #include + #endif +@@ -12,7 +12,7 @@ typedef union + uint16_t u; + } union16f_uw; + +-#if defined(AMX_FP16) ++#if defined(AMX_FP16) || defined(AMX_COMPLEX) + /* Transformation functions between fp16/float */ + static uint16_t make_f32_fp16 (float f) + { +diff --git a/gcc/testsuite/gcc.target/i386/amxcomplex-asmatt-1.c b/gcc/testsuite/gcc.target/i386/amxcomplex-asmatt-1.c +new file mode 100644 +index 000000000..b6745e34b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxcomplex-asmatt-1.c +@@ -0,0 +1,15 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-O2 -mamx-complex" } */ ++/* { dg-final { scan-assembler "tcmmimfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */ ++/* { dg-final { scan-assembler "tcmmrlfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */ ++#include ++ ++#define TMM1 1 ++#define TMM2 2 ++#define TMM3 3 ++ ++void TEST() ++{ ++ _tile_cmmimfp16ps (TMM1, TMM2, TMM3); ++ _tile_cmmrlfp16ps (TMM1, TMM2, TMM3); ++} +diff --git a/gcc/testsuite/gcc.target/i386/amxcomplex-asmintel-1.c b/gcc/testsuite/gcc.target/i386/amxcomplex-asmintel-1.c +new file mode 100644 +index 000000000..305465e88 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxcomplex-asmintel-1.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-require-effective-target masm_intel } */ ++/* { dg-options "-O2 -mamx-complex -masm=intel" } */ ++/* { dg-final { scan-assembler "tcmmimfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */ ++/* { dg-final { scan-assembler "tcmmrlfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */ ++#include ++ ++void TEST() ++{ ++ _tile_cmmimfp16ps (1, 2, 3); ++ _tile_cmmrlfp16ps (1, 2, 3); ++} +diff --git a/gcc/testsuite/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c b/gcc/testsuite/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c +new file mode 100644 +index 000000000..6e3762c9f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c +@@ -0,0 +1,53 @@ ++/* { dg-do run { target { ! ia32 } } } */ ++/* { dg-require-effective-target amx_complex } */ ++/* { dg-require-effective-target avx512fp16 } */ ++/* { dg-options "-O2 -mamx-complex -mavx512fp16" } */ ++#define AMX_COMPLEX ++#define DO_TEST test_amx_complex_cmmimfp16ps ++void test_amx_complex_cmmimfp16ps (); ++#include "amx-helper.h" ++ ++void calc_matrix_cmmimfp16ps (__tile *dst, __tile *src1, __tile *src2) ++{ ++ uint16_t *src1_buf = (uint16_t *) src1->buf; ++ uint16_t *src2_buf = (uint16_t *) src2->buf; ++ float *dst_buf = (float *) dst->buf; ++ ++ int M = src1->rows; ++ int N = src1->colsb / 4; ++ int K = src2->colsb / 4; ++ int i, j, k, t; ++ ++ for (i = 0; i < M; i++) ++ for (j = 0; j < N; j++) ++ for (k = 0; k < K; k++) ++ for (t = 0; t < 2; t+=2) ++ dst_buf[i * N + k] += ++ (make_fp16_f32(src1_buf[i * 2 * N + 2 * j + t]) * ++ make_fp16_f32(src2_buf[j * 2 * K + 2 * k + t + 1])) + ++ (make_fp16_f32(src1_buf[i * 2 * N + 2 * j + t + 1]) * ++ make_fp16_f32(src2_buf[j * 2 * K + 2 * k + t])); ++} ++ ++void test_amx_complex_cmmimfp16ps () ++{ ++ __tilecfg_u cfg; ++ __tile dst, dst_ref, src1, src2; ++ uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024]; ++ ++ init_fp16_max_tile_buffer (tmp_dst_buf); ++ init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf); ++ ++ init_tile_config (&cfg); ++ init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf); ++ init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf); ++ init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf); ++ ++ calc_matrix_cmmimfp16ps (&dst, &src1, &src2); ++ ++ _tile_cmmimfp16ps (1, 2, 3); ++ _tile_stored (1, dst_ref.buf, _STRIDE); ++ ++ if (!check_tile_register (&dst_ref, &dst)) ++ abort (); ++} +diff --git a/gcc/testsuite/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c b/gcc/testsuite/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c +new file mode 100644 +index 000000000..15940708a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c +@@ -0,0 +1,53 @@ ++/* { dg-do run { target { ! ia32 } } } */ ++/* { dg-require-effective-target amx_complex } */ ++/* { dg-require-effective-target avx512fp16 } */ ++/* { dg-options "-O2 -mamx-complex -mavx512fp16" } */ ++#define AMX_COMPLEX ++#define DO_TEST test_amx_complex_cmmrlfp16ps ++void test_amx_complex_cmmrlfp16ps(); ++#include "amx-helper.h" ++ ++void calc_matrix_cmmrlfp16ps (__tile *dst, __tile *src1, __tile *src2) ++{ ++ uint16_t *src1_buf = (uint16_t *) src1->buf; ++ uint16_t *src2_buf = (uint16_t *) src2->buf; ++ float *dst_buf = (float *) dst->buf; ++ ++ int M = src1->rows; ++ int N = src1->colsb / 4; ++ int K = src2->colsb / 4; ++ int i, j, k, t; ++ ++ for (i = 0; i < M; i++) ++ for (j = 0; j < N; j++) ++ for (k = 0; k < K; k++) ++ for (t = 0; t < 2; t+=2) ++ dst_buf[i * N + k] += ++ (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t]) * ++ make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t])) - ++ (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t + 1]) * ++ make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t + 1])); ++} ++ ++void test_amx_complex_cmmrlfp16ps () ++{ ++ __tilecfg_u cfg; ++ __tile dst, dst_ref, src1, src2; ++ uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024]; ++ ++ init_fp16_max_tile_buffer (tmp_dst_buf); ++ init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf); ++ ++ init_tile_config (&cfg); ++ init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf); ++ init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf); ++ init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf); ++ ++ calc_matrix_cmmrlfp16ps (&dst, &src1, &src2); ++ ++ _tile_cmmrlfp16ps (1, 2, 3); ++ _tile_stored (1, dst_ref.buf, _STRIDE); ++ ++ if (!check_tile_register (&dst_ref, &dst)) ++ abort (); ++} +diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +index bdcfdbc88..1a2f3b83d 100644 +--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc ++++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +@@ -82,6 +82,7 @@ extern void test_avxvnni (void) __attribute__((__target__("avxvnni"))); + extern void test_avx512fp16 (void) __attribute__((__target__("avx512fp16"))); + extern void test_amx_fp16 (void) __attribute__((__target__("amx-fp16"))); + extern void test_prefetchi (void) __attribute__((__target__("prefetchi"))); ++extern void test_amx_complex (void) __attribute__((__target__("amx-complex"))); + + extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); + extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); +@@ -165,6 +166,7 @@ extern void test_no_avxvnni (void) __attribute__((__target__("no-avxvnni"))); + extern void test_no_avx512fp16 (void) __attribute__((__target__("no-avx512fp16"))); + extern void test_no_amx_fp16 (void) __attribute__((__target__("no-amx-fp16"))); + extern void test_no_prefetchi (void) __attribute__((__target__("no-prefetchi"))); ++extern void test_no_amx_complex (void) __attribute__((__target__("no-amx-complex"))); + + extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); + extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); +diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c +index 9ab4a7e0c..d2aadd506 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-12.c ++++ b/gcc/testsuite/gcc.target/i386/sse-12.c +@@ -3,7 +3,7 @@ + popcntintrin.h gfniintrin.h and mm_malloc.h are usable + with -O -std=c89 -pedantic-errors. */ + /* { dg-do compile } */ +-/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mamx-fp16" } */ ++/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mamx-fp16 -mamx-complex" } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c +index db7c0fc7a..c39382836 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-13.c ++++ b/gcc/testsuite/gcc.target/i386/sse-13.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi" } */ ++/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mprefetchi -mamx-complex" } */ + /* { dg-add-options bind_pic_locally } */ + + #include +diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c +index eaa1a8d81..c34ac1aec 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-14.c ++++ b/gcc/testsuite/gcc.target/i386/sse-14.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16" } */ ++/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mamx-fp16 -mamx-complex" } */ + /* { dg-add-options bind_pic_locally } */ + + #include +diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c +index 19afe639d..c3667b829 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-22.c ++++ b/gcc/testsuite/gcc.target/i386/sse-22.c +@@ -103,7 +103,7 @@ + + + #ifndef DIFFERENT_PRAGMAS +-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16") ++#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16,amx-complex") + #endif + + /* Following intrinsics require immediate arguments. They +@@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1) + + /* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */ + #ifdef DIFFERENT_PRAGMAS +-#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16") ++#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16,amx-complex") + #endif + #include + test_1 (_cvtss_sh, unsigned short, float, 1) +diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c +index 741694e87..756b6eb9c 100644 +--- a/gcc/testsuite/gcc.target/i386/sse-23.c ++++ b/gcc/testsuite/gcc.target/i386/sse-23.c +@@ -843,6 +843,6 @@ + #define __builtin_ia32_vpclmulqdq_v2di(A, B, C) __builtin_ia32_vpclmulqdq_v2di(A, B, 1) + #define __builtin_ia32_vpclmulqdq_v8di(A, B, C) __builtin_ia32_vpclmulqdq_v8di(A, B, 1) + +-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16,prefetchi") ++#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,amx-fp16,prefetchi,amx-complex") + + #include +diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp +index 0d83c780c..d404058fd 100644 +--- a/gcc/testsuite/lib/target-supports.exp ++++ b/gcc/testsuite/lib/target-supports.exp +@@ -9421,6 +9421,17 @@ proc check_effective_target_avxvnni { } { + } "-mavxvnni" ] + } + ++# Return 1 if amx-complex instructions can be compiled. ++proc check_effective_target_amx_complex { } { ++ return [check_no_compiler_messages amx_complex object { ++ void ++ foo () ++ { ++ __asm__ volatile ("tcmmimfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::); ++ } ++ } "-mamx-complex" ] ++} ++ + # Return 1 if sse instructions can be compiled. + proc check_effective_target_sse { } { + return [check_no_compiler_messages sse object { +-- +2.31.1 + diff --git a/0276-i386-Add-AMX-COMPLEX-to-Granite-Rapids.patch b/0276-i386-Add-AMX-COMPLEX-to-Granite-Rapids.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c69affde2d13687a27e6124dc8cc53bdb19d909 --- /dev/null +++ b/0276-i386-Add-AMX-COMPLEX-to-Granite-Rapids.patch @@ -0,0 +1,30 @@ +From 40469a6119085e4c4741bcaeb9418606d28b40c4 Mon Sep 17 00:00:00 2001 +From: Haochen Jiang +Date: Fri, 31 Mar 2023 10:49:14 +0800 +Subject: [PATCH 22/28] i386: Add AMX-COMPLEX to Granite Rapids + +gcc/Changelog: + + * config/i386/i386.h (PTA_GRANITERAPIDS): Add PTA_AMX_COMPLEX. + +(cherry picked from commit afa87bd5f7b126e20268aa959441cde2e02bba0e) +--- + gcc/config/i386/i386.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 75953defc..56d7794dc 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2358,7 +2358,7 @@ constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_TREMONT | PTA_ADX | PTA_AVX + | PTA_PCONFIG | PTA_PKU | PTA_VAES | PTA_VPCLMULQDQ | PTA_SERIALIZE + | PTA_HRESET | PTA_KL | PTA_WIDEKL | PTA_AVXVNNI; + constexpr wide_int_bitmask PTA_GRANITERAPIDS = PTA_SAPPHIRERAPIDS | PTA_AMX_FP16 +- | PTA_PREFETCHI; ++ | PTA_PREFETCHI | PTA_AMX_COMPLEX; + constexpr wide_int_bitmask PTA_KNM = PTA_KNL | PTA_AVX5124VNNIW + | PTA_AVX5124FMAPS | PTA_AVX512VPOPCNTDQ; + constexpr wide_int_bitmask PTA_ZNVER1 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 +-- +2.31.1 + diff --git a/0277-Initial-Granite-Rapids-D-Support.patch b/0277-Initial-Granite-Rapids-D-Support.patch new file mode 100644 index 0000000000000000000000000000000000000000..def6e9633a2a7a399ff1078aec37165eca6d25ce --- /dev/null +++ b/0277-Initial-Granite-Rapids-D-Support.patch @@ -0,0 +1,212 @@ +From 125e5d448538f7534e0fe3df9b7947cf41605b51 Mon Sep 17 00:00:00 2001 +From: "Mo, Zewei" +Date: Mon, 3 Jul 2023 11:00:26 +0800 +Subject: [PATCH 23/28] Initial Granite Rapids D Support + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h + (get_intel_cpu): Handle Granite Rapids D. + * common/config/i386/i386-common.cc: + (processor_alias_table): Add graniterapids-d. + * common/config/i386/i386-cpuinfo.h + (enum processor_subtypes): Add INTEL_COREI7_GRANITERAPIDS_D. + * config.gcc: Add -march=graniterapids-d. + * config/i386/driver-i386.cc (host_detect_local_cpu): + Handle graniterapids-d. + * config/i386/i386.h: (PTA_GRANITERAPIDS_D): New. + * doc/extend.texi: Add graniterapids-d. + * doc/invoke.texi: Ditto. + +gcc/testsuite/ChangeLog: + + * g++.target/i386/mv16.C: Add graniterapids-d. + * gcc.target/i386/funcspec-56.inc: Handle new march. + +(cherry picked from commit a0cb65d34cc141571e870fb3b53b3ff47ae3338d) +--- + gcc/common/config/i386/cpuinfo.h | 9 ++++++++- + gcc/common/config/i386/i386-common.cc | 2 ++ + gcc/common/config/i386/i386-cpuinfo.h | 1 + + gcc/config.gcc | 3 ++- + gcc/config/i386/driver-i386.cc | 5 ++++- + gcc/config/i386/i386.h | 4 +++- + gcc/doc/extend.texi | 3 +++ + gcc/doc/invoke.texi | 11 +++++++++++ + gcc/testsuite/g++.target/i386/mv16.C | 6 ++++++ + gcc/testsuite/gcc.target/i386/funcspec-56.inc | 1 + + 10 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 39d3351db..1e53248ef 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -529,7 +529,6 @@ get_intel_cpu (struct __processor_model *cpu_model, + cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS; + break; + case 0xad: +- case 0xae: + /* Granite Rapids. */ + cpu = "graniterapids"; + CHECK___builtin_cpu_is ("corei7"); +@@ -537,6 +536,14 @@ get_intel_cpu (struct __processor_model *cpu_model, + cpu_model->__cpu_type = INTEL_COREI7; + cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS; + break; ++ case 0xae: ++ /* Granite Rapids D. */ ++ cpu = "graniterapids-d"; ++ CHECK___builtin_cpu_is ("corei7"); ++ CHECK___builtin_cpu_is ("graniterapids-d"); ++ cpu_model->__cpu_type = INTEL_COREI7; ++ cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS_D; ++ break; + case 0x17: + case 0x1d: + /* Penryn. */ +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index 87e8afe9b..28f468f48 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -1993,6 +1993,8 @@ const pta processor_alias_table[] = + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, + {"graniterapids", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS, + M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS), P_PROC_AVX512F}, ++ {"graniterapids-d", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS_D, ++ M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS_D), P_PROC_AVX512F}, + {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, + M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, + {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, +diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h +index 56020faac..a32f32c97 100644 +--- a/gcc/common/config/i386/i386-cpuinfo.h ++++ b/gcc/common/config/i386/i386-cpuinfo.h +@@ -93,6 +93,7 @@ enum processor_subtypes + INTEL_COREI7_ROCKETLAKE, + AMDFAM19H_ZNVER4, + INTEL_COREI7_GRANITERAPIDS, ++ INTEL_COREI7_GRANITERAPIDS_D, + CPU_SUBTYPE_MAX + }; + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index ca5c8f8a0..3108ac4eb 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -670,7 +670,8 @@ slm nehalem westmere sandybridge ivybridge haswell broadwell bonnell \ + silvermont knl knm skylake-avx512 cannonlake icelake-client icelake-server \ + skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \ + sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \ +-nano-x2 eden-x4 nano-x4 x86-64 x86-64-v2 x86-64-v3 x86-64-v4 graniterapids native" ++nano-x2 eden-x4 nano-x4 x86-64 x86-64-v2 x86-64-v3 x86-64-v4 graniterapids \ ++graniterapids-d native" + + # Additional x86 processors supported by --with-cpu=. Each processor + # MUST be separated by exactly one space. +diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc +index ea8c3d8d1..e3bca4b49 100644 +--- a/gcc/config/i386/driver-i386.cc ++++ b/gcc/config/i386/driver-i386.cc +@@ -576,8 +576,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) + /* This is unknown family 0x6 CPU. */ + if (has_feature (FEATURE_AVX)) + { ++ /* Assume Granite Rapids D. */ ++ if (has_feature (FEATURE_AMX_COMPLEX)) ++ cpu = "graniterapids-d"; + /* Assume Granite Rapids. */ +- if (has_feature (FEATURE_AMX_FP16)) ++ else if (has_feature (FEATURE_AMX_FP16)) + cpu = "graniterapids"; + /* Assume Tiger Lake */ + else if (has_feature (FEATURE_AVX512VP2INTERSECT)) +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 56d7794dc..eda3e5e5b 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2358,7 +2358,9 @@ constexpr wide_int_bitmask PTA_ALDERLAKE = PTA_TREMONT | PTA_ADX | PTA_AVX + | PTA_PCONFIG | PTA_PKU | PTA_VAES | PTA_VPCLMULQDQ | PTA_SERIALIZE + | PTA_HRESET | PTA_KL | PTA_WIDEKL | PTA_AVXVNNI; + constexpr wide_int_bitmask PTA_GRANITERAPIDS = PTA_SAPPHIRERAPIDS | PTA_AMX_FP16 +- | PTA_PREFETCHI | PTA_AMX_COMPLEX; ++ | PTA_PREFETCHI; ++constexpr wide_int_bitmask PTA_GRANITERAPIDS_D = PTA_GRANITERAPIDS ++ | PTA_AMX_COMPLEX; + constexpr wide_int_bitmask PTA_KNM = PTA_KNL | PTA_AVX5124VNNIW + | PTA_AVX5124FMAPS | PTA_AVX512VPOPCNTDQ; + constexpr wide_int_bitmask PTA_ZNVER1 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index d7b0bc802..674db2f1a 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -21837,6 +21837,9 @@ Intel Core i7 Rocketlake CPU. + @item graniterapids + Intel Core i7 graniterapids CPU. + ++@item graniterapids-d ++Intel Core i7 graniterapids D CPU. ++ + @item bonnell + Intel Atom Bonnell CPU. + +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 186b33481..a2ec060fd 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -31626,6 +31626,17 @@ MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, + SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, + AVX512BF16, AMX-FP16 and PREFETCHI instruction set support. + ++@item graniterapids-d ++Intel graniterapids D CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, ++SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, ++RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, ++AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, ++AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, ++VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, ++MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, ++SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, ++AVX512BF16, AMX-FP16, PREFETCHI and AMX-COMPLEX instruction set support. ++ + @item k6 + AMD K6 CPU with MMX instruction set support. + +diff --git a/gcc/testsuite/g++.target/i386/mv16.C b/gcc/testsuite/g++.target/i386/mv16.C +index 65cc24f32..17b1fc722 100644 +--- a/gcc/testsuite/g++.target/i386/mv16.C ++++ b/gcc/testsuite/g++.target/i386/mv16.C +@@ -96,6 +96,10 @@ int __attribute__ ((target("arch=graniterapids"))) foo () { + return 26; + } + ++int __attribute__ ((target("arch=graniterapids-d"))) foo () { ++ return 28; ++} ++ + int main () + { + int val = foo (); +@@ -136,6 +140,8 @@ int main () + assert (val == 24); + else if (__builtin_cpu_is ("graniterapids")) + assert (val == 25); ++ else if (__builtin_cpu_is ("graniterapids-d")) ++ assert (val == 26); + else + assert (val == 0); + +diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +index 1a2f3b83d..f0f3397a7 100644 +--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc ++++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc +@@ -191,6 +191,7 @@ extern void test_arch_sapphirerapids (void) __attribute__((__target__("arch=sapp + extern void test_arch_alderlake (void) __attribute__((__target__("arch=alderlake"))); + extern void test_arch_rocketlake (void) __attribute__((__target__("arch=rocketlake"))); + extern void test_arch_graniterapids (void) __attribute__((__target__("arch=graniterapids"))); ++extern void test_arch_graniterapids_d (void) __attribute__((__target__("arch=graniterapids-d"))); + extern void test_arch_k8 (void) __attribute__((__target__("arch=k8"))); + extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3"))); + extern void test_arch_opteron (void) __attribute__((__target__("arch=opteron"))); +-- +2.31.1 + diff --git a/0278-Correct-Granite-Rapids-D-documentation.patch b/0278-Correct-Granite-Rapids-D-documentation.patch new file mode 100644 index 0000000000000000000000000000000000000000..18e756a5f51d16f3c69d18448f1cfd24db55a3fc --- /dev/null +++ b/0278-Correct-Granite-Rapids-D-documentation.patch @@ -0,0 +1,48 @@ +From a809a6a416af4d08f7feeadfdd5d1f5a76a830b5 Mon Sep 17 00:00:00 2001 +From: Haochen Jiang +Date: Thu, 20 Jul 2023 10:47:18 +0800 +Subject: [PATCH 24/28] Correct Granite Rapids{, D} documentation + +gcc/Changelog: + + * doc/invoke.texi: Remove AVX512VP2INTERSECT in + Granite Rapids{, D} from documentation. + +(cherry picked from commit 38daaaa91438d3f635a10bf5d5181c3b29f07df9) +--- + gcc/doc/invoke.texi | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index a2ec060fd..4d3eccdb2 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -31622,9 +31622,9 @@ RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, + AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, + AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, + VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, +-MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, +-SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, +-AVX512BF16, AMX-FP16 and PREFETCHI instruction set support. ++MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, ++UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16, AMX-FP16 ++and PREFETCHI instruction set support. + + @item graniterapids-d + Intel graniterapids D CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, +@@ -31633,9 +31633,9 @@ RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, + AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, + AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, + VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, +-MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, +-SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, +-AVX512BF16, AMX-FP16, PREFETCHI and AMX-COMPLEX instruction set support. ++MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, ++UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512FP16, AVX512BF16, AMX-FP16, ++PREFETCHI and AMX-COMPLEX instruction set support. + + @item k6 + AMD K6 CPU with MMX instruction set support. +-- +2.31.1 + diff --git a/0279-i386-Remove-Meteorlake-s-family_model.patch b/0279-i386-Remove-Meteorlake-s-family_model.patch new file mode 100644 index 0000000000000000000000000000000000000000..13e5dc9beaaac26d831868bee6f4aa466da22269 --- /dev/null +++ b/0279-i386-Remove-Meteorlake-s-family_model.patch @@ -0,0 +1,30 @@ +From 62852213bc6d3e56804ca05826bb95a3a2fe4eba Mon Sep 17 00:00:00 2001 +From: "Hu, Lin1" +Date: Thu, 15 Dec 2022 15:51:18 +0800 +Subject: [PATCH 25/28] i386: Remove Meteorlake's family_model + +gcc/ChangeLog: + + * common/config/i386/cpuinfo.h (get_intel_cpu): Remove case 0xb5 + for meteorlake. + +(cherry picked from commit 9e74b7ec0b218364905e3e7de5c41e8148ffc61b) +--- + gcc/common/config/i386/cpuinfo.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 1e53248ef..348bc0c12 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -510,7 +510,6 @@ get_intel_cpu (struct __processor_model *cpu_model, + /* Alder Lake. */ + case 0xb7: + /* Raptor Lake. */ +- case 0xb5: + case 0xaa: + case 0xac: + /* Meteor Lake. */ +-- +2.31.1 + diff --git a/0280-x86-Update-model-values-for-Alderlake-Rocketlake-and.patch b/0280-x86-Update-model-values-for-Alderlake-Rocketlake-and.patch new file mode 100644 index 0000000000000000000000000000000000000000..4abff3ff906452f9d9b6573815312b307ecaf9d1 --- /dev/null +++ b/0280-x86-Update-model-values-for-Alderlake-Rocketlake-and.patch @@ -0,0 +1,33 @@ +From 73042aa18fe70aa30a9c7c760b08e642560ecccd Mon Sep 17 00:00:00 2001 +From: "Cui, Lili" +Date: Thu, 29 Jun 2023 03:10:35 +0000 +Subject: [PATCH 26/28] x86: Update model values for Alderlake, Rocketlake and + Raptorlake. + +Update model values for Alderlake, Rocketlake and Raptorlake according to SDM. + +gcc/ChangeLog + + * common/config/i386/cpuinfo.h (get_intel_cpu): Remove model value 0xa8 + from Rocketlake, move model value 0xbf from Alderlake to Raptorlake. + +(cherry picked from commit e510c3be13a8ccdf1fc1b27c2501c126d493f335) +--- + gcc/common/config/i386/cpuinfo.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index 348bc0c12..f9bcb6fad 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -509,6 +509,7 @@ get_intel_cpu (struct __processor_model *cpu_model, + case 0x9a: + /* Alder Lake. */ + case 0xb7: ++ case 0xbf: + /* Raptor Lake. */ + case 0xaa: + case 0xac: +-- +2.31.1 + diff --git a/0281-x86-Update-model-values-for-Raptorlake.patch b/0281-x86-Update-model-values-for-Raptorlake.patch new file mode 100644 index 0000000000000000000000000000000000000000..eace6b337dfc15f4e25edc8f832720d85877a8f8 --- /dev/null +++ b/0281-x86-Update-model-values-for-Raptorlake.patch @@ -0,0 +1,32 @@ +From 3dbe28984e0f9c24d6670cfba42983bc32c08b0a Mon Sep 17 00:00:00 2001 +From: "Cui, Lili" +Date: Mon, 14 Aug 2023 02:06:00 +0000 +Subject: [PATCH 27/28] x86: Update model values for Raptorlake. + +Update model values for Raptorlake according to SDM. + +gcc/ChangeLog + + * common/config/i386/cpuinfo.h (get_intel_cpu): Add model value 0xba + to Raptorlake. + +(cherry picked from commit 614052dd4ea083e086712809c754ffebd9361316) +--- + gcc/common/config/i386/cpuinfo.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h +index f9bcb6fad..da1568fd1 100644 +--- a/gcc/common/config/i386/cpuinfo.h ++++ b/gcc/common/config/i386/cpuinfo.h +@@ -509,6 +509,7 @@ get_intel_cpu (struct __processor_model *cpu_model, + case 0x9a: + /* Alder Lake. */ + case 0xb7: ++ case 0xba: + case 0xbf: + /* Raptor Lake. */ + case 0xaa: +-- +2.31.1 + diff --git a/0282-Fix-target_clone-arch-graniterapids-d.patch b/0282-Fix-target_clone-arch-graniterapids-d.patch new file mode 100644 index 0000000000000000000000000000000000000000..54abd2eeb0356913d6f70823b5c70fd5a0aa6483 --- /dev/null +++ b/0282-Fix-target_clone-arch-graniterapids-d.patch @@ -0,0 +1,159 @@ +From 8db0f3cd29bd7f937ffa01dd1100360fbbf5b6f4 Mon Sep 17 00:00:00 2001 +From: liuhongt +Date: Tue, 22 Aug 2023 18:18:31 +0800 +Subject: [PATCH 28/28] Fix target_clone ("arch=graniterapids-d") + +Both "graniterapid-d" and "graniterapids" are attached with +PROCESSOR_GRANITERAPID in processor_alias_table but mapped to +different __cpu_subtype in get_intel_cpu. + +And get_builtin_code_for_version will try to match the first +PROCESSOR_GRANITERAPIDS in processor_alias_table which maps to +"granitepraids" here. + +861 else if (new_target->arch_specified && new_target->arch > 0) +1862 for (i = 0; i < pta_size; i++) +1863 if (processor_alias_table[i].processor == new_target->arch) +1864 { +1865 const pta *arch_info = &processor_alias_table[i]; +1866 switch (arch_info->priority) +1867 { +1868 default: +1869 arg_str = arch_info->name; + +This mismatch makes dispatch_function_versions check the preidcate +of__builtin_cpu_is ("graniterapids") for "graniterapids-d" and causes +the issue. +The patch explicitly adds PROCESSOR_GRANITERAPIDS_D to make a distinction. + +For "alderlake","raptorlake", "meteorlake" they share same isa, cost, +tuning, and mapped to the same __cpu_type/__cpu_subtype in +get_intel_cpu, so no need to add PROCESSOR_RAPTORLAKE and others. + +gcc/ChangeLog: + + * common/config/i386/i386-common.cc (processor_names): Add new + member graniterapids-s. + * config/i386/i386-options.cc (processor_alias_table): Update + table with and PROCESSOR_GRANITERAPIDS_D. + (m_GRANITERAPID_D): New macro. + (m_CORE_AVX512): Add m_GRANITERAPIDS_D. + (processor_cost_table): Add icelake_cost for + PROCESSOR_GRANITERAPIDS_D. + * config/i386/i386.h (enum processor_type): Add new member + PROCESSOR_GRANITERAPIDS_D. + * config/i386/i386-c.cc (ix86_target_macros_internal): Handle + PROCESSOR_GRANITERAPIDS_D +--- + gcc/common/config/i386/i386-common.cc | 6 ++++-- + gcc/config/i386/i386-c.cc | 8 ++++++++ + gcc/config/i386/i386-options.cc | 4 +++- + gcc/config/i386/i386.h | 3 ++- + 4 files changed, 17 insertions(+), 4 deletions(-) + +diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc +index 28f468f48..bec6801ce 100644 +--- a/gcc/common/config/i386/i386-common.cc ++++ b/gcc/common/config/i386/i386-common.cc +@@ -1873,6 +1873,7 @@ const char *const processor_names[] = + "alderlake", + "rocketlake", + "graniterapids", ++ "graniterapids-d", + "intel", + "geode", + "k6", +@@ -1993,8 +1994,9 @@ const pta processor_alias_table[] = + M_CPU_SUBTYPE (INTEL_COREI7_ALDERLAKE), P_PROC_AVX2}, + {"graniterapids", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS, + M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS), P_PROC_AVX512F}, +- {"graniterapids-d", PROCESSOR_GRANITERAPIDS, CPU_HASWELL, PTA_GRANITERAPIDS_D, +- M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS_D), P_PROC_AVX512F}, ++ {"graniterapids-d", PROCESSOR_GRANITERAPIDS_D, CPU_HASWELL, ++ PTA_GRANITERAPIDS_D, M_CPU_SUBTYPE (INTEL_COREI7_GRANITERAPIDS_D), ++ P_PROC_AVX512F}, + {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, + M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, + {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, +diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc +index 5e0ac278c..49f0db2b8 100644 +--- a/gcc/config/i386/i386-c.cc ++++ b/gcc/config/i386/i386-c.cc +@@ -246,6 +246,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + def_or_undef (parse_in, "__graniterapids"); + def_or_undef (parse_in, "__graniterapids__"); + break; ++ case PROCESSOR_GRANITERAPIDS_D: ++ def_or_undef (parse_in, "__graniterapids_d"); ++ def_or_undef (parse_in, "__graniterapids_d__"); ++ break; + case PROCESSOR_ALDERLAKE: + def_or_undef (parse_in, "__alderlake"); + def_or_undef (parse_in, "__alderlake__"); +@@ -254,6 +258,7 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + def_or_undef (parse_in, "__rocketlake"); + def_or_undef (parse_in, "__rocketlake__"); + break; ++ + /* use PROCESSOR_max to not set/unset the arch macro. */ + case PROCESSOR_max: + break; +@@ -426,6 +431,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, + case PROCESSOR_GRANITERAPIDS: + def_or_undef (parse_in, "__tune_graniterapids__"); + break; ++ case PROCESSOR_GRANITERAPIDS_D: ++ def_or_undef (parse_in, "__tune_graniterapids_d__"); ++ break; + case PROCESSOR_INTEL: + case PROCESSOR_GENERIC: + break; +diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc +index 7efd25084..86932d719 100644 +--- a/gcc/config/i386/i386-options.cc ++++ b/gcc/config/i386/i386-options.cc +@@ -128,10 +128,11 @@ along with GCC; see the file COPYING3. If not see + #define m_ALDERLAKE (HOST_WIDE_INT_1U< +Date: Mon, 22 Jul 2024 14:06:18 +0800 +Subject: [PATCH 1/2] i386: Change prefetchi output template + +For prefetchi instructions, RIP-relative address is explicitly mentioned +for operand and assembler obeys that rule strictly. This makes +instruction like: + + prefetchit0 bar + +got illegal for assembler, which should be a broad usage for prefetchi. + +Change to %a to explicitly add (%rip) after function label to make it +legal in assembler so that it could pass to linker to get the real address. + +gcc/ChangeLog: + + * config/i386/i386.md (prefetchi): Change to %a. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/prefetchi-1.c: Check (%rip). + +Reference: +https://gcc.gnu.org/git/?p=gcc.git;a=commit;h= +062e46a813799684c6f900815fd22451d6294ae1 +--- + gcc/config/i386/i386.md | 2 +- + gcc/testsuite/gcc.target/i386/prefetchi-1.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index f08c2cfb1..1b733008e 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -22917,7 +22917,7 @@ + "TARGET_PREFETCHI && TARGET_64BIT" + { + static const char * const patterns[2] = { +- "prefetchit1\t%0", "prefetchit0\t%0" ++ "prefetchit1\t%a0", "prefetchit0\t%a0" + }; + + int locality = INTVAL (operands[1]); +diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-1.c b/gcc/testsuite/gcc.target/i386/prefetchi-1.c +index 80f25e70e..03dfdc55e 100644 +--- a/gcc/testsuite/gcc.target/i386/prefetchi-1.c ++++ b/gcc/testsuite/gcc.target/i386/prefetchi-1.c +@@ -1,7 +1,7 @@ + /* { dg-do compile { target { ! ia32 } } } */ + /* { dg-options "-mprefetchi -O2" } */ +-/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+" 2 } } */ +-/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+" 2 } } */ ++/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+bar\\(%rip\\)" 2 } } */ ++/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+bar\\(%rip\\)" 2 } } */ + + #include + +-- +2.31.1 + diff --git a/0284-i386-Add-non-optimize-prefetchi-intrins.patch b/0284-i386-Add-non-optimize-prefetchi-intrins.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a450e8dba7dd7c27af7cd073db2afe4f6b0c393 --- /dev/null +++ b/0284-i386-Add-non-optimize-prefetchi-intrins.patch @@ -0,0 +1,92 @@ +From c19afda0ee549d294fd5714c63db24bcd4570d03 Mon Sep 17 00:00:00 2001 +From: Haochen Jiang +Date: Thu, 25 Jul 2024 16:16:05 +0800 +Subject: [PATCH 2/2] i386: Add non-optimize prefetchi intrins + +Under -O0, with the "newly" introduced intrins, the variable will be +transformed as mem instead of the origin symbol_ref. The compiler will +then treat the operand as invalid and turn the operation into nop, which +is not expected. Use macro for non-optimize to keep the variable as +symbol_ref just as how prefetch intrin does. + +gcc/ChangeLog: + + * config/i386/prfchiintrin.h + (_m_prefetchit0): Add macro for non-optimized option. + (_m_prefetchit1): Ditto. + +gcc/testsuite/ChangeLog: + + * gcc.target/i386/prefetchi-1b.c: New test. + +Reference: +https://gcc.gnu.org/git/?p=gcc.git;a=commit;h= +b4524c4430ba9771265bd9fc31e69a3f35dfe117 +--- + gcc/config/i386/prfchiintrin.h | 9 +++++++ + gcc/testsuite/gcc.target/i386/prefetchi-1b.c | 26 ++++++++++++++++++++ + 2 files changed, 35 insertions(+) + create mode 100644 gcc/testsuite/gcc.target/i386/prefetchi-1b.c + +diff --git a/gcc/config/i386/prfchiintrin.h b/gcc/config/i386/prfchiintrin.h +index 06deef488..1e3d42dc3 100644 +--- a/gcc/config/i386/prfchiintrin.h ++++ b/gcc/config/i386/prfchiintrin.h +@@ -30,6 +30,7 @@ + + #ifdef __x86_64__ + ++#ifdef __OPTIMIZE__ + extern __inline void + __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + _m_prefetchit0 (void* __P) +@@ -43,6 +44,14 @@ _m_prefetchit1 (void* __P) + { + __builtin_ia32_prefetchi (__P, 2); + } ++#else ++#define _m_prefetchit0(P) \ ++ __builtin_ia32_prefetchi(P, 3) ++ ++#define _m_prefetchit1(P) \ ++ __builtin_ia32_prefetchi(P, 2) ++ ++#endif + + #endif + +diff --git a/gcc/testsuite/gcc.target/i386/prefetchi-1b.c b/gcc/testsuite/gcc.target/i386/prefetchi-1b.c +new file mode 100644 +index 000000000..93139554d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/prefetchi-1b.c +@@ -0,0 +1,26 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-mprefetchi -O0" } */ ++/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+bar\\(%rip\\)" 1 } } */ ++/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+bar\\(%rip\\)" 1 } } */ ++ ++#include ++ ++int ++bar (int a) ++{ ++ return a + 1; ++} ++ ++int ++foo1 (int b) ++{ ++ _m_prefetchit0 (bar); ++ return bar (b) + 1; ++} ++ ++int ++foo2 (int b) ++{ ++ _m_prefetchit1 (bar); ++ return bar (b) + 1; ++} +-- +2.31.1 + diff --git a/0285-SME-Recover-hip09-and-hip11-in-aarch64-cores.def.patch b/0285-SME-Recover-hip09-and-hip11-in-aarch64-cores.def.patch new file mode 100644 index 0000000000000000000000000000000000000000..24dacd1eb01c3309f74cfa17af6c94d333dcbcef --- /dev/null +++ b/0285-SME-Recover-hip09-and-hip11-in-aarch64-cores.def.patch @@ -0,0 +1,32 @@ +From 239f0637307ff2f6afb1473e99d0bb0eaf8946b2 Mon Sep 17 00:00:00 2001 +From: xiezhiheng +Date: Fri, 23 Aug 2024 15:37:17 +0800 +Subject: [PATCH 154/157] [SME] Recover hip09 and hip11 in aarch64-cores.def + +--- + gcc/config/aarch64/aarch64-cores.def | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def +index f069c81cf..3337fd1a0 100644 +--- a/gcc/config/aarch64/aarch64-cores.def ++++ b/gcc/config/aarch64/aarch64-cores.def +@@ -130,6 +130,7 @@ AARCH64_CORE("a64fx", a64fx, a64fx, V8_2A, (F16, SVE), a64fx, 0x46, 0x001, -1) + + /* HiSilicon ('H') cores. */ + AARCH64_CORE("tsv110", tsv110, tsv110, V8_2A, (CRYPTO, F16), tsv110, 0x48, 0xd01, -1) ++AARCH64_CORE("hip09", hip09, hip09, V8_5A, (SVE, I8MM, F32MM, F64MM, PROFILE, PREDRES), hip09, 0x48, 0xd02, 0x0) + + /* ARMv8.3-A Architecture Processors. */ + +@@ -171,6 +172,7 @@ AARCH64_CORE("cortex-a710", cortexa710, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, + AARCH64_CORE("cortex-x2", cortexx2, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd48, -1) + + AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversen2, 0x41, 0xd49, -1) ++AARCH64_CORE("hip11", hip11, hip11, V8_5A, (SVE, SVE2, F16), hip11, 0x48, 0xd22, -1) + + AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) + AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) +-- +2.33.0 + diff --git a/0286-Try-to-use-AI-model-to-guide-optimization.patch b/0286-Try-to-use-AI-model-to-guide-optimization.patch new file mode 100644 index 0000000000000000000000000000000000000000..a697dcc7815d3697b9a09a95881de29f6e1ae30e --- /dev/null +++ b/0286-Try-to-use-AI-model-to-guide-optimization.patch @@ -0,0 +1,671 @@ +diff --git a/gcc/Makefile.in b/gcc/Makefile.in +index fcfa54697..f42aeb8e8 100644 +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -1449,6 +1449,7 @@ OBJS = \ + inchash.o \ + incpath.o \ + init-regs.o \ ++ ipa-hardware-detection.o \ + internal-fn.o \ + ipa-struct-reorg/ipa-struct-reorg.o \ + ipa-cp.o \ +diff --git a/gcc/common.opt b/gcc/common.opt +index fd98382fa..99e626641 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -185,6 +185,9 @@ const char *main_input_basename + Variable + int main_input_baselength + ++Variable ++bool optimize_maximum ++ + ; The base name used for auxiliary output files. + ; dump_base_name minus dump_base_ext. + +@@ -469,6 +472,10 @@ Ofast + Common Optimization + Optimize for speed disregarding exact standards compliance. + ++Om ++Common Optimization ++Optimize for maximizing radical optimization. ++ + Og + Common Optimization + Optimize for debugging experience rather than speed or size. +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 309ecc3d9..ad853af9a 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -18637,6 +18637,134 @@ aarch64_sve_adjust_stmt_cost (class vec_info *vinfo, vect_cost_for_stmt kind, + return stmt_cost; + } + ++/* Check whether in C language or LTO with only C language. */ ++extern bool lang_c_p (void); ++ ++static void ++override_C_optimize_options (struct gcc_options *opts) ++{ ++ opts->x_flag_ipa_reorder_fields = 1; ++ opts->x_flag_ipa_struct_reorg = 6; ++ opts->x_struct_layout_optimize_level = 6; ++ opts->x_flag_gnu89_inline = 1; ++ opts->x_flag_ccmp2 = 1; ++ opts->x_flag_array_widen_compare = 1; ++ opts->x_flag_convert_minmax = 1; ++ opts->x_flag_tree_slp_transpose_vectorize = 1; ++ opts->x_param_max_inline_insns_auto = 64; ++ opts->x_param_inline_unit_growth = 96; ++} ++ ++/* Check whether in CPP language or LTO with only CPP language. */ ++static bool ++lang_cpp_p (void) ++{ ++ const char *language_string = lang_hooks.name; ++ if (!language_string) ++ { ++ return false; ++ } ++ if (lang_GNU_CXX ()) ++ { ++ return true; ++ } ++ else if (strcmp (language_string, "GNU GIMPLE") == 0) // for LTO check ++ { ++ unsigned i = 0; ++ tree t = NULL_TREE; ++ FOR_EACH_VEC_SAFE_ELT (all_translation_units, i, t) ++ { ++ language_string = TRANSLATION_UNIT_LANGUAGE (t); ++ if (language_string == NULL ++ || strncmp (lang_hooks.name, "GNU C++", 7)) ++ { ++ return false; ++ } ++ } ++ return true; ++ } ++ return false; ++} ++ ++static void ++override_CPP_optimize_options (struct gcc_options *opts) ++{ ++ opts->x_flag_finite_loops = 1; ++ opts->x_flag_omit_frame_pointer = 1; ++ opts->x_flag_sized_deallocation = 0; ++ opts->x_flag_loop_elim = 1; ++ opts->x_flag_convert_minmax = 1; ++ opts->x_param_early_inlining_insns = 256; ++ opts->x_param_max_inline_insns_auto = 128; ++ opts->x_param_inline_unit_growth = 256; ++ opts->x_flag_cmlt_arith = 1; ++} ++ ++static void ++override_optimize_options_1 (struct gcc_options *opts) ++{ ++ opts->x_flag_split_ldp_stp = 1; ++ opts->x_flag_if_conversion_gimple = 1; ++ opts->x_flag_ifcvt_allow_complicated_cmps = 1; ++ opts->x_param_ifcvt_allow_register_renaming = 2; ++ opts->x_param_max_rtl_if_conversion_unpredictable_cost = 48; ++ opts->x_param_max_rtl_if_conversion_predictable_cost = 48; ++} ++ ++static void ++override_Fortran_optimize_options (struct gcc_options *opts) ++{ ++ opts->x_flag_unroll_loops = 1; ++ opts->x_flag_unconstrained_commons = 1; ++ opts->x_param_ipa_cp_eval_threshold = 1; ++ opts->x_param_ipa_cp_unit_growth = 80; ++ opts->x_param_ipa_cp_max_recursive_depth = 8; ++ opts->x_param_large_unit_insns = 30000; ++ opts->x_flag_ira_loop_pressure = 1; ++ opts->x_flag_inline_functions_called_once = 0; ++ opts->x_flag_ira_algorithm = IRA_ALGORITHM_PRIORITY; ++ opts->x_flag_delayed_branch = 1; ++ opts->x_flag_gcse_las = 1; ++ opts->x_flag_gcse_sm = 1; ++ opts->x_flag_ipa_pta = 1; ++ opts->x_flag_reorder_blocks_and_partition = 1; ++ opts->x_flag_reorder_blocks = 1; ++ opts->x_flag_crypto_accel_aes = 1; ++ opts->x_param_flexible_seg_len = 1; ++} ++ ++/* Reset the optimize option. ++ After checking the model result, this function can ++ reset the more appropriate options. */ ++static void ++reset_machine_option (struct gcc_options *opts) ++{ ++ if (!(opts->x_optimize_maximum) ++ || strstr (opts->x_aarch64_tune_string, "hip09") == NULL) ++ { ++ return; ++ } ++ ++ const char *ai_infer_level = getenv ("AI_INFER_LEVEL"); ++ if (ai_infer_level) ++ { ++ override_optimize_options_1 (opts); ++ if (lang_c_p ()) ++ { ++ override_C_optimize_options (opts); ++ } ++ else if (lang_cpp_p ()) ++ { ++ override_CPP_optimize_options (opts); ++ } ++ else if (lang_GNU_Fortran ()) ++ { ++ override_Fortran_optimize_options (opts); ++ } ++ } ++} ++ ++ + /* STMT_COST is the cost calculated for STMT_INFO, which has cost kind KIND + and which when vectorized would operate on vector type VECTYPE. Add the + cost of any embedded operations. */ +@@ -20089,6 +20217,7 @@ aarch64_override_options_internal (struct gcc_options *opts) + && opts->x_optimize >= aarch64_tune_params.prefetch->default_opt_level) + opts->x_flag_prefetch_loop_arrays = 1; + ++ reset_machine_option (opts); + aarch64_override_options_after_change_1 (opts); + } + +diff --git a/gcc/ipa-hardware-detection.cc b/gcc/ipa-hardware-detection.cc +new file mode 100644 +index 000000000..8085a8c65 +--- /dev/null ++++ b/gcc/ipa-hardware-detection.cc +@@ -0,0 +1,243 @@ ++/* Hardware Detection. ++ Copyright (C) 2024-2024 Free Software Foundation, Inc. ++This file is part of GCC. ++GCC is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the ++Free Software Foundation; either version 3, or (at your option) any ++later version. ++GCC is distributed in the hope that it will be useful, but WITHOUT ++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#include "config.h" ++#include "system.h" ++#include "coretypes.h" ++#include "backend.h" ++#include "target.h" ++#include "tree.h" ++#include "gimple.h" ++#include "tree-pass.h" ++#include "gimple-ssa.h" ++#include "tree-pretty-print.h" ++#include "fold-const.h" ++#include "gimplify.h" ++#include "gimple-iterator.h" ++#include "tree-ssa-loop-manip.h" ++#include "tree-ssa-loop.h" ++#include "ssa.h" ++#include "tree-into-ssa.h" ++#include "cfganal.h" ++#include "cfgloop.h" ++#include "gimple-pretty-print.h" ++#include "tree-cfg.h" ++#include "cgraph.h" ++#include "print-tree.h" ++#include "cfghooks.h" ++#include "gimple-fold.h" ++#include "gimplify-me.h" ++ ++namespace { ++ ++/* Build a binary operation and gimplify it. Emit code before GSI. ++ Return the gimple_val holding the result. */ ++ ++static tree ++gimplify_build2 (gimple_stmt_iterator *gsi, enum tree_code code, ++ tree type, tree a, tree b) ++{ ++ tree ret; ++ ++ ret = fold_build2_loc (gimple_location (gsi_stmt (*gsi)), code, type, a, b); ++ return force_gimple_operand_gsi (gsi, ret, true, NULL, true, ++ GSI_SAME_STMT); ++} ++ ++static basic_block ++create_abort_bb (basic_block last_bb) ++{ ++ basic_block bb = create_empty_bb (last_bb); ++ if (last_bb->loop_father != NULL) ++ { ++ add_bb_to_loop (bb, last_bb->loop_father); ++ loops_state_set (LOOPS_NEED_FIXUP); ++ } ++ gimple_stmt_iterator gsi = gsi_last_bb (bb); ++ tree fn = builtin_decl_implicit (BUILT_IN_ABORT); ++ gimple *g = gimple_build_call (fn, 0); ++ gsi_insert_after (&gsi, g, GSI_NEW_STMT); ++ return bb; ++} ++ ++static basic_block ++create_part_bb (basic_block last_bb, tree part_base) ++{ ++ basic_block bb = create_empty_bb (last_bb); ++ if (last_bb->loop_father != NULL) ++ { ++ add_bb_to_loop (bb, last_bb->loop_father); ++ loops_state_set (LOOPS_NEED_FIXUP); ++ } ++ gimple_stmt_iterator gsi = gsi_last_bb (bb); ++ gsi_insert_after (&gsi, gimple_build_nop (), GSI_NEW_STMT); ++ /* This number is used to efficiently identify the supported part range. */ ++ tree part_cond = gimplify_build2 ( ++ &gsi, PLUS_EXPR, unsigned_type_node, part_base, ++ build_int_cst (unsigned_type_node, 4294963967)); ++ gcond *cond = gimple_build_cond (LE_EXPR, part_cond, ++ build_int_cst (unsigned_type_node, 2), ++ NULL_TREE, NULL_TREE); ++ gimple_set_location (cond, input_location); ++ gsi_insert_before (&gsi, cond, GSI_SAME_STMT); ++ gsi_remove (&gsi, true); ++ return bb; ++} ++ ++static void ++create_detection_bb () ++{ ++ edge old_e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)); ++ basic_block ret_bb = old_e->dest; ++ ++ basic_block detection_bb = create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun)); ++ if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father != NULL) ++ { ++ add_bb_to_loop (detection_bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father); ++ loops_state_set (LOOPS_NEED_FIXUP); ++ } ++ tree cpuid_decl = build_decl (input_location, VAR_DECL, ++ get_identifier ("cpuid"), unsigned_type_node); ++ add_local_decl (cfun, cpuid_decl); ++ ++ gimple_stmt_iterator gsi = gsi_last_bb (detection_bb); ++ vec *outputs = NULL; ++ tree purpose = build_string (strlen ("=r"), "=r"); ++ tree output = build_tree_list ( ++ build_tree_list (NULL_TREE, purpose), cpuid_decl); ++ vec_safe_push (outputs, output); ++ gasm *asm_stmt = gimple_build_asm_vec ( ++ "mrs %0, MIDR_EL1", NULL, outputs, NULL, NULL); ++ gsi_insert_after (&gsi, asm_stmt, GSI_NEW_STMT); ++ gsi_insert_after (&gsi, gimple_build_nop (), GSI_NEW_STMT); ++ ++ tree implementer = gimplify_build2 ( ++ &gsi, RSHIFT_EXPR, unsigned_type_node, cpuid_decl, ++ build_int_cst (unsigned_type_node, 24)); ++ tree part_base = gimplify_build2 ( ++ &gsi, RSHIFT_EXPR, unsigned_type_node, cpuid_decl, ++ build_int_cst (unsigned_type_node, 4)); ++ tree part = gimplify_build2 ( ++ &gsi, BIT_AND_EXPR, unsigned_type_node, part_base, ++ build_int_cst (unsigned_type_node, 4095)); ++ gcond *implementer_cond = gimple_build_cond ( ++ EQ_EXPR, implementer, ++ build_int_cst (unsigned_type_node, 72), ++ NULL_TREE, NULL_TREE); ++ gimple_set_location (implementer_cond, input_location); ++ gsi_insert_before (&gsi, implementer_cond, GSI_SAME_STMT); ++ gsi_remove (&gsi, true); ++ ++ basic_block part_bb = create_part_bb (detection_bb, part); ++ basic_block abort_bb = create_abort_bb (part_bb); ++ ++ remove_edge_raw (old_e); ++ make_single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), ++ detection_bb, EDGE_FALLTHRU); ++ edge etrue = make_edge (detection_bb, part_bb, EDGE_TRUE_VALUE); ++ etrue->probability = profile_probability::likely (); ++ edge efalse = make_edge (detection_bb, abort_bb, EDGE_FALSE_VALUE); ++ efalse->probability = profile_probability::unlikely (); ++ edge part_true = make_edge (part_bb, ret_bb, EDGE_TRUE_VALUE); ++ part_true->probability = profile_probability::likely (); ++ edge part_false = make_edge (part_bb, abort_bb, EDGE_FALSE_VALUE); ++ part_false->probability = profile_probability::unlikely (); ++ make_single_succ_edge (abort_bb, ret_bb, EDGE_FALLTHRU); ++ if (dom_info_available_p (CDI_DOMINATORS)) ++ { ++ set_immediate_dominator (CDI_DOMINATORS, part_bb, detection_bb); ++ set_immediate_dominator (CDI_DOMINATORS, ret_bb, detection_bb); ++ set_immediate_dominator (CDI_DOMINATORS, abort_bb, detection_bb); ++ } ++} ++ ++const pass_data pass_data_ipa_hardware_detection = ++{ ++ SIMPLE_IPA_PASS, ++ "hardware_detection", ++ OPTGROUP_NONE, ++ TV_IPA_HARDWARE_DETECTION, ++ (PROP_cfg | PROP_ssa), ++ 0, ++ 0, ++ 0, ++ (TODO_update_ssa | TODO_verify_all) ++}; ++ ++class pass_ipa_hardware_detection : public simple_ipa_opt_pass ++{ ++public: ++ pass_ipa_hardware_detection (gcc::context *ctxt) ++ : simple_ipa_opt_pass (pass_data_ipa_hardware_detection, ctxt) ++ {} ++ ++ virtual bool gate (function *); ++ virtual unsigned int execute (function *); ++}; // class pass_ipa_hardware_detection ++ ++bool ++pass_ipa_hardware_detection::gate (function *) ++{ ++ const char *ai_infer_level = getenv ("AI_INFER_LEVEL"); ++ return (ai_infer_level ++ && optimize_maximum > 0 ++ /* Only enable in lto or whole_program. */ ++ && (in_lto_p || flag_whole_program)); ++} ++ ++unsigned int ++pass_ipa_hardware_detection::execute (function *) ++{ ++ unsigned int ret = 0; ++ cgraph_node *cnode; ++ FOR_EACH_FUNCTION (cnode) ++ { ++ if (!cnode->real_symbol_p ()) ++ { ++ continue; ++ } ++ if (cnode->definition) ++ { ++ if (!cnode->has_gimple_body_p () || cnode->inlined_to) ++ continue; ++ ++ cnode->get_body (); ++ function *fn = DECL_STRUCT_FUNCTION (cnode->decl); ++ if (!fn) ++ continue; ++ ++ if (DECL_NAME (cnode->decl) ++ && MAIN_NAME_P (DECL_NAME (cnode->decl))) ++ { ++ push_cfun (fn); ++ calculate_dominance_info (CDI_DOMINATORS); ++ ++ create_detection_bb (); ++ ++ cgraph_edge::rebuild_edges (); ++ free_dominance_info (CDI_DOMINATORS); ++ pop_cfun (); ++ } ++ } ++ } ++ return ret; ++} ++} // anon namespace ++ ++simple_ipa_opt_pass * ++make_pass_ipa_hardware_detection (gcc::context *ctxt) ++{ ++ return new pass_ipa_hardware_detection (ctxt); ++} +diff --git a/gcc/opts-common.cc b/gcc/opts-common.cc +index 489a6e02a..12c3f7299 100644 +--- a/gcc/opts-common.cc ++++ b/gcc/opts-common.cc +@@ -992,6 +992,158 @@ opts_concat (const char *first, ...) + return newstr; + } + ++typedef int64_t (*run_ai_model_func)(int, const char **, ++ const char *, int, int64_t *); ++#define PTR_UNION_TYPE(TOTYPE) union { void *_q; TOTYPE _nq; } ++#define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q) ++#define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq) ++ ++static int64_t ++ai_infer_optimization (int argc, const char **argv, ++ const char *mcpu_option, ++ int argc_hw, int64_t *argv_hw) ++{ ++ /* Load dependent AI-framework libraries. */ ++ void *onnxruntime_lib_handle = NULL; ++ const char *onnxruntime_lib_path = "libonnxruntime.so"; ++ ++ onnxruntime_lib_handle = dlopen (onnxruntime_lib_path, ++ RTLD_LAZY | RTLD_GLOBAL); ++ if (!onnxruntime_lib_handle) ++ { ++ return -1; ++ } ++ ++ void *ai4c_lib_handle = NULL; ++ const char *ai4c_lib_path = "libONNXRunner.so"; ++ ++ ai4c_lib_handle = dlopen (ai4c_lib_path, RTLD_LAZY | RTLD_GLOBAL); ++ if (!ai4c_lib_handle) ++ { ++ return -1; ++ } ++ ++ /* Clear any existing error. */ ++ dlerror (); ++ ++ /* Run AI4Compiler model. */ ++ if (ai4c_lib_handle == NULL || onnxruntime_lib_handle == NULL) ++ { ++ return -1; ++ } ++ ++ run_ai_model_func run_ai_model; ++ PTR_UNION_TYPE (run_ai_model_func) run_ai_model_func_union; ++ PTR_UNION_AS_VOID_PTR (run_ai_model_func_union) ++ = dlsym (ai4c_lib_handle, "runONNXModelOptimizer"); ++ run_ai_model = PTR_UNION_AS_CAST_PTR (run_ai_model_func_union); ++ if (!run_ai_model) ++ { ++ dlclose (ai4c_lib_handle); ++ dlclose (onnxruntime_lib_handle); ++ return -1; ++ } ++ int64_t model_pred = (*run_ai_model) (argc, argv, ++ mcpu_option, argc_hw, argv_hw); ++ ++ if (ai4c_lib_handle) ++ dlclose (ai4c_lib_handle); ++ ++ if (onnxruntime_lib_handle) ++ dlclose (onnxruntime_lib_handle); ++ ++ if (model_pred == 1) ++ putenv ("AI_INFER_LEVEL=1"); ++ return model_pred; ++} ++ ++static int ++handle_lto_option (unsigned int lang_mask, ++ unsigned int num_decoded_options, ++ unsigned int argc, ++ const char **argv, ++ struct cl_decoded_option *&opt_array) ++{ ++ int ret = 0; ++ char *lan = ""; ++ char *compiler = xstrdup (argv[0]); ++ lan = strrchr (compiler, '/'); ++ if (lan != NULL) ++ lan ++; ++ else ++ lan = compiler; ++ if (strstr (lan, "gcc") != NULL) ++ { ++ opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array, argc + 2); ++ const char* lto_flag = "-flto=8"; ++ decode_cmdline_option (<o_flag, lang_mask, ++ &opt_array[num_decoded_options]); ++ ret++; ++ const char* ltopartition_flag = "-flto-partition=one"; ++ decode_cmdline_option (<opartition_flag, lang_mask, ++ &opt_array[num_decoded_options + 1]); ++ ret++; ++ } ++ else if (strstr (lan, "g++") != NULL ++ || strstr (lan, "gfortran") != NULL) ++ { ++ opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array, argc + 1); ++ const char* lto_flag = "-flto=8"; ++ decode_cmdline_option (<o_flag, lang_mask, ++ &opt_array[num_decoded_options]); ++ ret++; ++ } ++ if (compiler) ++ free (compiler); ++ return ret; ++} ++ ++static int ++handle_machine_option (unsigned int lang_mask, ++ unsigned int num_decoded_options, ++ unsigned int argc, ++ const char **argv, ++ struct cl_decoded_option *&opt_array) ++{ ++ int ret = 0; ++ bool flag_Om = false; ++ bool flag_hip09 = false; ++ for (unsigned i = 1; i < argc; i ++) ++ { ++ if (strcmp (argv[i], "-Om") == 0) ++ flag_Om = true; ++ if (strstr (argv[i], "mcpu=hip09") != NULL) ++ flag_hip09 = true; ++ } ++ if (!flag_hip09 || !flag_Om) ++ { ++ return ret; ++ } ++ ++ const char *ai_infer_level = getenv ("AI_INFER_LEVEL"); ++ if (ai_infer_level) ++ { ++ return ret; ++ } ++ int argc_hw = 6; ++ int64_t argv_hw[argc_hw] = { ++ global_options.x_param_simultaneous_prefetches, ++ global_options.x_param_l1_cache_size, ++ global_options.x_param_l1_cache_line_size, ++ global_options.x_param_l2_cache_size, ++ global_options.x_param_prefetch_latency, ++ global_options.x_param_ipa_prefetch_distance_factor}; ++ int64_t output_pred = ai_infer_optimization ( ++ argc, argv, "hip09", argc_hw, argv_hw); ++ if (output_pred != 1) ++ { ++ return ret; ++ } ++ ++ return handle_lto_option (lang_mask, num_decoded_options, ++ argc, argv, opt_array); ++} ++ + /* Decode command-line options (ARGC and ARGV being the arguments of + main) into an array, setting *DECODED_OPTIONS to a pointer to that + array and *DECODED_OPTIONS_COUNT to the number of entries in the +@@ -1090,6 +1242,9 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv, + num_decoded_options++; + } + ++ num_decoded_options += handle_machine_option (lang_mask, num_decoded_options, ++ argc, argv, opt_array); ++ + *decoded_options = opt_array; + *decoded_options_count = num_decoded_options; + prune_options (decoded_options, decoded_options_count, lang_mask); +diff --git a/gcc/opts.cc b/gcc/opts.cc +index e34e5ee8e..d97f6079f 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -780,6 +780,14 @@ default_options_optimization (struct gcc_options *opts, + opts->x_optimize_debug = 1; + break; + ++ case OPT_Om: ++ /* -Om adds flags to -O3. */ ++ opts->x_optimize_size = 0; ++ opts->x_optimize = 3; ++ opts->x_optimize_maximum = true; ++ opts->x_optimize_debug = 0; ++ break; ++ + case OPT_fopenacc: + if (opt->value) + openacc_mode = true; +@@ -2733,6 +2741,8 @@ common_handle_option (struct gcc_options *opts, + &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT); + break; + ++ case OPT_Om: ++ break; + case OPT_O: + case OPT_Os: + case OPT_Ofast: +diff --git a/gcc/passes.def b/gcc/passes.def +index 8797f166f..690d344c0 100644 +--- a/gcc/passes.def ++++ b/gcc/passes.def +@@ -179,6 +179,7 @@ along with GCC; see the file COPYING3. If not see + passes are executed after partitioning and thus see just parts of the + compiled unit. */ + INSERT_PASSES_AFTER (all_late_ipa_passes) ++ NEXT_PASS (pass_ipa_hardware_detection); + NEXT_PASS (pass_ipa_pta); + /* FIXME: this should be a normal IP pass. */ + NEXT_PASS (pass_ipa_struct_reorg); +diff --git a/gcc/timevar.def b/gcc/timevar.def +index 8e7510eb3..bd8c9a4f7 100644 +--- a/gcc/timevar.def ++++ b/gcc/timevar.def +@@ -81,6 +81,7 @@ DEFTIMEVAR (TV_IPA_CONSTANT_PROP , "ipa cp") + DEFTIMEVAR (TV_IPA_INLINING , "ipa inlining heuristics") + DEFTIMEVAR (TV_IPA_FNSPLIT , "ipa function splitting") + DEFTIMEVAR (TV_IPA_COMDATS , "ipa comdats") ++DEFTIMEVAR (TV_IPA_HARDWARE_DETECTION, "ipa detection") + DEFTIMEVAR (TV_IPA_PREFETCH , "ipa prefetch") + DEFTIMEVAR (TV_IPA_STRUCT_REORG , "ipa struct reorg optimization") + DEFTIMEVAR (TV_IPA_OPT , "ipa various optimizations") +diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h +index 1c983ef71..ee873f0b2 100644 +--- a/gcc/tree-pass.h ++++ b/gcc/tree-pass.h +@@ -528,6 +528,8 @@ extern ipa_opt_pass_d *make_pass_ipa_icp (gcc::context *ctxt); + extern ipa_opt_pass_d *make_pass_ipa_odr (gcc::context *ctxt); + extern ipa_opt_pass_d *make_pass_ipa_reference (gcc::context *ctxt); + extern ipa_opt_pass_d *make_pass_ipa_pure_const (gcc::context *ctxt); ++extern simple_ipa_opt_pass *make_pass_ipa_hardware_detection (gcc::context * ++ ctxt); + extern simple_ipa_opt_pass *make_pass_ipa_prefetch (gcc::context *ctxt); + extern simple_ipa_opt_pass *make_pass_ipa_struct_reorg (gcc::context *ctxt); + extern simple_ipa_opt_pass *make_pass_ipa_pta (gcc::context *ctxt); diff --git a/0287-Add-dynamic-memory-access-checks.patch b/0287-Add-dynamic-memory-access-checks.patch new file mode 100644 index 0000000000000000000000000000000000000000..e23d8f64c0d87f6c3d65f9d5ead4bdace2fdca5d --- /dev/null +++ b/0287-Add-dynamic-memory-access-checks.patch @@ -0,0 +1,774 @@ +From 08fb60d0a0707af4004b20358f4a921e4ae6cca6 Mon Sep 17 00:00:00 2001 +From: Diachkov Ilia +Date: Thu, 22 Aug 2024 15:23:36 +0800 +Subject: [PATCH 156/157] Add dynamic memory access checks + +Signed-off-by: Diachkov Ilia +--- + gcc/ipa-prefetch.cc | 622 +++++++++++++++++++++++++++++++++++++------- + gcc/params.opt | 4 + + 2 files changed, 525 insertions(+), 101 deletions(-) + +diff --git a/gcc/ipa-prefetch.cc b/gcc/ipa-prefetch.cc +index 94290ea9c..b000d4d75 100644 +--- a/gcc/ipa-prefetch.cc ++++ b/gcc/ipa-prefetch.cc +@@ -368,6 +368,7 @@ typedef std::map memref_tree_map; + typedef std::set stmt_set; + typedef std::set tree_set; + typedef std::map tree_map; ++typedef std::map tree_poly_offset_map; + + tree_memref_map *tm_map; + funct_mrs_map *fmrs_map; +@@ -710,6 +711,20 @@ get_mem_ref_address_ssa_name (tree mem, tree base) + return NULL_TREE; + } + ++static void ++dump_base_addr (tree base_addr) ++{ ++ if (base_addr) ++ { ++ fprintf (dump_file, "Base addr (%s): ", ++ get_tree_code_name (TREE_CODE (base_addr))); ++ print_generic_expr (dump_file, base_addr); ++ } ++ else ++ fprintf (dump_file, "Base addr (%s): ", "null"); ++ fprintf (dump_file, "\n"); ++} ++ + static void + analyse_mem_ref (gimple *stmt, tree mem, memref_t* mr) + { +@@ -736,14 +751,7 @@ analyse_mem_ref (gimple *stmt, tree mem, memref_t* mr) + { + tree base_addr = get_mem_ref_address_ssa_name (mem, base); + if (dump_file) +- { +- fprintf (dump_file, "Base addr (%s): ", +- base_addr ? get_tree_code_name (TREE_CODE (base_addr)) +- : "null"); +- if (base_addr) +- print_generic_expr (dump_file, base_addr); +- fprintf (dump_file, "\n"); +- } ++ dump_base_addr (base_addr); + if (base_addr) + { + mr->base = analyse_addr_eval (base_addr, mr); +@@ -1187,7 +1195,7 @@ reduce_memref_set (memref_set *set, vec &vec) + } + + static void +-find_nearest_common_dominator (memref_t *mr, basic_block &dom) ++find_nearest_common_post_dominator (memref_t *mr, basic_block &dom) + { + for (unsigned int i = 0; i < mr->stmts.length (); i++) + { +@@ -1196,7 +1204,7 @@ find_nearest_common_dominator (memref_t *mr, basic_block &dom) + if (dom == bb) + continue; + if (dom) +- dom = nearest_common_dominator (CDI_DOMINATORS, dom, bb); ++ dom = nearest_common_dominator (CDI_POST_DOMINATORS, dom, bb); + else + dom = bb; + } +@@ -1495,10 +1503,13 @@ gimple_copy_and_remap (gimple *stmt) + + static gimple * + gimple_copy_and_remap_memref_stmts (memref_t *mr, gimple_seq &stmts, +- int last_idx, stmt_set &processed) ++ int first_idx, int last_idx, ++ stmt_set &processed) + { + gimple *last_stmt = NULL; +- for (int i = mr->stmts.length () - 1; i >= last_idx ; i--) ++ if (first_idx == 0) ++ first_idx = mr->stmts.length () - 1; ++ for (int i = first_idx; i >= last_idx; i--) + { + if (processed.count (mr->stmts[i])) + continue; +@@ -1515,6 +1526,436 @@ gimple_copy_and_remap_memref_stmts (memref_t *mr, gimple_seq &stmts, + return last_stmt; + } + ++/* Check if prefetch insertion may be always unsafe in this case. For now ++ reject cases with access to arrays with no domain or with no elements. */ ++ ++static bool ++check_prefetch_safety (vec &mrs, memref_t *cmr) ++{ ++ for (unsigned int i = 0; i < mrs.length (); i++) ++ { ++ memref_t *mr = mrs[i]; ++ if (mr == cmr || mr->used_mrs.empty ()) ++ continue; ++ bool is_store; ++ tree *mem = simple_mem_ref_in_stmt (mr->stmts[0], &is_store); ++ if (mem == NULL || TREE_CODE (*mem) != ARRAY_REF) ++ continue; ++ tree array = TREE_OPERAND (*mem, 0); ++ tree atype = TREE_TYPE (array); ++ gcc_assert (atype); ++ tree domain = TYPE_DOMAIN (atype); ++ if (!domain || !tree_fits_uhwi_p (TYPE_MIN_VALUE (domain)) ++ || !tree_fits_uhwi_p (TYPE_MAX_VALUE (domain))) ++ { ++ if (dump_file) ++ { ++ fprintf (dump_file, "Unsupported array type: "); ++ print_generic_expr (dump_file, atype); ++ fprintf (dump_file, "\n"); ++ } ++ return false; ++ } ++ unsigned HOST_WIDE_INT min_val = tree_to_uhwi (TYPE_MIN_VALUE (domain)); ++ unsigned HOST_WIDE_INT max_val = tree_to_uhwi (TYPE_MAX_VALUE (domain)); ++ if (min_val == 0 && max_val == 0) ++ { ++ if (dump_file) ++ { ++ fprintf (dump_file, "Unsupported array type's bounds: "); ++ print_generic_expr (dump_file, atype); ++ fprintf (dump_file, "\n"); ++ } ++ return false; ++ } ++ } ++ return true; ++} ++ ++/* Collect base addresses which we need to check. */ ++ ++static void ++collect_base_addresses (vec &used_mr_vec, HOST_WIDE_INT dist_val, ++ memref_t *comp_mr, tree_poly_offset_map &offset_map) ++{ ++ if (dump_file) ++ fprintf (dump_file, "Collect base addresses which we need to check.\n"); ++ for (unsigned int i = 0; i < used_mr_vec.length (); i++) ++ { ++ memref_t *mr = used_mr_vec[i]; ++ if (mr == comp_mr || mr->used_mrs.empty ()) ++ continue; ++ bool is_store; ++ tree *mem = simple_mem_ref_in_stmt (mr->stmts[0], &is_store); ++ if (mem == NULL || TREE_CODE (*mem) != MEM_REF) ++ continue; ++ tree base = get_base_address (*mem); ++ tree base_addr = get_mem_ref_address_ssa_name (*mem, base); ++ if (!base_addr) ++ continue; ++ if (dump_file) ++ { ++ dump_base_addr (base_addr); ++ if (base) ++ { ++ fprintf (dump_file, "Base:"); ++ print_generic_expr (dump_file, base); ++ fprintf (dump_file, "\n"); ++ } ++ } ++ if (!TREE_OPERAND (base, 1)) ++ continue; ++ poly_offset_int curr_offset = mem_ref_offset (base); ++ poly_offset_int saved_offset = 0; ++ if (offset_map.count (base_addr)) ++ { ++ saved_offset = offset_map[base_addr]; ++ if ((dist_val > 0 && known_gt (curr_offset, saved_offset)) ++ || (dist_val < 0 && known_lt (curr_offset, saved_offset))) ++ offset_map[base_addr] = curr_offset; ++ else if (dump_file) ++ fprintf (dump_file, "Off: step=%ld gt=%d lt=%d\n", dist_val, ++ known_gt (curr_offset, saved_offset), ++ known_lt (curr_offset, saved_offset)); ++ } ++ else ++ offset_map[base_addr] = curr_offset; ++ } ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "Final list of base addresses:\n"); ++ for (tree_poly_offset_map::iterator it1 = offset_map.begin (); ++ it1 != offset_map.end (); ++it1) ++ { ++ tree base_addr = it1->first; ++ poly_offset_int off = it1->second; ++ fprintf (dump_file, "Base:"); ++ print_generic_expr (dump_file, base_addr); ++ HOST_WIDE_INT val = estimated_poly_value (off.force_shwi (), ++ POLY_VALUE_LIKELY); ++ fprintf (dump_file, "\nOff: %ld\n", val); ++ } ++ fprintf (dump_file, "Finish collecting base addresses.\n"); ++ } ++} ++ ++/* Return true if we need page check to access memory at this address. */ ++ ++static bool ++need_page_check (tree base_addr, tree_set &checked_base_addrs) ++{ ++ if (dump_file) ++ dump_base_addr (base_addr); ++ if (base_addr == NULL) ++ { ++ if (dump_file) ++ fprintf (dump_file, "Base address not found\n"); ++ return false; ++ } ++ if (checked_base_addrs.count (base_addr)) ++ { ++ if (dump_file) ++ fprintf (dump_file, "Base address is already checked\n"); ++ return false; ++ } ++ return true; ++} ++ ++/* Insert instructions to check the original address and newly evaluated ++ adress for prefetch correspond the same page. */ ++ ++static gimple * ++insert_page_check (tree addr, tree_poly_offset_map &offset_map, ++ gimple_seq &stmts) ++{ ++ poly_offset_int offset = 0; ++ if (offset_map.count (addr)) ++ offset = offset_map[addr]; ++ tree addr_type = TREE_TYPE (addr); ++ tree utype = unsigned_type_for (addr_type); ++ tree new_addr = build_int_cst (addr_type, 0); ++ if (decl_map->count (addr)) ++ new_addr = (*decl_map)[addr]; ++ tree t1 = make_ssa_name (utype); ++ tree t2 = make_ssa_name (utype); ++ unsigned long long pmask = ~(param_ipa_prefetch_pagesize - 1); ++ tree pmask_cst = build_int_cst (utype, pmask); ++ tree off_tree = wide_int_to_tree (sizetype, offset); ++ gcc_assert (TREE_CODE (addr_type) == POINTER_TYPE); ++ tree addr_with_offset = gimple_build (&stmts, POINTER_PLUS_EXPR, ++ addr_type, addr, off_tree); ++ tree conv_addr = make_ssa_name (utype); ++ tree conv_new_addr = make_ssa_name (utype); ++ gimple *conv1 = gimple_build_assign (conv_addr, ++ fold_convert (utype, addr_with_offset)); ++ gimple *conv2 = gimple_build_assign (conv_new_addr, ++ fold_convert (utype, new_addr)); ++ gimple *paddr = gimple_build_assign (t1, BIT_AND_EXPR, ++ conv_addr, pmask_cst); ++ gimple *new_paddr = gimple_build_assign (t2, BIT_AND_EXPR, ++ conv_new_addr, pmask_cst); ++ gcond *cond = gimple_build_cond (EQ_EXPR, t1, t2, NULL, NULL); ++ gimple_seq_add_stmt (&stmts, conv1); ++ gimple_seq_add_stmt (&stmts, paddr); ++ gimple_seq_add_stmt (&stmts, conv2); ++ gimple_seq_add_stmt (&stmts, new_paddr); ++ gimple_seq_add_stmt (&stmts, cond); ++ return cond; ++} ++ ++/* Check if this array access needs dynamic address verification. Support only ++ arrays with 1-d indexing. */ ++ ++static bool ++need_array_index_check (tree mem) ++{ ++ /* Check pattern: t1 = (type) t0; ld/st array[t1]. If any index of type (t0) ++ does not go beyond the bounds of the array, we don't need the check. */ ++ tree array = TREE_OPERAND (mem, 0); ++ tree atype = TREE_TYPE (array); ++ tree index = TREE_OPERAND (mem, 1); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "Array ind: "); ++ print_generic_expr (dump_file, index); ++ fprintf (dump_file, "\nMem: "); ++ print_generic_expr (dump_file, array); ++ fprintf (dump_file, "\nInd type: "); ++ print_generic_expr (dump_file, TREE_TYPE (index)); ++ fprintf (dump_file, "\nMem type: "); ++ print_generic_expr (dump_file, atype); ++ fprintf (dump_file, "\n"); ++ } ++ tree domain = TYPE_DOMAIN (atype); ++ if (!domain || !tree_fits_uhwi_p (TYPE_MIN_VALUE (domain)) ++ || !tree_fits_uhwi_p (TYPE_MAX_VALUE (domain))) ++ { ++ if (dump_file) ++ fprintf (dump_file, "Unsupported array type domain.\n"); ++ return true; ++ } ++ unsigned HOST_WIDE_INT min_val = tree_to_uhwi (TYPE_MIN_VALUE (domain)); ++ unsigned HOST_WIDE_INT max_val = tree_to_uhwi (TYPE_MAX_VALUE (domain)); ++ if (dump_file) ++ fprintf (dump_file, "Array bounds (%ld, %ld)\n", min_val, max_val); ++ if (TREE_CODE (index) != SSA_NAME) ++ return true; ++ ++ gimple *stmt = SSA_NAME_DEF_STMT (index); ++ if (!is_gimple_assign (stmt)) ++ { ++ if (dump_file) ++ { ++ fprintf (dump_file, "Is not assign, stop analysis: "); ++ print_gimple_stmt (dump_file, stmt, 3, TDF_DETAILS); ++ } ++ return true; ++ } ++ tree *lhs = gimple_assign_lhs_ptr (stmt); ++ tree *rhs = gimple_assign_rhs1_ptr (stmt); ++ tree lhs_type = TREE_TYPE (*lhs); ++ tree rhs_type = TREE_TYPE (*rhs); ++ tree ind_type = (TYPE_PRECISION (lhs_type) < TYPE_PRECISION (rhs_type)) ++ ? lhs_type : rhs_type; ++ if (!ind_type || !tree_fits_uhwi_p (TYPE_MIN_VALUE (ind_type)) ++ || !tree_fits_uhwi_p (TYPE_MAX_VALUE (ind_type))) ++ { ++ if (dump_file) ++ fprintf (dump_file, "Unsupported index type.\n"); ++ return true; ++ } ++ int prec = tree_to_uhwi (TYPE_SIZE (ind_type)); ++ unsigned HOST_WIDE_INT t_max_val = tree_to_uhwi (TYPE_MAX_VALUE (ind_type)); ++ unsigned HOST_WIDE_INT t_min_val = tree_to_uhwi (TYPE_MIN_VALUE (ind_type)); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "Index type (%d, %ld, %ld): ", prec, ++ t_min_val, t_max_val); ++ print_generic_expr (dump_file, ind_type); ++ fprintf (dump_file, "\n"); ++ } ++ return !((t_max_val <= max_val) && (t_min_val >= min_val)); ++} ++ ++/* Insert instructions to check the new index is within the array bounds. */ ++ ++static gimple * ++insert_index_check (tree mem, gimple_seq &stmts) ++{ ++ if (dump_file) ++ fprintf (dump_file, "Insert array index check\n"); ++ tree atype = TREE_TYPE (TREE_OPERAND (mem, 0)); ++ tree ind = TREE_OPERAND (mem, 1); ++ if (decl_map->count (ind)) ++ ind = (*decl_map)[ind]; ++ tree domain = TYPE_DOMAIN (atype); ++ gcc_assert (domain && tree_fits_uhwi_p (TYPE_MIN_VALUE (domain)) ++ && tree_fits_uhwi_p (TYPE_MAX_VALUE (domain))); ++ ++ tree ind_min_val = TYPE_MIN_VALUE (domain); ++ tree ind_max_val = TYPE_MAX_VALUE (domain); ++ tree t1 = make_ssa_name (boolean_type_node); ++ tree t2 = make_ssa_name (boolean_type_node); ++ tree t3 = make_ssa_name (boolean_type_node); ++ t1 = fold_build2 (LE_EXPR, boolean_type_node, ind, ind_max_val); ++ t2 = fold_build2 (GE_EXPR, boolean_type_node, ind, ind_min_val); ++ t3 = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node, t1, t2); ++ gcond *cond = gimple_build_cond (EQ_EXPR, t3, boolean_true_node, NULL, NULL); ++ gimple_seq_add_stmt (&stmts, cond); ++ return cond; ++} ++ ++/* Insert safety checks for memory access stmts newly created to evaluate ++ prefetch addresses. */ ++ ++static void ++process_used_mr (memref_t *mr, tree_poly_offset_map &offset_map, ++ tree_set &checked_base_addrs, gimple_seq &stmts, ++ vec &bbends) ++{ ++ bool is_store; ++ tree *mem = simple_mem_ref_in_stmt (mr->stmts[0], &is_store); ++ if (mem == NULL) ++ return; ++ if (dump_file) ++ { ++ fprintf (dump_file, "MR (%d) maybe need to insert address check: ", ++ mr->mr_id); ++ print_generic_expr (dump_file, *mem); ++ fprintf (dump_file, "\n"); ++ } ++ gimple *bbend = NULL; ++ if (TREE_CODE (*mem) == MEM_REF) ++ { ++ tree base = get_base_address (*mem); ++ tree base_addr = get_mem_ref_address_ssa_name (*mem, base); ++ if (!need_page_check (base_addr, checked_base_addrs)) ++ return; ++ bbend = insert_page_check (base_addr, offset_map, stmts); ++ checked_base_addrs.insert (base_addr); ++ } ++ else if (TREE_CODE (*mem) == ARRAY_REF && need_array_index_check (*mem)) ++ bbend = insert_index_check (*mem, stmts); ++ if (bbend) ++ bbends.safe_push (bbend); ++} ++ ++/* Create new variables and insert new stmts to evaluate prefetch addresses. */ ++ ++static void ++create_stmts_for_used_mrs (vec &used_mr_vec, vec &bbends, ++ gimple_seq &stmts, stmt_set &processed_stmts, ++ HOST_WIDE_INT dist_val, memref_t *comp_mr) ++{ ++ tree_poly_offset_map offset_map; ++ collect_base_addresses (used_mr_vec, dist_val, comp_mr, offset_map); ++ ++ /* Insert stmts to evaluate prefetch addresses. */ ++ tree_set checked_base_addrs; ++ for (unsigned int i = 0; i < used_mr_vec.length (); i++) ++ { ++ memref_t *mr = used_mr_vec[i]; ++ if (mr == comp_mr) ++ continue; ++ gimple *last_stmt = gimple_copy_and_remap_memref_stmts (mr, stmts, 0, 1, ++ processed_stmts); ++ if (last_stmt && dump_file) ++ { ++ fprintf (dump_file, "MR (%d) new mem: ", mr->mr_id); ++ print_generic_expr (dump_file, gimple_assign_lhs (last_stmt)); ++ fprintf (dump_file, "\n"); ++ } ++ if (!mr->used_mrs.empty ()) ++ process_used_mr (mr, offset_map, checked_base_addrs, stmts, bbends); ++ last_stmt = gimple_copy_and_remap_memref_stmts (mr, stmts, 0, 0, ++ processed_stmts); ++ } ++} ++ ++/* Insert prefetch instructions. */ ++ ++static void ++insert_prefetch_stmts (vec &pcalls, gimple_seq &stmts, ++ gimple *&last_pref, vec &vmrs, ++ stmt_set &processed_stmts) ++{ ++ if (dump_file) ++ fprintf (dump_file, "Evaluate addresses and insert prefetch insns.\n"); ++ ++ tree local; ++ switch (param_ipa_prefetch_locality) ++ { ++ case 0: ++ local = integer_zero_node; ++ break; ++ case 1: ++ local = integer_one_node; ++ break; ++ case 2: ++ local = build_int_cst (integer_type_node, 2); ++ break; ++ default: ++ case 3: ++ local = integer_three_node; ++ break; ++ } ++ tree_set prefetched_addrs; ++ for (unsigned int i = 0; i < vmrs.length (); i++) ++ { ++ memref_t *mr = vmrs[i]; ++ /* Don't need to copy the last stmt, since we insert prefetch insn ++ instead of it. */ ++ gimple_copy_and_remap_memref_stmts (mr, stmts, 0, 1, processed_stmts); ++ gimple *last_stmt = mr->stmts[0]; ++ gcc_assert (last_stmt); ++ ++ tree old_addr = get_mem_ref_address_ssa_name (mr->mem, NULL_TREE); ++ tree new_addr = old_addr; ++ if (decl_map->count (old_addr)) ++ new_addr = (*decl_map)[old_addr]; ++ if (prefetched_addrs.count (new_addr)) ++ continue; ++ /* Insert prefetch intrinsic call. */ ++ tree write_p = mr->is_store ? integer_one_node : integer_zero_node; ++ last_pref = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH), ++ 3, new_addr, write_p, local); ++ pcalls.safe_push (last_pref); ++ gimple_seq_add_stmt (&stmts, last_pref); ++ prefetched_addrs.insert (new_addr); ++ ++ if (dump_file) ++ { ++ fprintf (dump_file, "Insert %d prefetch stmt:\n", i); ++ print_gimple_stmt (dump_file, last_pref, 0); ++ } ++ } ++} ++ ++/* Split bbs after condition stmts and fix control flow graph. */ ++ ++static void ++correct_cfg (vec &bbends, gimple *last_pref, basic_block &dom_bb) ++{ ++ edge e_last = split_block (dom_bb, last_pref); ++ if (!bbends.length () || last_pref == NULL) ++ return; ++ for (int i = bbends.length () - 1; i >= 0; i--) ++ { ++ gimple *bbend = bbends[i]; ++ if (dump_file) ++ { ++ fprintf (dump_file, "Split dom_bb after condition stmts:\n"); ++ print_gimple_stmt (dump_file, bbend, 0); ++ } ++ basic_block last_bb = e_last->dest; ++ edge e = split_block (dom_bb, bbend); ++ e->flags &= ~EDGE_FALLTHRU; ++ e->flags |= EDGE_TRUE_VALUE; ++ edge e_false = make_edge (dom_bb, last_bb, EDGE_FALSE_VALUE); ++ e_false->probability = profile_probability::never (); ++ } ++} ++ + static void + create_cgraph_edge (cgraph_node *n, gimple *stmt) + { +@@ -1529,6 +1970,17 @@ create_cgraph_edge (cgraph_node *n, gimple *stmt) + ipa_call_summaries->get_create (e); + } + ++/* Modify cgraph inserting calls to prefetch intrinsics. */ ++ ++static void ++modify_ipa_info (cgraph_node *n, vec &pcalls) ++{ ++ for (unsigned i = 0; i < pcalls.length (); i++) ++ create_cgraph_edge (n, pcalls[i]); ++ ipa_update_overall_fn_summary (n); ++ renumber_gimple_stmt_uids (DECL_STRUCT_FUNCTION (n->decl)); ++} ++ + /* Insert prefetch intrinsics in this function, return nonzero on success. */ + + static int +@@ -1607,6 +2059,18 @@ optimize_function (cgraph_node *n, function *fn) + return 0; + } + ++ vec used_mr_vec = vNULL; ++ for (memref_set::const_iterator it = used_mrs.begin (); ++ it != used_mrs.end (); it++) ++ used_mr_vec.safe_push (*it); ++ used_mr_vec.qsort (memref_id_cmp); ++ if (!check_prefetch_safety (used_mr_vec, comp_mr)) ++ { ++ if (dump_file) ++ fprintf (dump_file, "Prefetching may be unsafe. Skip the case.\n"); ++ return 0; ++ } ++ + /* Filter out memrefs with the same memory references. + TODO: maybe do the same with used mrs. */ + vec vmrs = vNULL; +@@ -1616,18 +2080,18 @@ optimize_function (cgraph_node *n, function *fn) + /* TODO: maybe it is useful to process also used_mrs. */ + basic_block dom_bb = NULL; + for (unsigned int i = 0; i < vmrs.length (); i++) +- find_nearest_common_dominator (vmrs[i], dom_bb); ++ find_nearest_common_post_dominator (vmrs[i], dom_bb); + + if (!dom_bb) + { + if (dump_file) +- fprintf (dump_file, "Dominator bb for MRs is not found. " ++ fprintf (dump_file, "Post dominator bb for MRs is not found. " + "Skip the case.\n"); + return 0; + } + else if (dump_file) + { +- fprintf (dump_file, "Dominator bb %d for MRs:\n", dom_bb->index); ++ fprintf (dump_file, "Post dominator bb %d for MRs:\n", dom_bb->index); + gimple_dump_bb (dump_file, dom_bb, 0, dump_flags); + fprintf (dump_file, "\n"); + } +@@ -1636,19 +2100,33 @@ optimize_function (cgraph_node *n, function *fn) + gimple *last_used = NULL; + for (gimple_stmt_iterator si = gsi_last_bb (dom_bb); !gsi_end_p (si); + gsi_prev (&si)) +- if (comp_mr->stmts[0] == gsi_stmt (si)) +- { +- last_used = gsi_stmt (si); +- if (dump_file) ++ { ++ bool found = false; ++ for (unsigned int i = 0; i < vmrs.length (); i++) ++ /* TODO: take into account only those MRs that should be ++ checked memory. */ ++ if (vmrs[i]->stmts[0] == gsi_stmt (si)) + { +- fprintf (dump_file, "Last used stmt in dominator bb:\n"); +- print_gimple_stmt (dump_file, last_used, 0); ++ found = true; ++ break; + } +- break; +- } ++ if (found || comp_mr->stmts[0] == gsi_stmt (si)) ++ { ++ last_used = gsi_stmt (si); ++ if (dump_file) ++ { ++ fprintf (dump_file, "Last used stmt in post dominator bb:\n"); ++ print_gimple_stmt (dump_file, last_used, 0); ++ } ++ break; ++ } ++ } + +- split_block (dom_bb, last_used); +- gimple_stmt_iterator gsi = gsi_last_bb (dom_bb); ++ gimple_stmt_iterator gsi; ++ if (last_used) ++ gsi = gsi_for_stmt (last_used); ++ else ++ gsi = gsi_last_bb (dom_bb); + + /* Create new inc var. Insert new_var = old_var + step * factor. */ + decl_map = new tree_map; +@@ -1660,7 +2138,7 @@ optimize_function (cgraph_node *n, function *fn) + stmt_set processed_stmts; + if (!dominated_by_p (CDI_DOMINATORS, dom_bb, gimple_bb (comp_mr->stmts[0]))) + { +- gimple *tmp = gimple_copy_and_remap_memref_stmts (comp_mr, stmts, 0, ++ gimple *tmp = gimple_copy_and_remap_memref_stmts (comp_mr, stmts, 0, 0, + processed_stmts); + inc_var = gimple_assign_lhs (tmp); + } +@@ -1683,86 +2161,26 @@ optimize_function (cgraph_node *n, function *fn) + fprintf (dump_file, "\n"); + } + +- /* Create other new vars. Insert new stmts. */ +- vec used_mr_vec = vNULL; +- for (memref_set::const_iterator it = used_mrs.begin (); +- it != used_mrs.end (); it++) +- used_mr_vec.safe_push (*it); +- used_mr_vec.qsort (memref_id_cmp); +- +- for (unsigned int j = 0; j < used_mr_vec.length (); j++) +- { +- memref_t *mr = used_mr_vec[j]; +- if (mr == comp_mr) +- continue; +- gimple *last_stmt = gimple_copy_and_remap_memref_stmts (mr, stmts, 0, +- processed_stmts); +- gcc_assert (last_stmt); +- if (dump_file) +- { +- fprintf (dump_file, "MR (%d) new mem: ", mr->mr_id); +- print_generic_expr (dump_file, gimple_assign_lhs (last_stmt)); +- fprintf (dump_file, "\n"); +- } +- } +- /* On new load check page fault. */ +- /* Insert prefetch instructions. */ +- if (dump_file) +- fprintf (dump_file, "Evaluate addresses and insert prefetch insn.\n"); ++ vec bbends = vNULL; ++ create_stmts_for_used_mrs (used_mr_vec, bbends, stmts, processed_stmts, ++ dist_val, comp_mr); + + vec pcalls = vNULL; +- tree local; +- switch (param_ipa_prefetch_locality) +- { +- case 0: +- local = integer_zero_node; +- break; +- case 1: +- local = integer_one_node; +- break; +- case 2: +- local = build_int_cst (integer_type_node, 2); +- break; +- default: +- case 3: +- local = integer_three_node; +- break; +- } +- tree_set prefetched_addrs; +- for (unsigned int j = 0; j < vmrs.length (); j++) +- { +- memref_t *mr = vmrs[j]; +- /* Don't need to copy the last stmt, since we insert prefetch insn +- instead of it. */ +- gimple_copy_and_remap_memref_stmts (mr, stmts, 1, processed_stmts); +- gimple *last_stmt = mr->stmts[0]; +- gcc_assert (last_stmt); +- tree write_p = mr->is_store ? integer_one_node : integer_zero_node; +- tree addr = get_mem_ref_address_ssa_name (mr->mem, NULL_TREE); +- if (decl_map->count (addr)) +- addr = (*decl_map)[addr]; +- if (prefetched_addrs.count (addr)) +- continue; +- last_stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH), +- 3, addr, write_p, local); +- pcalls.safe_push (last_stmt); +- gimple_seq_add_stmt (&stmts, last_stmt); +- prefetched_addrs.insert (addr); +- if (dump_file) +- { +- fprintf (dump_file, "Insert %d prefetch stmt:\n", j); +- print_gimple_stmt (dump_file, last_stmt, 0); +- } +- } +- ++ gimple *last_pref = NULL; ++ insert_prefetch_stmts (pcalls, stmts, last_pref, vmrs, processed_stmts); + gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++ ++ correct_cfg (bbends, last_pref, dom_bb); ++ + delete decl_map; + +- /* Modify cgraph inserting calls to prefetch intrinsics. */ +- for (unsigned i = 0; i < pcalls.length (); i++) +- create_cgraph_edge (n, pcalls[i]); +- ipa_update_overall_fn_summary (n); +- renumber_gimple_stmt_uids (DECL_STRUCT_FUNCTION (n->decl)); ++ modify_ipa_info (n, pcalls); ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "After optimization:\n"); ++ dump_function_to_file (cfun->decl, dump_file, (dump_flags_t)0); ++ } + + return 1; + } +@@ -1781,8 +2199,10 @@ insert_prefetch () + fprintf (dump_file, "Optimize function %s\n", n->dump_name ()); + push_cfun (DECL_STRUCT_FUNCTION (n->decl)); + calculate_dominance_info (CDI_DOMINATORS); ++ calculate_dominance_info (CDI_POST_DOMINATORS); + res |= optimize_function (n, fn); + free_dominance_info (CDI_DOMINATORS); ++ free_dominance_info (CDI_POST_DOMINATORS); + pop_cfun (); + } + return res; +diff --git a/gcc/params.opt b/gcc/params.opt +index 747d0f829..fc700ab79 100644 +--- a/gcc/params.opt ++++ b/gcc/params.opt +@@ -317,6 +317,10 @@ The factor represents the number of inductive variable incrementations to evalua + Common Joined UInteger Var(param_ipa_prefetch_locality) Init(3) IntegerRange(0, 3) Param Optimization + The flag represents temporal locality value between 0 and 3, the higher value means the higher temporal locality in the data. + ++-param=ipa-prefetch-pagesize= ++Common Joined UInteger Var(param_ipa_prefetch_pagesize) Init(4096) Param Optimization ++The flag represents current pagesize for runtime checks of memory access addresses. ++ + -param=ira-loop-reserved-regs= + Common Joined UInteger Var(param_ira_loop_reserved_regs) Init(2) Param Optimization + The number of registers in each class kept unused by loop invariant motion. +-- +2.33.0 + diff --git a/0288-Enable-macro-use-commandline.patch b/0288-Enable-macro-use-commandline.patch new file mode 100644 index 0000000000000000000000000000000000000000..cafe01b5c6851ce46b31cb2e97b778be3ddb029e --- /dev/null +++ b/0288-Enable-macro-use-commandline.patch @@ -0,0 +1,207 @@ +From 7a578a8725f8fd7d92fcbbac14841ea7e8d0870f Mon Sep 17 00:00:00 2001 +From: zhangxiaohua +Date: Sun, 25 Aug 2024 23:08:53 +0800 +Subject: [PATCH 157/157] Enable macro-use-commandline + +Signed-off-by: zhangxiaohua +--- + gcc/c-family/c-opts.cc | 4 +++ + gcc/c-family/c.opt | 4 +++ + gcc/doc/cppopts.texi | 4 +++ + gcc/doc/invoke.texi | 1 + + .../gcc.dg/cpp/macro-use-cmdline-1.c | 26 ++++++++++++++ + .../gcc.dg/cpp/macro-use-cmdline-2.c | 34 +++++++++++++++++++ + libcpp/include/cpplib.h | 3 ++ + libcpp/init.cc | 1 + + libcpp/macro.cc | 16 ++++++++- + 9 files changed, 92 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-1.c + create mode 100644 gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-2.c + +diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc +index 5134f6128..744b54dc3 100644 +--- a/gcc/c-family/c-opts.cc ++++ b/gcc/c-family/c-opts.cc +@@ -527,6 +527,10 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, + cpp_opts->track_macro_expansion = 2; + break; + ++ case OPT_fmacro_use_commandline: ++ cpp_opts->macro_use_commandline = 1; ++ break; ++ + case OPT_fexec_charset_: + cpp_opts->narrow_charset = arg; + break; +diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt +index 07da40ef4..a36c27f07 100644 +--- a/gcc/c-family/c.opt ++++ b/gcc/c-family/c.opt +@@ -2012,6 +2012,10 @@ ftrack-macro-expansion= + C ObjC C++ ObjC++ JoinedOrMissing RejectNegative UInteger + -ftrack-macro-expansion=<0|1|2> Track locations of tokens coming from macro expansion and display them in error messages. + ++fmacro-use-commandline ++C ObjC C++ ObjC++ JoinedOrMissing RejectNegative UInteger ++Preferentially use options from the commandline. ++ + fpretty-templates + C++ ObjC++ Var(flag_pretty_templates) Init(1) + Do not pretty-print template specializations as the template signature followed by the arguments. +diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi +index c0a92b370..8c8a81eac 100644 +--- a/gcc/doc/cppopts.texi ++++ b/gcc/doc/cppopts.texi +@@ -277,6 +277,10 @@ correct column numbers in warnings or errors, even if tabs appear on the + line. If the value is less than 1 or greater than 100, the option is + ignored. The default is 8. + ++@item -fmacro-use-commandline ++@opindex fmacro-use-commandline ++Preferentially use options from the command line. ++ + @item -ftrack-macro-expansion@r{[}=@var{level}@r{]} + @opindex ftrack-macro-expansion + Track locations of tokens across macro expansions. This allows the +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index bdd8b9429..2ff7d860d 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -630,6 +630,7 @@ Objective-C and Objective-C++ Dialects}. + -fexec-charset=@var{charset} -fextended-identifiers @gol + -finput-charset=@var{charset} -flarge-source-files @gol + -fmacro-prefix-map=@var{old}=@var{new} -fmax-include-depth=@var{depth} @gol ++-fmacro-use-commandline @gol + -fno-canonical-system-headers -fpch-deps -fpch-preprocess @gol + -fpreprocessed -ftabstop=@var{width} -ftrack-macro-expansion @gol + -fwide-exec-charset=@var{charset} -fworking-directory @gol +diff --git a/gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-1.c b/gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-1.c +new file mode 100644 +index 000000000..f85d9c268 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-1.c +@@ -0,0 +1,26 @@ ++/* ++ { dg-options "-fmacro-use-commandline -DTEST_MACRO=1 -DTEST_MACRO=20" } ++ { dg-do compile } ++ { dg-do run } ++*/ ++ ++/* { dg-warning "-:redefined" "redef TEST_MACRO" { target *-*-* } 0 } ++ { dg-message "-:previous" "prev def TEST_MACRO" { target *-*-* } 0 } ++*/ ++ ++#if DEBUG ++extern int puts (const char *); ++#else ++#define puts(X) ++#endif ++extern void abort (void); ++ ++#define err(str) do { puts(str); abort(); } while (0) ++ ++int main (int argc, char *argv[]) ++{ ++ int macroValue = TEST_MACRO; ++ if (macroValue != 20) ++ err("macroValue"); ++ return 0; ++} +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-2.c b/gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-2.c +new file mode 100644 +index 000000000..99d92d1e4 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/cpp/macro-use-cmdline-2.c +@@ -0,0 +1,34 @@ ++/* ++ { dg-options "-fmacro-use-commandline -DTEST_MACRO=1" } ++ { dg-do compile } ++ { dg-do run } ++*/ ++ ++#define TEST_MACRO 300 ++#define TEST_MACRO_1 400 ++/* ++ { dg-warning "-:redefined" "redef TEST_MACRO" { target *-*-* } 7 } ++ { dg-message "-:previous" "prev def TEST_MACRO" { target *-*-* } 0 } ++*/ ++ ++#if DEBUG ++extern int puts (const char *); ++#else ++#define puts(X) ++#endif ++ ++extern void abort (void); ++ ++#define err(str) do { puts(str); abort(); } while (0) ++ ++int main (int argc, char *argv[]) ++{ ++ int macroValue = TEST_MACRO; ++ if (macroValue != 1) ++ err("macroValue"); ++ ++ int macroValue1 = TEST_MACRO_1; ++ if (macroValue1 != 400) ++ err("macroValue1"); ++ return 0; ++} +\ No newline at end of file +diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h +index 3eba6f74b..c6101ca01 100644 +--- a/libcpp/include/cpplib.h ++++ b/libcpp/include/cpplib.h +@@ -471,6 +471,9 @@ struct cpp_options + consumes the highest amount of memory. */ + unsigned char track_macro_expansion; + ++ /* Use the options on the command line first. */ ++ unsigned char macro_use_commandline; ++ + /* Nonzero means handle C++ alternate operator names. */ + unsigned char operator_names; + +diff --git a/libcpp/init.cc b/libcpp/init.cc +index f4ab83d21..47be60a36 100644 +--- a/libcpp/init.cc ++++ b/libcpp/init.cc +@@ -215,6 +215,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, + cpp_options::track_macro_expansion to learn about the other + values. */ + CPP_OPTION (pfile, track_macro_expansion) = 2; ++ CPP_OPTION (pfile, macro_use_commandline) = 0; + CPP_OPTION (pfile, warn_normalize) = normalized_C; + CPP_OPTION (pfile, warn_literal_suffix) = 1; + CPP_OPTION (pfile, canonical_system_headers) +diff --git a/libcpp/macro.cc b/libcpp/macro.cc +index 8ebf360c0..aa9e4ffa6 100644 +--- a/libcpp/macro.cc ++++ b/libcpp/macro.cc +@@ -3852,7 +3852,21 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) + node->value.macro->line, 0, + "this is the location of the previous definition"); + } +- _cpp_free_definition (node); ++#define LOCATION_FROM_LINEMAP 0 ++#define MIN_LINE_OF_MACRO_BEEN_OVERRIDDEN 96 ++#define MAX_LINE_OF_MACRO_BEEN_OVERRIDDEN 128 ++ if (CPP_OPTION (pfile, macro_use_commandline) ++ && node->value.macro->line >= MIN_LINE_OF_MACRO_BEEN_OVERRIDDEN ++ && node->value.macro->line <= MAX_LINE_OF_MACRO_BEEN_OVERRIDDEN ++ && pfile->forced_token_location == LOCATION_FROM_LINEMAP) ++ { ++ cpp_pedwarning_with_line (pfile, CPP_W_NONE, ++ node->value.macro->line, 0, ++ "use the previous definition from commandline"); ++ return false; ++ } ++ else ++ _cpp_free_definition (node); + } + + /* Enter definition in hash table. */ +-- +2.33.0 + diff --git a/0289-tree-ssa-loop-crc.cc-TARGET_CRC32-may-be-not-defined.patch b/0289-tree-ssa-loop-crc.cc-TARGET_CRC32-may-be-not-defined.patch new file mode 100644 index 0000000000000000000000000000000000000000..05818083d7a37e65e0e4e43ca980d3f49391cc39 --- /dev/null +++ b/0289-tree-ssa-loop-crc.cc-TARGET_CRC32-may-be-not-defined.patch @@ -0,0 +1,35 @@ +From 63f99f46e851aecc070496a0e688a0d118c820a4 Mon Sep 17 00:00:00 2001 +From: YunQiang Su +Date: Mon, 2 Sep 2024 17:57:52 +0800 +Subject: [PATCH] tree-ssa-loop-crc.cc: TARGET_CRC32 may be not defined + +TARGET_CRC32 may be not defined on some architectures, RISC-V is one example. +--- + gcc/tree-ssa-loop-crc.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gcc/tree-ssa-loop-crc.cc b/gcc/tree-ssa-loop-crc.cc +index b9c2f71ca..7eee9446d 100644 +--- a/gcc/tree-ssa-loop-crc.cc ++++ b/gcc/tree-ssa-loop-crc.cc +@@ -1227,6 +1227,9 @@ convert_to_new_loop (class loop *loop) + static unsigned int + tree_ssa_loop_crc () + { ++#ifndef TARGET_CRC32 ++ return 0; ++#else + if (TARGET_CRC32 == false) + { + warning (OPT____,"The loop-crc optimization is not working." \ +@@ -1269,6 +1272,7 @@ tree_ssa_loop_crc () + } + } + return todo; ++#endif + } + + /* Loop crc. */ +-- +2.33.0 + diff --git a/0290-Add-ipa-prefetch-test-for-gcc-s-case.patch b/0290-Add-ipa-prefetch-test-for-gcc-s-case.patch new file mode 100644 index 0000000000000000000000000000000000000000..4545420167bc764595b22b12d7ce486786325429 --- /dev/null +++ b/0290-Add-ipa-prefetch-test-for-gcc-s-case.patch @@ -0,0 +1,209 @@ +From 0534ae05fc313c0d449b48ffe3e01642b644e6d2 Mon Sep 17 00:00:00 2001 +From: Diachkov Ilia +Date: Fri, 6 Sep 2024 10:40:50 +0800 +Subject: [PATCH 1/2] Add ipa-prefetch test for gcc's case + +--- + gcc/ipa-prefetch.cc | 4 +- + gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c | 167 ++++++++++++++++++++ + 2 files changed, 170 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c + +diff --git a/gcc/ipa-prefetch.cc b/gcc/ipa-prefetch.cc +index b000d4d75..8e628390b 100644 +--- a/gcc/ipa-prefetch.cc ++++ b/gcc/ipa-prefetch.cc +@@ -1668,6 +1668,8 @@ static gimple * + insert_page_check (tree addr, tree_poly_offset_map &offset_map, + gimple_seq &stmts) + { ++ if (dump_file) ++ fprintf (dump_file, "Insert page check.\n"); + poly_offset_int offset = 0; + if (offset_map.count (addr)) + offset = offset_map[addr]; +@@ -1783,7 +1785,7 @@ static gimple * + insert_index_check (tree mem, gimple_seq &stmts) + { + if (dump_file) +- fprintf (dump_file, "Insert array index check\n"); ++ fprintf (dump_file, "Insert array index check.\n"); + tree atype = TREE_TYPE (TREE_OPERAND (mem, 0)); + tree ind = TREE_OPERAND (mem, 1); + if (decl_map->count (ind)) +diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c b/gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c +new file mode 100644 +index 000000000..f1001c350 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c +@@ -0,0 +1,167 @@ ++/* { dg-do link } */ ++/* { dg-options "-O3 -fipa-prefetch -flto -flto-partition=one -fdump-ipa-ipa_prefetch" } */ ++/* { dg-require-effective-target lto } */ ++ ++/* Based on opensource gcc code. */ ++ ++#include ++#include ++#include ++ ++#define SPARSESET_ELT_TYPE unsigned int ++#define ALLOCNO_NUM(A) ((A)->num) ++ ++typedef struct sparseset_def ++{ ++ SPARSESET_ELT_TYPE *dense; /* Dense array. */ ++ SPARSESET_ELT_TYPE *sparse; /* Sparse array. */ ++ SPARSESET_ELT_TYPE members; /* Number of elements. */ ++ SPARSESET_ELT_TYPE size; /* Maximum number of elements. */ ++ SPARSESET_ELT_TYPE iter; /* Iterator index. */ ++ unsigned char iter_inc; /* Iteration increment amount. */ ++ bool iterating; ++ SPARSESET_ELT_TYPE elms[2]; /* Combined dense and sparse arrays. */ ++} *sparseset; ++ ++struct ira_allocno ++{ ++ /* The allocno order number starting with 0. Each allocno has an ++ unique number and the number is never changed for the ++ allocno. */ ++ int num; ++ /* Regno for allocno or cap. */ ++ int regno; ++ /*...*/ ++}; ++ ++typedef struct ira_allocno_live_range *allocno_live_range_t; ++typedef struct ira_allocno *ira_allocno_t; ++ ++struct ira_allocno_live_range ++{ ++ /* Allocno whose live range is described by given structure. */ ++ ira_allocno_t allocno; ++ /* Program point range. */ ++ int start, finish; ++ /* Next structure describing program points where the allocno ++ lives. */ ++ allocno_live_range_t next; ++ /* Pointer to structures with the same start/finish. */ ++ allocno_live_range_t start_next, finish_next; ++}; ++ ++bool ++sparseset_bit_p (sparseset s, SPARSESET_ELT_TYPE e) ++{ ++ SPARSESET_ELT_TYPE idx; ++ ++ idx = s->sparse[e]; ++ ++ return idx < s->members && s->dense[idx] == e; ++} ++ ++bool new_pseudos_p; ++int ira_max_point, ira_allocnos_num; ++allocno_live_range_t *ira_finish_point_ranges; ++ ++static inline void ++sparseset_clear (sparseset s) ++{ ++ s->members = 0; ++ s->iterating = false; ++} ++ ++sparseset ++sparseset_alloc (SPARSESET_ELT_TYPE n_elms) ++{ ++ unsigned int n_bytes = sizeof (struct sparseset_def) ++ + ((n_elms - 1) * 2 * sizeof (SPARSESET_ELT_TYPE)); ++ ++ /* We use xcalloc rather than xmalloc to silence some valgrind uninitialized ++ read errors when accessing set->sparse[n] when "n" is not, and never has ++ been, in the set. These uninitialized reads are expected, by design and ++ harmless. If this turns into a performance problem due to some future ++ additional users of sparseset, we can revisit this decision. */ ++ sparseset set = (sparseset) calloc (1, n_bytes); ++ set->dense = &(set->elms[0]); ++ set->sparse = &(set->elms[n_elms]); ++ set->size = n_elms; ++ sparseset_clear (set); ++ return set; ++} ++ ++void ++sparseset_insert_bit (sparseset s, SPARSESET_ELT_TYPE e, SPARSESET_ELT_TYPE idx) ++{ ++ s->sparse[e] = idx; ++ s->dense[idx] = e; ++} ++ ++void ++sparseset_swap (sparseset s, SPARSESET_ELT_TYPE idx1, SPARSESET_ELT_TYPE idx2) ++{ ++ SPARSESET_ELT_TYPE tmp = s->dense[idx2]; ++ sparseset_insert_bit (s, s->dense[idx1], idx2); ++ sparseset_insert_bit (s, tmp, idx1); ++} ++ ++void __attribute__ ((noinline)) ++sparseset_clear_bit (sparseset s, SPARSESET_ELT_TYPE e) ++{ ++ if (sparseset_bit_p (s, e)) ++ { ++ SPARSESET_ELT_TYPE idx = s->sparse[e]; ++ SPARSESET_ELT_TYPE iter = s->iter; ++ SPARSESET_ELT_TYPE mem = s->members - 1; ++ ++ /* If we are iterating over this set and we want to delete a ++ member we've already visited, then we swap the element we ++ want to delete with the element at the current iteration ++ index so that it plays well together with the code below ++ that actually removes the element. */ ++ if (s->iterating && idx <= iter) ++ { ++ if (idx < iter) ++ { ++ sparseset_swap (s, idx, iter); ++ idx = iter; ++ } ++ s->iter_inc = 0; ++ } ++ ++ /* Replace the element we want to delete with the last element ++ in the dense array and then decrement s->members, effectively ++ removing the element we want to delete. */ ++ sparseset_insert_bit (s, s->dense[mem], idx); ++ s->members = mem; ++ } ++} ++ ++allocno_live_range_t r; ++sparseset allocnos_live; ++ ++void ++ira_flattening () ++{ ++ int i; ++ ++ if (new_pseudos_p) ++ { ++ allocnos_live = sparseset_alloc (ira_allocnos_num); ++ for (i = 0; i < ira_max_point; i++) ++ { ++ for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next) ++ sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (r->allocno)); ++ } ++ } ++} ++ ++int main() ++{ ++ ira_flattening (); ++ return 0; ++} ++ ++/* { dg-final { scan-wpa-ipa-dump-times "Insert page check" 1 "ipa_prefetch"} } */ ++/* { dg-final { scan-wpa-ipa-dump-times "Insert 0 prefetch stmt:" 1 "ipa_prefetch"} } */ ++/* { dg-final { scan-wpa-ipa-dump-times "Split dom_bb after condition stmts:" 1 "ipa_prefetch"} } */ +-- +2.33.0 + diff --git a/0291-Fix-settings-for-wide-operations-tests.patch b/0291-Fix-settings-for-wide-operations-tests.patch new file mode 100644 index 0000000000000000000000000000000000000000..1e368b6d4a9ee7dc54af81a9af071f73f3c96ad5 --- /dev/null +++ b/0291-Fix-settings-for-wide-operations-tests.patch @@ -0,0 +1,73 @@ +From 411792b0bbb63715d8e90d46eb4f0d9c810ce8ba Mon Sep 17 00:00:00 2001 +From: Pronin Alexander 00812787 +Date: Tue, 3 Sep 2024 21:26:03 +0800 +Subject: [PATCH 2/2] Fix settings for wide operations tests + +Signed-off-by: lin-houzhong +--- + gcc/testsuite/gcc.dg/double_sized_mul-1.c | 8 +++++--- + gcc/testsuite/gcc.dg/double_sized_mul-2.c | 9 +++++---- + gcc/testsuite/gcc.dg/uaddsub.c | 6 ++++-- + 3 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/gcc/testsuite/gcc.dg/double_sized_mul-1.c b/gcc/testsuite/gcc.dg/double_sized_mul-1.c +index d32a25223..b848e02de 100644 +--- a/gcc/testsuite/gcc.dg/double_sized_mul-1.c ++++ b/gcc/testsuite/gcc.dg/double_sized_mul-1.c +@@ -1,7 +1,8 @@ +-/* { dg-do compile } */ ++/* { dg-do compile { target aarch64*-*-* x86_64*-*-*} } */ + /* fif-conversion-gimple and fuaddsub-overflow-match-all are required for + proper overflow detection in some cases. */ +-/* { dg-options "-O2 -fif-conversion-gimple -march=armv8.2-a -fuaddsub-overflow-match-all -fdump-tree-widening_mul-stats" } */ ++/* { dg-options "-O2 -fif-conversion-gimple -fuaddsub-overflow-match-all -fdump-tree-widening_mul-stats" } */ ++/* { dg-additional-options "-march=armv8.2-a" { target aarch64*-*-* } } */ + #include + + typedef unsigned __int128 uint128_t; +@@ -138,4 +139,5 @@ uint128_t mul128_perm (uint64_t a, uint64_t b) + return res; + } + +-/* { dg-final { scan-tree-dump-times "double sized mul optimized: 1" 6 "widening_mul" } } */ ++/* { dg-final { scan-tree-dump-times "double sized mul optimized: 1" 6 "widening_mul" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump-times "double sized mul optimized: 1" 4 "widening_mul" { target x86_64*-*-* } } } */ +diff --git a/gcc/testsuite/gcc.dg/double_sized_mul-2.c b/gcc/testsuite/gcc.dg/double_sized_mul-2.c +index ff35902b7..cf8f0aedd 100644 +--- a/gcc/testsuite/gcc.dg/double_sized_mul-2.c ++++ b/gcc/testsuite/gcc.dg/double_sized_mul-2.c +@@ -1,7 +1,8 @@ +-/* { dg-do compile } */ +-/* fif-conversion-gimple is required for proper overflow detection +- in some cases. */ +-/* { dg-options "-O2 -fif-conversion-gimple -march=armv8.2-a -fuaddsub-overflow-match-all -fdump-tree-widening_mul-stats" } */ ++/* { dg-do compile { target aarch64*-*-* x86_64*-*-*} } */ ++/* fif-conversion-gimple and fuaddsub-overflow-match-all are required for ++ proper overflow detection in some cases. */ ++/* { dg-options "-O2 -fif-conversion-gimple -fuaddsub-overflow-match-all -fdump-tree-widening_mul-stats" } */ ++/* { dg-additional-options "-march=armv8.2-a" { target aarch64*-*-* } } */ + #include + + typedef unsigned __int128 uint128_t; +diff --git a/gcc/testsuite/gcc.dg/uaddsub.c b/gcc/testsuite/gcc.dg/uaddsub.c +index 96c26d308..dcb587fc8 100644 +--- a/gcc/testsuite/gcc.dg/uaddsub.c ++++ b/gcc/testsuite/gcc.dg/uaddsub.c +@@ -1,5 +1,6 @@ +-/* { dg-do compile } */ ++/* { dg-do compile { target aarch64*-*-* x86_64-*-* } } */ + /* { dg-options "-O2 -fuaddsub-overflow-match-all -fdump-tree-optimized" } */ ++/* { dg-additional-options "-march=armv8.2-a" { target aarch64*-*-* } } */ + #include + + typedef unsigned __int128 uint128_t; +@@ -140,4 +141,5 @@ uint256_t sub256 (uint128_t a, uint128_t b) + } + + /* { dg-final { scan-tree-dump-times "= .ADD_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" } } */ +-/* { dg-final { scan-tree-dump-times "= .SUB_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" } } */ ++/* { dg-final { scan-tree-dump-times "= .SUB_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump-times "= .SUB_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 4 "optimized" { target x86_64*-*-* } } } */ +-- +2.33.0 + diff --git a/0292-Fix-errors-in-ipa-prefetch-IAORPF-and-IAOSJ0.patch b/0292-Fix-errors-in-ipa-prefetch-IAORPF-and-IAOSJ0.patch new file mode 100644 index 0000000000000000000000000000000000000000..13341df6672c078b4bc6e3cfba77b18e2c763634 --- /dev/null +++ b/0292-Fix-errors-in-ipa-prefetch-IAORPF-and-IAOSJ0.patch @@ -0,0 +1,42 @@ +From 808294bf0f32aaff1cc7e56a756b246d328b3402 Mon Sep 17 00:00:00 2001 +From: Diachkov Ilia +Date: Fri, 6 Sep 2024 11:10:03 +0800 +Subject: [PATCH 2/3] Fix errors in ipa-prefetch (IAORPF and IAOSJ0) + +Signed-off-by: Diachkov Ilia +--- + gcc/ipa-prefetch.cc | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/gcc/ipa-prefetch.cc b/gcc/ipa-prefetch.cc +index b000d4d75..74af55af0 100644 +--- a/gcc/ipa-prefetch.cc ++++ b/gcc/ipa-prefetch.cc +@@ -1681,7 +1681,8 @@ insert_page_check (tree addr, tree_poly_offset_map &offset_map, + unsigned long long pmask = ~(param_ipa_prefetch_pagesize - 1); + tree pmask_cst = build_int_cst (utype, pmask); + tree off_tree = wide_int_to_tree (sizetype, offset); +- gcc_assert (TREE_CODE (addr_type) == POINTER_TYPE); ++ gcc_assert (TREE_CODE (addr_type) == POINTER_TYPE ++ || TREE_CODE (addr_type) == REFERENCE_TYPE); + tree addr_with_offset = gimple_build (&stmts, POINTER_PLUS_EXPR, + addr_type, addr, off_tree); + tree conv_addr = make_ssa_name (utype); +@@ -2082,11 +2083,11 @@ optimize_function (cgraph_node *n, function *fn) + for (unsigned int i = 0; i < vmrs.length (); i++) + find_nearest_common_post_dominator (vmrs[i], dom_bb); + +- if (!dom_bb) ++ if (!dom_bb || dom_bb->index == ENTRY_BLOCK || dom_bb->index == EXIT_BLOCK) + { + if (dump_file) +- fprintf (dump_file, "Post dominator bb for MRs is not found. " +- "Skip the case.\n"); ++ fprintf (dump_file, "Post dominator bb for MRs is not found or " ++ "it's an entry/exit block. Skip the case.\n"); + return 0; + } + else if (dump_file) +-- +2.33.0 + diff --git a/0293-Fix-error-with-stmts-insertion-in-ipa-prefetch-for-I.patch b/0293-Fix-error-with-stmts-insertion-in-ipa-prefetch-for-I.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c9ec2575784c8c42d58935fa61dd66807e1686f --- /dev/null +++ b/0293-Fix-error-with-stmts-insertion-in-ipa-prefetch-for-I.patch @@ -0,0 +1,51 @@ +From bfb77997f423ffe3bdcbd8bb8d7f739fe51ce4f5 Mon Sep 17 00:00:00 2001 +From: Diachkov Ilia +Date: Fri, 6 Sep 2024 11:36:11 +0800 +Subject: [PATCH 3/3] Fix error with stmts insertion in ipa-prefetch (for + IAO6R3) + +Signed-off-by: Diachkov Ilia +--- + gcc/ipa-prefetch.cc | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/gcc/ipa-prefetch.cc b/gcc/ipa-prefetch.cc +index b000d4d75..6190c2ebb 100644 +--- a/gcc/ipa-prefetch.cc ++++ b/gcc/ipa-prefetch.cc +@@ -2096,7 +2096,7 @@ optimize_function (cgraph_node *n, function *fn) + fprintf (dump_file, "\n"); + } + +- /* Try to find comp_mr's stmt in the dominator bb. */ ++ /* Try to find comp_mr's stmt in the post dominator bb. */ + gimple *last_used = NULL; + for (gimple_stmt_iterator si = gsi_last_bb (dom_bb); !gsi_end_p (si); + gsi_prev (&si)) +@@ -2168,7 +2168,22 @@ optimize_function (cgraph_node *n, function *fn) + vec pcalls = vNULL; + gimple *last_pref = NULL; + insert_prefetch_stmts (pcalls, stmts, last_pref, vmrs, processed_stmts); +- gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++ ++ gimple *gstmt = gsi_stmt (gsi); ++ bool insert_after = last_used || gstmt == NULL || !is_ctrl_stmt (gstmt); ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "Insert prefetch sequence %s stmt:\n", ++ insert_after ? "after": "before"); ++ if (gstmt) ++ print_gimple_stmt (dump_file, gstmt, 0); ++ else ++ fprintf (dump_file, "(no stmts)\n"); ++ } ++ if (insert_after) ++ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); ++ else ++ gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); + + correct_cfg (bbends, last_pref, dom_bb); + +-- +2.33.0 + diff --git a/0294-Fix-errors-in-ipa-prefetch-IAO50J-and-IAO5H7.patch b/0294-Fix-errors-in-ipa-prefetch-IAO50J-and-IAO5H7.patch new file mode 100644 index 0000000000000000000000000000000000000000..43a88b8a4f5c5dd482deb6f23f77e4d47885141d --- /dev/null +++ b/0294-Fix-errors-in-ipa-prefetch-IAO50J-and-IAO5H7.patch @@ -0,0 +1,80 @@ +From cd79fc29d2cdb73836f8699355113e94b833e0e0 Mon Sep 17 00:00:00 2001 +From: Diachkov Ilia +Date: Wed, 11 Sep 2024 17:18:58 +0800 +Subject: [PATCH 2/2] Fix errors in ipa-prefetch(IAO50J and IAO5H7) + +Signed-off-by: Diachkov Ilia +--- + gcc/ipa-prefetch.cc | 35 ++++++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) + +diff --git a/gcc/ipa-prefetch.cc b/gcc/ipa-prefetch.cc +index 5184687aa..685f9c267 100644 +--- a/gcc/ipa-prefetch.cc ++++ b/gcc/ipa-prefetch.cc +@@ -2099,6 +2099,18 @@ optimize_function (cgraph_node *n, function *fn) + fprintf (dump_file, "\n"); + } + ++ /* Check that all used mrs dominate found post dominator bb. This case ++ may be supported later by copying MR evaluation to the bb. */ ++ for (unsigned int i = 0; i < used_mr_vec.length (); i++) ++ if (!dominated_by_p (CDI_DOMINATORS, dom_bb, ++ gimple_bb (used_mr_vec[i]->stmts[0]))) ++ { ++ if (dump_file) ++ fprintf (dump_file, "MR's (%d) bb is not dominate the found bb %d. " ++ "Skip the case.\n", used_mr_vec[i]->mr_id, dom_bb->index); ++ return 0; ++ } ++ + /* Try to find comp_mr's stmt in the post dominator bb. */ + gimple *last_used = NULL; + for (gimple_stmt_iterator si = gsi_last_bb (dom_bb); !gsi_end_p (si); +@@ -2133,17 +2145,29 @@ optimize_function (cgraph_node *n, function *fn) + + /* Create new inc var. Insert new_var = old_var + step * factor. */ + decl_map = new tree_map; +- gcc_assert (comp_mr->stmts[0] && gimple_assign_single_p (comp_mr->stmts[0])); +- tree inc_var = gimple_assign_lhs (comp_mr->stmts[0]); ++ gimple *old_inc_stmt = comp_mr->stmts[0]; ++ gcc_assert (old_inc_stmt && gimple_assign_single_p (old_inc_stmt)); ++ tree inc_var = gimple_assign_lhs (old_inc_stmt); ++ if (dump_file) ++ { ++ fprintf (dump_file, "Old inc stmt: "); ++ print_gimple_stmt (dump_file, old_inc_stmt, 0); ++ } + /* If old_var definition dominates the current use, just use it, otherwise + evaluate it just before new inc var evaluation. */ + gimple_seq stmts = NULL; + stmt_set processed_stmts; +- if (!dominated_by_p (CDI_DOMINATORS, dom_bb, gimple_bb (comp_mr->stmts[0]))) ++ tree local_inc_var = inc_var; ++ if (!dominated_by_p (CDI_DOMINATORS, dom_bb, gimple_bb (old_inc_stmt))) + { + gimple *tmp = gimple_copy_and_remap_memref_stmts (comp_mr, stmts, 0, 0, + processed_stmts); +- inc_var = gimple_assign_lhs (tmp); ++ local_inc_var = gimple_assign_lhs (tmp); ++ if (dump_file) ++ { ++ fprintf (dump_file, "Localized old inc stmt: "); ++ print_gimple_stmt (dump_file, tmp, 0); ++ } + } + tree var_type = TREE_TYPE (inc_var); + enum tree_code inc_code; +@@ -2155,7 +2179,8 @@ optimize_function (cgraph_node *n, function *fn) + HOST_WIDE_INT dist_val = tree_to_shwi (step) + * param_ipa_prefetch_distance_factor; + tree dist = build_int_cst (TREE_TYPE (step), dist_val); +- tree new_inc_var = gimple_build (&stmts, inc_code, var_type, inc_var, dist); ++ tree new_inc_var = gimple_build (&stmts, inc_code, var_type, local_inc_var, ++ dist); + (*decl_map)[inc_var] = new_inc_var; + if (dump_file) + { +-- +2.33.0 + diff --git a/0295-Fix-error-with-grouped_load-merge-in-slp-transpose-v.patch b/0295-Fix-error-with-grouped_load-merge-in-slp-transpose-v.patch new file mode 100644 index 0000000000000000000000000000000000000000..8540cd4aca03f8077c98480d442cc194836ea137 --- /dev/null +++ b/0295-Fix-error-with-grouped_load-merge-in-slp-transpose-v.patch @@ -0,0 +1,30 @@ +From 7b4cce4896cefefedba9545a9633585e086b7621 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Wed, 11 Sep 2024 18:26:22 +0800 +Subject: [PATCH 1/2] Fix error with grouped_load merge in + slp-transpose-vectorize (for IALR8B) + +--- + gcc/tree-vect-slp.cc | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc +index e3e246977..d4870de43 100644 +--- a/gcc/tree-vect-slp.cc ++++ b/gcc/tree-vect-slp.cc +@@ -3807,7 +3807,11 @@ vect_slp_grouped_load_find (bb_vec_info bb_vinfo, vec &visited, + these two grouped loads need to be merged. */ + tree opb = get_op_base_address (first_element); + unsigned int grp_size_b = DR_GROUP_SIZE (first_element); +- if (opa == opb && grp_size_a == grp_size_b) ++ /* Ensure that the elements merge to load group meet the alignment condition (dr_misalignment) */ ++ HOST_WIDE_INT diff = 0; ++ diff = (TREE_INT_CST_LOW (DR_INIT (first_element->dr_aux.dr)) ++ - TREE_INT_CST_LOW (DR_INIT (merge_first_element->dr_aux.dr))); ++ if (opa == opb && grp_size_a == grp_size_b && diff >= 0) + { + res.safe_push (first_element); + visited[i] = true; +-- +2.33.0 + diff --git a/0296-Fix-error-in-slp-transpose-vectorize-for-IAQFM3.patch b/0296-Fix-error-in-slp-transpose-vectorize-for-IAQFM3.patch new file mode 100644 index 0000000000000000000000000000000000000000..34862f283b12674816bd1fd597c62a6101312055 --- /dev/null +++ b/0296-Fix-error-in-slp-transpose-vectorize-for-IAQFM3.patch @@ -0,0 +1,28 @@ +From b3a6a170bf1dc0e460e98a7fd02c92e6b036784a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Fri, 13 Sep 2024 14:13:07 +0800 +Subject: [PATCH 2/2] Fix error in slp-transpose-vectorize (for IAQFM3) + +--- + gcc/tree-vect-slp.cc | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc +index d4870de43..d7e198dff 100644 +--- a/gcc/tree-vect-slp.cc ++++ b/gcc/tree-vect-slp.cc +@@ -3811,7 +3811,10 @@ vect_slp_grouped_load_find (bb_vec_info bb_vinfo, vec &visited, + HOST_WIDE_INT diff = 0; + diff = (TREE_INT_CST_LOW (DR_INIT (first_element->dr_aux.dr)) + - TREE_INT_CST_LOW (DR_INIT (merge_first_element->dr_aux.dr))); +- if (opa == opb && grp_size_a == grp_size_b && diff >= 0) ++ if (opa == opb ++ && grp_size_a == grp_size_b ++ && diff >= 0 ++ && check_same_bb (first_element, merge_first_element)) + { + res.safe_push (first_element); + visited[i] = true; +-- +2.33.0 + diff --git a/0297-Fix-grouped-load-merging-error-in-SLP-transpose-vectorization.patch b/0297-Fix-grouped-load-merging-error-in-SLP-transpose-vectorization.patch new file mode 100644 index 0000000000000000000000000000000000000000..21a24c0f4bcaa8f6dce6f75c5be868871a9c1ea0 --- /dev/null +++ b/0297-Fix-grouped-load-merging-error-in-SLP-transpose-vectorization.patch @@ -0,0 +1,26 @@ +From 8b30d71f881e15bfbc514f9b65fee178610e1536 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Wed, 18 Sep 2024 10:48:55 +0800 +Subject: [PATCH] Fix error in slp-transpose-vectorize (for IARHFM) + +--- + gcc/tree-vect-slp.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc +index d7e198dff..fbd638333 100644 +--- a/gcc/tree-vect-slp.cc ++++ b/gcc/tree-vect-slp.cc +@@ -3814,7 +3814,8 @@ vect_slp_grouped_load_find (bb_vec_info bb_vinfo, vec &visited, + if (opa == opb + && grp_size_a == grp_size_b + && diff >= 0 +- && check_same_bb (first_element, merge_first_element)) ++ && check_same_bb (first_element, merge_first_element) ++ && DR_PTR_INFO (first_element->dr_aux.dr) != DR_PTR_INFO (merge_first_element->dr_aux.dr)) + { + res.safe_push (first_element); + visited[i] = true; +-- +2.33.0 + diff --git a/0298-Mark-prefetch-builtin-as-willreturn.patch b/0298-Mark-prefetch-builtin-as-willreturn.patch new file mode 100644 index 0000000000000000000000000000000000000000..7a489a5d9b0d7e1c7454a66a02ef59ac805532a6 --- /dev/null +++ b/0298-Mark-prefetch-builtin-as-willreturn.patch @@ -0,0 +1,99 @@ +From a252bbd11d22481a1e719ed36d800e2192abb369 Mon Sep 17 00:00:00 2001 +From: Pronin Alexander +Date: Thu, 31 Oct 2024 15:49:27 +0800 +Subject: [PATCH 1/6] Mark prefetch builtin as willreturn + +Signed-off-by: Pronin Alexander +--- + gcc/common.opt | 4 ++++ + gcc/gimple.cc | 30 ++++++++++++++++++++++++++++++ + gcc/gimple.h | 1 + + gcc/tree-ssa-pre.cc | 4 +--- + 4 files changed, 36 insertions(+), 3 deletions(-) + +diff --git a/gcc/common.opt b/gcc/common.opt +index 688d65e4d..be5fcc681 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1313,6 +1313,10 @@ fdelete-null-pointer-checks + Common Var(flag_delete_null_pointer_checks) Init(-1) Optimization + Delete useless null pointer checks. + ++fbuiltin-will-return ++Common Var(flag_builtin_will_return) Optimization ++Consider some of the builtins as definitely returning. ++ + fdevirtualize-at-ltrans + Common Var(flag_ltrans_devirtualize) + Stream extra data to support more aggressive devirtualization in LTO local transformation mode. +diff --git a/gcc/gimple.cc b/gcc/gimple.cc +index 9e62da426..04ca9f161 100644 +--- a/gcc/gimple.cc ++++ b/gcc/gimple.cc +@@ -2998,6 +2998,36 @@ nonbarrier_call_p (gimple *call) + return false; + } + ++static inline bool ++will_return_builtin_p (gimple *call) ++{ ++ if (!flag_builtin_will_return) ++ return false; ++ ++ if (!gimple_call_builtin_p (call, BUILT_IN_NORMAL)) ++ return false; ++ ++ switch (DECL_FUNCTION_CODE (gimple_call_fndecl (call))) ++ { ++ case BUILT_IN_PREFETCH: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++bool ++will_return_call_p (gimple *call, function *fun) ++{ ++ int flags = gimple_call_flags (call); ++ if (!(flags & (ECF_CONST|ECF_PURE)) ++ || (flags & ECF_LOOPING_CONST_OR_PURE) ++ || stmt_can_throw_external (fun, call)) ++ return will_return_builtin_p (call); ++ ++ return true; ++} ++ + /* Callback for walk_stmt_load_store_ops. + + Return TRUE if OP will dereference the tree stored in DATA, FALSE +diff --git a/gcc/gimple.h b/gcc/gimple.h +index 77a5a07e9..bb05a7664 100644 +--- a/gcc/gimple.h ++++ b/gcc/gimple.h +@@ -1628,6 +1628,7 @@ extern bool gimple_asm_clobbers_memory_p (const gasm *); + extern void dump_decl_set (FILE *, bitmap); + extern bool nonfreeing_call_p (gimple *); + extern bool nonbarrier_call_p (gimple *); ++extern bool will_return_call_p (gimple *, function *); + extern bool infer_nonnull_range (gimple *, tree); + extern bool infer_nonnull_range_by_dereference (gimple *, tree); + extern bool infer_nonnull_range_by_attribute (gimple *, tree); +diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc +index 98134b5d3..b5264133a 100644 +--- a/gcc/tree-ssa-pre.cc ++++ b/gcc/tree-ssa-pre.cc +@@ -3988,9 +3988,7 @@ compute_avail (function *fun) + that forbids hoisting possibly trapping expressions + before it. */ + int flags = gimple_call_flags (stmt); +- if (!(flags & (ECF_CONST|ECF_PURE)) +- || (flags & ECF_LOOPING_CONST_OR_PURE) +- || stmt_can_throw_external (fun, stmt)) ++ if (!will_return_call_p (stmt, fun)) + /* Defer setting of BB_MAY_NOTRETURN to avoid it + influencing the processing of the call itself. */ + set_bb_may_notreturn = true; +-- +2.33.0 + diff --git a/0299-Backport-Disallow-pointer-operands-for-and-partly-PR.patch b/0299-Backport-Disallow-pointer-operands-for-and-partly-PR.patch new file mode 100644 index 0000000000000000000000000000000000000000..c0a733c1ad49595a8e148a4f51f1df371a84eb46 --- /dev/null +++ b/0299-Backport-Disallow-pointer-operands-for-and-partly-PR.patch @@ -0,0 +1,156 @@ +From 3b109376d057342a31267ea4c9bd422d940874cb Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Thu, 31 Oct 2024 16:09:43 +0800 +Subject: [PATCH 2/6] [Backport]Disallow pointer operands for |,^ and partly + &[PR106878] + +Signed-off-by: Jakub Jelinek +--- + gcc/match.pd | 6 ++++- + .../gcc.c-torture/compile/pr106878.c | 15 +++++++++++++ + gcc/tree-cfg.cc | 22 ++++++++++++++++--- + gcc/tree-ssa-reassoc.cc | 16 +++++++++++++- + 4 files changed, 54 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106878.c + +diff --git a/gcc/match.pd b/gcc/match.pd +index 8f41c292f..822e065e8 100644 +--- a/gcc/match.pd ++++ b/gcc/match.pd +@@ -1655,6 +1655,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) + && (int_fits_type_p (@1, TREE_TYPE (@0)) + || tree_nop_conversion_p (TREE_TYPE (@0), type))) + || types_match (@0, @1)) ++ && !POINTER_TYPE_P (TREE_TYPE (@0)) ++ && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE + /* ??? This transform conflicts with fold-const.cc doing + Convert (T)(x & c) into (T)x & (T)c, if c is an integer + constants (if x has signed type, the sign bit cannot be set +@@ -1691,7 +1693,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) + (if (GIMPLE + && TREE_CODE (@1) != INTEGER_CST + && tree_nop_conversion_p (type, TREE_TYPE (@2)) +- && types_match (type, @0)) ++ && types_match (type, @0) ++ && !POINTER_TYPE_P (TREE_TYPE (@0)) ++ && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE) + (bitop @0 (convert @1))))) + + (for bitop (bit_and bit_ior) +diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106878.c b/gcc/testsuite/gcc.c-torture/compile/pr106878.c +new file mode 100644 +index 000000000..c84571894 +--- /dev/null ++++ b/gcc/testsuite/gcc.c-torture/compile/pr106878.c +@@ -0,0 +1,15 @@ ++/* PR tree-optimization/106878 */ ++ ++typedef __INTPTR_TYPE__ intptr_t; ++typedef __UINTPTR_TYPE__ uintptr_t; ++int a; ++ ++int ++foo (const int *c) ++{ ++ uintptr_t d = ((intptr_t) c | (intptr_t) &a) & 65535 << 16; ++ intptr_t e = (intptr_t) c; ++ if (d != (e & 65535 << 16)) ++ return 1; ++ return 0; ++} +diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc +index 48b52f785..d33aaec8c 100644 +--- a/gcc/tree-cfg.cc ++++ b/gcc/tree-cfg.cc +@@ -4163,7 +4163,9 @@ verify_gimple_assign_binary (gassign *stmt) + case ROUND_MOD_EXPR: + case RDIV_EXPR: + case EXACT_DIV_EXPR: +- /* Disallow pointer and offset types for many of the binary gimple. */ ++ case BIT_IOR_EXPR: ++ case BIT_XOR_EXPR: ++ /* Disallow pointer and offset types for many of the binary gimple. */ + if (POINTER_TYPE_P (lhs_type) + || TREE_CODE (lhs_type) == OFFSET_TYPE) + { +@@ -4178,9 +4180,23 @@ verify_gimple_assign_binary (gassign *stmt) + + case MIN_EXPR: + case MAX_EXPR: +- case BIT_IOR_EXPR: +- case BIT_XOR_EXPR: ++ /* Continue with generic binary expression handling. */ ++ break; ++ + case BIT_AND_EXPR: ++ if (POINTER_TYPE_P (lhs_type) ++ && TREE_CODE (rhs2) == INTEGER_CST) ++ break; ++ /* Disallow pointer and offset types for many of the binary gimple. */ ++ if (POINTER_TYPE_P (lhs_type) ++ || TREE_CODE (lhs_type) == OFFSET_TYPE) ++ { ++ error ("invalid types for %qs", code_name); ++ debug_generic_expr (lhs_type); ++ debug_generic_expr (rhs1_type); ++ debug_generic_expr (rhs2_type); ++ return true; ++ } + /* Continue with generic binary expression handling. */ + break; + +diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc +index e3d521e32..6baef4764 100644 +--- a/gcc/tree-ssa-reassoc.cc ++++ b/gcc/tree-ssa-reassoc.cc +@@ -3617,10 +3617,14 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length, + tree type2 = NULL_TREE; + bool strict_overflow_p = false; + candidates.truncate (0); ++ if (POINTER_TYPE_P (type1)) ++ type1 = pointer_sized_int_node; + for (j = i; j; j = chains[j - 1]) + { + tree type = TREE_TYPE (ranges[j - 1].exp); + strict_overflow_p |= ranges[j - 1].strict_overflow_p; ++ if (POINTER_TYPE_P (type)) ++ type = pointer_sized_int_node; + if ((b % 4) == 3) + { + /* For the signed < 0 cases, the types should be +@@ -3651,6 +3655,8 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length, + tree type = TREE_TYPE (ranges[j - 1].exp); + if (j == k) + continue; ++ if (POINTER_TYPE_P (type)) ++ type = pointer_sized_int_node; + if ((b % 4) == 3) + { + if (!useless_type_conversion_p (type1, type)) +@@ -3680,7 +3686,7 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length, + op = r->exp; + continue; + } +- if (id == l) ++ if (id == l || POINTER_TYPE_P (TREE_TYPE (op))) + { + code = (b % 4) == 3 ? BIT_NOT_EXPR : NOP_EXPR; + g = gimple_build_assign (make_ssa_name (type1), code, op); +@@ -3704,6 +3710,14 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length, + gimple_seq_add_stmt_without_update (&seq, g); + op = gimple_assign_lhs (g); + } ++ type1 = TREE_TYPE (ranges[k - 1].exp); ++ if (POINTER_TYPE_P (type1)) ++ { ++ gimple *g ++ = gimple_build_assign (make_ssa_name (type1), NOP_EXPR, op); ++ gimple_seq_add_stmt_without_update (&seq, g); ++ op = gimple_assign_lhs (g); ++ } + candidates.pop (); + if (update_range_test (&ranges[k - 1], NULL, candidates.address (), + candidates.length (), opcode, ops, op, +-- +2.33.0 + diff --git a/0300-Remove-erroneous-pattern-from-gimple-ifcvt.patch b/0300-Remove-erroneous-pattern-from-gimple-ifcvt.patch new file mode 100644 index 0000000000000000000000000000000000000000..0eca175156e2190e6135a0e1fb80b979df4f8a7b --- /dev/null +++ b/0300-Remove-erroneous-pattern-from-gimple-ifcvt.patch @@ -0,0 +1,55 @@ +From 91ef8899a80e493042fd2687ad89064c9f90cf17 Mon Sep 17 00:00:00 2001 +From: Pronin Alexander +Date: Thu, 31 Oct 2024 16:14:34 +0800 +Subject: [PATCH 3/6] Remove erroneous pattern from gimple ifcvt + +Signed-off-by: Pronin Alexander +--- + gcc/match.pd | 2 +- + gcc/testsuite/gcc.dg/ifcvt-gimple-1.c | 21 +++++++++++++++++++++ + 2 files changed, 22 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.dg/ifcvt-gimple-1.c + +diff --git a/gcc/match.pd b/gcc/match.pd +index 8f41c292f..2dd6581d1 100644 +--- a/gcc/match.pd ++++ b/gcc/match.pd +@@ -4276,7 +4276,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) + ) + + (if (flag_if_conversion_gimple) +- (for simple_op (plus minus bit_and bit_ior bit_xor) ++ (for simple_op (plus minus bit_ior bit_xor) + (simplify + (cond @0 (simple_op @1 INTEGER_CST@2) @1) + (switch +diff --git a/gcc/testsuite/gcc.dg/ifcvt-gimple-1.c b/gcc/testsuite/gcc.dg/ifcvt-gimple-1.c +new file mode 100644 +index 000000000..381a4ad51 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/ifcvt-gimple-1.c +@@ -0,0 +1,21 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 -fno-inline -fif-conversion-gimple" } */ ++ ++#include ++ ++void foo(int a, int *p) { ++ *p = a; ++} ++ ++void verify (int a) { ++ if (a != 3) ++ abort (); ++} ++ ++int main() { ++ int a = 0; ++ foo (3, &a); ++ int tmp = (a > 7) ? a & 1 : a; ++ verify (tmp); ++ return 0; ++} +-- +2.33.0 + diff --git a/0301-Add-required-check-for-iteration-through-uses.patch b/0301-Add-required-check-for-iteration-through-uses.patch new file mode 100644 index 0000000000000000000000000000000000000000..105f4f75616777a5f8e3437645f41c75bc7b5d2b --- /dev/null +++ b/0301-Add-required-check-for-iteration-through-uses.patch @@ -0,0 +1,33 @@ +From ca24d352e98e357f4f7b8f0d262201765705a08a Mon Sep 17 00:00:00 2001 +From: Pronin Alexander +Date: Thu, 31 Oct 2024 16:31:33 +0800 +Subject: [PATCH 4/6] Add required check for iteration through uses + +Signed-off-by: Pronin Alexander +--- + gcc/tree-ssa-math-opts.cc | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc +index 2c06b8a60..80c06fa01 100644 +--- a/gcc/tree-ssa-math-opts.cc ++++ b/gcc/tree-ssa-math-opts.cc +@@ -4938,8 +4938,13 @@ convert_double_size_mul (gimple_stmt_iterator *gsi, gimple *stmt) + + /* Find the mult low part getter. */ + FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, match[3]) +- if (gimple_assign_rhs_code (use_stmt) == REALPART_EXPR) +- break; ++ { ++ if (!is_gimple_assign (use_stmt)) ++ continue; ++ ++ if (gimple_assign_rhs_code (use_stmt) == REALPART_EXPR) ++ break; ++ } + + /* Create high and low (if needed) parts extractors. */ + /* Low part. */ +-- +2.33.0 + diff --git a/0302-Added-param-for-optimization-for-merging-bb-s-with-c.patch b/0302-Added-param-for-optimization-for-merging-bb-s-with-c.patch new file mode 100644 index 0000000000000000000000000000000000000000..da25a9e25c950f625e6e27963f2ab5c54f33d32f --- /dev/null +++ b/0302-Added-param-for-optimization-for-merging-bb-s-with-c.patch @@ -0,0 +1,158 @@ +From 210147e28d542a03588ba3c3fa473301a03bb687 Mon Sep 17 00:00:00 2001 +From: Gmyrikov Konstantin +Date: Thu, 31 Oct 2024 16:45:15 +0800 +Subject: [PATCH 6/6] Added param for optimization for merging bb's with cheap + insns.Zero param means turned off optimization(default implementation),One + means turned on + +Signed-off-by: Gmyrikov Konstantin +--- + gcc/params.opt | 4 +++ + gcc/testsuite/gcc.dg/if_comb1.c | 13 +++++++++ + gcc/testsuite/gcc.dg/if_comb2.c | 13 +++++++++ + gcc/testsuite/gcc.dg/if_comb3.c | 12 +++++++++ + gcc/tree-ssa-ifcombine.cc | 47 ++++++++++++++++++++++++++++++--- + 5 files changed, 86 insertions(+), 3 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/if_comb1.c + create mode 100644 gcc/testsuite/gcc.dg/if_comb2.c + create mode 100644 gcc/testsuite/gcc.dg/if_comb3.c + +diff --git a/gcc/params.opt b/gcc/params.opt +index fc700ab79..3ddfaf5b2 100644 +--- a/gcc/params.opt ++++ b/gcc/params.opt +@@ -789,6 +789,10 @@ Maximum number of VALUEs handled during a single find_base_term call. + Common Joined UInteger Var(param_max_vrp_switch_assertions) Init(10) Param Optimization + Maximum number of assertions to add along the default edge of a switch statement during VRP. + ++-param=merge-assign-stmts-ifcombine= ++Common Joined UInteger Var(param_merge_assign_stmts_ifcombine) Init(0) IntegerRange(0, 1) Param Optimization ++Whether bb's with cheap gimple_assign stmts should be merged in the ifcombine pass. ++ + -param=min-crossjump-insns= + Common Joined UInteger Var(param_min_crossjump_insns) Init(5) IntegerRange(1, 65536) Param Optimization + The minimum number of matching instructions to consider for crossjumping. +diff --git a/gcc/testsuite/gcc.dg/if_comb1.c b/gcc/testsuite/gcc.dg/if_comb1.c +new file mode 100644 +index 000000000..e00adc37d +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/if_comb1.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-Ofast -S --param=merge-assign-stmts-ifcombine=1 -fdump-tree-ifcombine" } */ ++ ++int foo (double a, double b, int c) ++{ ++ if (c < 10 || a - b > 1.0) ++ return 0; ++ else ++ return 1; ++} ++ ++/* { dg-final { scan-tree-dump "optimizing two comparisons" "ifcombine"} } */ ++/* { dg-final { scan-tree-dump "Merging blocks" "ifcombine"} } */ +diff --git a/gcc/testsuite/gcc.dg/if_comb2.c b/gcc/testsuite/gcc.dg/if_comb2.c +new file mode 100644 +index 000000000..176e7e726 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/if_comb2.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-Ofast -S --param=merge-assign-stmts-ifcombine=1 -fdump-tree-ifcombine" } */ ++ ++int foo (int a, int b, int c) ++{ ++ if (a > 1 || b * c < 10) ++ return 0; ++ else ++ return 1; ++} ++ ++/* { dg-final { scan-tree-dump "optimizing two comparisons" "ifcombine"} } */ ++/* { dg-final { scan-tree-dump "Merging blocks" "ifcombine"} } */ +diff --git a/gcc/testsuite/gcc.dg/if_comb3.c b/gcc/testsuite/gcc.dg/if_comb3.c +new file mode 100644 +index 000000000..aa2e4510c +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/if_comb3.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-Ofast -S --param=merge-assign-stmts-ifcombine=1 -fdump-tree-ifcombine" } */ ++ ++int foo (int a, int b, int c) ++{ ++ if (a > 1 && b + c < 10) ++ a++; ++ return a; ++} ++ ++/* { dg-final { scan-tree-dump "optimizing two comparisons" "ifcombine"} } */ ++/* { dg-final { scan-tree-dump "Merging blocks" "ifcombine"} } */ +diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc +index ce9bbebf9..264a8bcae 100644 +--- a/gcc/tree-ssa-ifcombine.cc ++++ b/gcc/tree-ssa-ifcombine.cc +@@ -110,6 +110,18 @@ recognize_if_then_else (basic_block cond_bb, + return true; + } + ++/* Verify if gimple insn cheap for param=merge-assign-stmts-ifcombine ++ optimization. */ ++ ++bool is_insn_cheap (enum tree_code t) ++{ ++ static enum tree_code cheap_insns[] = {MULT_EXPR, PLUS_EXPR, MINUS_EXPR}; ++ for (int i = 0; i < sizeof (cheap_insns)/sizeof (enum tree_code); i++) ++ if (t == cheap_insns[i]) ++ return 1; ++ return 0; ++} ++ + /* Verify if the basic block BB does not have side-effects. Return + true in this case, else false. */ + +@@ -572,9 +584,38 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, + = param_logical_op_non_short_circuit; + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) + return false; +- /* Only do this optimization if the inner bb contains only the conditional. */ +- if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) +- return false; ++ if (param_merge_assign_stmts_ifcombine) ++ { ++ int number_cheap_insns = 0; ++ int number_conds = 0; ++ for (auto i = gsi_start_nondebug_after_labels_bb ++ (outer_cond_bb); !gsi_end_p (i); gsi_next_nondebug (&i)) ++ if (gimple_code (gsi_stmt (i)) == GIMPLE_ASSIGN ++ && is_insn_cheap (gimple_assign_rhs_code (gsi_stmt (i)))) ++ number_cheap_insns++; ++ else if (gimple_code (gsi_stmt (i)) == GIMPLE_COND) ++ number_conds++; ++ for (auto i = gsi_start_nondebug_after_labels_bb ++ (inner_cond_bb); !gsi_end_p (i); gsi_next_nondebug (&i)) ++ if (gimple_code (gsi_stmt (i)) == GIMPLE_ASSIGN ++ && is_insn_cheap (gimple_assign_rhs_code (gsi_stmt (i)))) ++ number_cheap_insns++; ++ else if (gimple_code (gsi_stmt (i)) == GIMPLE_COND) ++ number_conds++; ++ if (!(number_cheap_insns == 1 && number_conds == 2) ++ && !gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb ++ (inner_cond_bb))) ++ return false; ++ } ++ else ++ { ++ /* Only do this optimization if the inner bb contains ++ only the conditional. */ ++ if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb ++ (inner_cond_bb))) ++ return false; ++ } ++ + t1 = fold_build2_loc (gimple_location (inner_cond), + inner_cond_code, + boolean_type_node, +-- +2.33.0 + diff --git a/0303-Add-generation-of-stream-in-functions-for-pre-versio.patch b/0303-Add-generation-of-stream-in-functions-for-pre-versio.patch new file mode 100644 index 0000000000000000000000000000000000000000..dfa965b684d5c45f8f78e4e66a40e2926f5a5260 --- /dev/null +++ b/0303-Add-generation-of-stream-in-functions-for-pre-versio.patch @@ -0,0 +1,6263 @@ +From 4789a6eae616df0b7d07901114c91a2099e4d56d Mon Sep 17 00:00:00 2001 +From: wangchunyang +Date: Wed, 13 Nov 2024 11:26:16 +0800 +Subject: [PATCH 1/2] Add generation of stream in functions for pre-version lto + objects + +--- + gcc/lto-streamer.h | 6 + + gcc/opt-read.awk | 1 + + gcc/optc-save-gen.awk | 6044 ++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 6050 insertions(+), 1 deletion(-) + +diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h +index 597e9e405..9db1a20b3 100644 +--- a/gcc/lto-streamer.h ++++ b/gcc/lto-streamer.h +@@ -943,12 +943,18 @@ void cl_target_option_stream_in (class data_in *, + struct bitpack_d *, + struct cl_target_option *); + ++void cl_target_option_stream_in_prev (class data_in *, ++ struct bitpack_d *, ++ struct cl_target_option *); ++ + void cl_optimization_stream_out (struct output_block *, + struct bitpack_d *, struct cl_optimization *); + + void cl_optimization_stream_in (class data_in *, + struct bitpack_d *, struct cl_optimization *); + ++void cl_optimization_stream_in_prev (class data_in *, ++ struct bitpack_d *, struct cl_optimization *); + + + /* In lto-opts.cc. */ +diff --git a/gcc/opt-read.awk b/gcc/opt-read.awk +index ce3617c8d..624cf6e3d 100644 +--- a/gcc/opt-read.awk ++++ b/gcc/opt-read.awk +@@ -71,6 +71,7 @@ BEGIN { + n_target_save++ + + extra_target_vars[n_extra_target_vars] = name ++ extra_target_vars_set[name] = 1 + extra_target_var_types[n_extra_target_vars] = type + n_extra_target_vars++ + } +diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk +index 76e9b3cb9..7c012dd4e 100644 +--- a/gcc/optc-save-gen.awk ++++ b/gcc/optc-save-gen.awk +@@ -174,6 +174,8 @@ print " unsigned HOST_WIDE_INT mask = 0;"; + j = 0; + k = 0; + for (i = 0; i < n_opt_other; i++) { ++ var_opt_other_j[var_opt_other[i]] = j; ++ var_opt_other_k[var_opt_other[i]] = k; + print " if (opts_set->x_" var_opt_other[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -185,6 +187,8 @@ for (i = 0; i < n_opt_other; i++) { + } + + for (i = 0; i < n_opt_int; i++) { ++ var_opt_int_j[var_opt_int[i]] = j; ++ var_opt_int_k[var_opt_int[i]] = k; + print " if (opts_set->x_" var_opt_int[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -196,6 +200,8 @@ for (i = 0; i < n_opt_int; i++) { + } + + for (i = 0; i < n_opt_enum; i++) { ++ var_opt_enum_j[var_opt_enum[i]] = j; ++ var_opt_enum_k[var_opt_enum[i]] = k; + print " if (opts_set->x_" var_opt_enum[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -207,6 +213,8 @@ for (i = 0; i < n_opt_enum; i++) { + } + + for (i = 0; i < n_opt_short; i++) { ++ var_opt_short_j[var_opt_short[i]] = j; ++ var_opt_short_k[var_opt_short[i]] = k; + print " if (opts_set->x_" var_opt_short[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -218,6 +226,8 @@ for (i = 0; i < n_opt_short; i++) { + } + + for (i = 0; i < n_opt_char; i++) { ++ var_opt_char_j[var_opt_char[i]] = j; ++ var_opt_char_k[var_opt_char[i]] = k; + print " if (opts_set->x_" var_opt_char[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -229,6 +239,8 @@ for (i = 0; i < n_opt_char; i++) { + } + + for (i = 0; i < n_opt_string; i++) { ++ var_opt_string_j[var_opt_string[i]] = j; ++ var_opt_string_k[var_opt_string[i]] = k; + print " if (opts_set->x_" var_opt_string[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -604,6 +616,8 @@ for (i = 0; i < n_extra_target_vars; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ extra_target_vars_j[extra_target_vars[i]] = j; ++ extra_target_vars_k[extra_target_vars[i]] = k; + print " if (opts_set->x_" extra_target_vars[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -622,6 +636,8 @@ for (i = 0; i < n_target_other; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ var_target_other_j[var_target_other[i]] = j; ++ var_target_other_k[var_target_other[i]] = k; + print " if (opts_set->x_" var_target_other[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -636,6 +652,8 @@ for (i = 0; i < n_target_enum; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ var_target_enum_j[var_target_enum[i]] = j; ++ var_target_enum_k[var_target_enum[i]] = k; + print " if (opts_set->x_" var_target_enum[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -654,6 +672,8 @@ for (i = 0; i < n_target_int; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ var_target_int_j[var_target_int[i]] = j; ++ var_target_int_k[var_target_int[i]] = k; + print " if (opts_set->x_" var_target_int[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -668,6 +688,8 @@ for (i = 0; i < n_target_short; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ var_target_short_j[var_target_short[i]] = j; ++ var_target_short_k[var_target_short[i]] = k; + print " if (opts_set->x_" var_target_short[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -682,6 +704,8 @@ for (i = 0; i < n_target_char; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ var_target_char_j[var_target_char[i]] = j; ++ var_target_char_k[var_target_char[i]] = k; + print " if (opts_set->x_" var_target_char[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -696,6 +720,8 @@ for (i = 0; i < n_target_string; i++) { + if (j == 0 && k == 0) { + print " unsigned HOST_WIDE_INT mask = 0;"; + } ++ var_target_string_j[var_target_string[i]] = j; ++ var_target_string_k[var_target_string[i]] = k; + print " if (opts_set->x_" var_target_string[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { +@@ -1038,6 +1064,7 @@ for (i = 0; i < n_target_save; i++) { + sub(" *" name "$", "", type) + if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$") { + var_target_str[n_target_str++] = name; ++ var_target_str_set[name] = 1; + string_options_names[name]++ + } + else { +@@ -1048,12 +1075,14 @@ for (i = 0; i < n_target_save; i++) { + sub("\\[.+", "", name) + sub(" [^ ]+$", "", type) + var_target_array[n_target_array] = name ++ var_target_array_set[name] = 1 + var_target_array_type[n_target_array] = type + var_target_array_size[n_target_array++] = size + } + else { + var_target_val_type[n_target_val] = type; + var_target_val[n_target_val++] = name; ++ var_target_val_set[name] = 1; + } + } + } +@@ -1069,17 +1098,21 @@ if (have_save) { + + var_list_seen[name]++; + otype = var_type_struct(flags[i]) +- if (otype ~ "^const char \\**$") ++ if (otype ~ "^const char \\**$") { + var_target_str[n_target_str++] = "x_" name; ++ var_target_str_set["x_" name] = 1; ++ } + else { + var_target_val_type[n_target_val] = otype; + var_target_val[n_target_val++] = "x_" name; ++ var_target_val_set["x_" name]; + } + } + } + } else { + var_target_val_type[n_target_val] = "int"; + var_target_val[n_target_val++] = "x_target_flags"; ++ var_target_val_set["x_target_flags"] = 1; + } + + for (i = 0; i < n_target_str; i++) { +@@ -1253,6 +1286,224 @@ for (i = 0; i < n_target_int; i++) { + + print "}"; + ++print ""; ++print "/* Stream in target options */"; ++print "void"; ++print "cl_target_option_stream_in_prev (struct data_in *data_in ATTRIBUTE_UNUSED,"; ++print " struct bitpack_d *bp ATTRIBUTE_UNUSED,"; ++print " struct cl_target_option *ptr ATTRIBUTE_UNUSED)"; ++print "{"; ++if ("x_aarch64_branch_protection_string" in var_target_str_set) { ++ print " ptr->x_aarch64_branch_protection_string = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_aarch64_branch_protection_string)" ++ print " ptr->x_aarch64_branch_protection_string = xstrdup (ptr->x_aarch64_branch_protection_string);" ++} ++else { ++ print " bp_unpack_string (data_in, bp);" ++} ++if ("x_aarch64_override_tune_string" in var_target_str_set) { ++ print " ptr->x_aarch64_override_tune_string = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_aarch64_override_tune_string)" ++ print " ptr->x_aarch64_override_tune_string = xstrdup (ptr->x_aarch64_override_tune_string);" ++} ++else { ++ print " bp_unpack_string (data_in, bp);" ++} ++if ("x_aarch64_asm_isa_flags" in var_target_val_set) { ++ print " ptr->x_aarch64_asm_isa_flags = (aarch64_feature_flags) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_isa_flags" in var_target_val_set) { ++ print " ptr->x_aarch64_isa_flags = (aarch64_feature_flags) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_selected_arch" in var_target_val_set) { ++ print " ptr->x_selected_arch = (enum aarch64_arch) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_ra_sign_key" in var_target_val_set) { ++ print " ptr->x_aarch64_ra_sign_key = (enum aarch64_key_type) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_selected_tune" in var_target_val_set) { ++ print " ptr->x_selected_tune = (enum aarch64_processor) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_stack_protector_guard_offset" in var_target_val_set) { ++ print " ptr->x_aarch64_stack_protector_guard_offset = (long) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_enable_bti" in var_target_val_set) { ++ print " ptr->x_aarch64_enable_bti = (unsigned) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_cmodel_var" in var_target_val_set) { ++ print " ptr->x_aarch64_cmodel_var = (enum aarch64_code_model ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_fix_a53_err835769" in var_target_val_set) { ++ print " ptr->x_aarch64_fix_a53_err835769 = (signed char ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_fix_a53_err843419" in var_target_val_set) { ++ print " ptr->x_aarch64_fix_a53_err843419 = (signed char ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_target_flags" in var_target_val_set) { ++ print " ptr->x_target_flags = (/* - */ int ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_flag_omit_leaf_frame_pointer" in var_target_val_set) { ++ print " ptr->x_flag_omit_leaf_frame_pointer = (signed char ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_flag_outline_atomics" in var_target_val_set) { ++ print " ptr->x_aarch64_flag_outline_atomics = (signed char ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_pcrelative_literal_loads" in var_target_val_set) { ++ print " ptr->x_pcrelative_literal_loads = (signed char ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_ra_sign_scope" in var_target_val_set) { ++ print " ptr->x_aarch64_ra_sign_scope = (enum aarch64_function_type ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++if ("x_aarch64_tls_dialect" in var_target_val_set) { ++ print " ptr->x_aarch64_tls_dialect = (enum aarch64_tls_type ) bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++print " unsigned HOST_WIDE_INT explicit_mask_prev[1];" ++print " for (size_t i = 0; i < 1; i++)" ++print " explicit_mask_prev[i] = bp_unpack_value (bp, 64);" ++print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)" ++print " ptr->explicit_mask[i] = 0;" ++if ("aarch64_asm_isa_flags" in extra_target_vars_k) { ++ k = extra_target_vars_k["aarch64_asm_isa_flags"] ++ j = extra_target_vars_j["aarch64_asm_isa_flags"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_isa_flags" in extra_target_vars_k) { ++ k = extra_target_vars_k["aarch64_isa_flags"] ++ j = extra_target_vars_j["aarch64_isa_flags"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("selected_arch" in extra_target_vars_k) { ++ k = extra_target_vars_k["selected_arch"] ++ j = extra_target_vars_j["selected_arch"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_ra_sign_key" in extra_target_vars_k) { ++ k = extra_target_vars_k["aarch64_ra_sign_key"] ++ j = extra_target_vars_j["aarch64_ra_sign_key"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("selected_tune" in extra_target_vars_k) { ++ k = extra_target_vars_k["selected_tune"] ++ j = extra_target_vars_j["selected_tune"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_stack_protector_guard_offset" in extra_target_vars_k) { ++ k = extra_target_vars_k["aarch64_stack_protector_guard_offset"] ++ j = extra_target_vars_j["aarch64_stack_protector_guard_offset"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_enable_bti" in extra_target_vars_k) { ++ k = extra_target_vars_k["aarch64_enable_bti"] ++ j = extra_target_vars_j["aarch64_enable_bti"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_cmodel_var" in var_target_enum_k) { ++ k = var_target_enum_k["aarch64_cmodel_var"] ++ j = var_target_enum_j["aarch64_cmodel_var"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_ra_sign_scope" in var_target_enum_k) { ++ k = var_target_enum_k["aarch64_ra_sign_scope"] ++ j = var_target_enum_j["aarch64_ra_sign_scope"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_tls_dialect" in var_target_enum_k) { ++ k = var_target_enum_k["aarch64_tls_dialect"] ++ j = var_target_enum_j["aarch64_tls_dialect"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_fix_a53_err835769" in var_target_char_k) { ++ k = var_target_char_k["aarch64_fix_a53_err835769"] ++ j = var_target_char_j["aarch64_fix_a53_err835769"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_fix_a53_err843419" in var_target_char_k) { ++ k = var_target_char_k["aarch64_fix_a53_err843419"] ++ j = var_target_char_j["aarch64_fix_a53_err843419"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_omit_leaf_frame_pointer" in var_target_char_k) { ++ k = var_target_char_k["flag_omit_leaf_frame_pointer"] ++ j = var_target_char_j["flag_omit_leaf_frame_pointer"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_flag_outline_atomics" in var_target_char_k) { ++ k = var_target_char_k["aarch64_flag_outline_atomics"] ++ j = var_target_char_j["aarch64_flag_outline_atomics"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("pcrelative_literal_loads" in var_target_char_k) { ++ k = var_target_char_k["pcrelative_literal_loads"] ++ j = var_target_char_j["pcrelative_literal_loads"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_branch_protection_string" in var_target_string_k) { ++ k = var_target_string_k["aarch64_branch_protection_string"] ++ j = var_target_string_j["aarch64_branch_protection_string"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("aarch64_override_tune_string" in var_target_string_k) { ++ k = var_target_string_k["aarch64_override_tune_string"] ++ j = var_target_string_j["aarch64_override_tune_string"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("target_flags" in var_target_explicit_mask) { ++ print " ptr->explicit_mask_target_flags = bp_unpack_value (bp, 64);" ++} ++else { ++ print " bp_unpack_value (bp, 64);" ++} ++print "}"; ++print ""; ++ + print "/* free heap memory used by target options */"; + print "void"; + print "cl_target_option_free (struct cl_target_option *ptr ATTRIBUTE_UNUSED)"; +@@ -1266,15 +1517,19 @@ print "}"; + + n_opt_val = 4; + var_opt_val[0] = "x_optimize" ++var_opt_val_set["x_optimize"] = 1 + var_opt_val_type[0] = "char " + var_opt_hash[0] = 1; + var_opt_val[1] = "x_optimize_size" ++var_opt_val_set["x_optimize_size"] = 1 + var_opt_val_type[1] = "char " + var_opt_hash[1] = 1; + var_opt_val[2] = "x_optimize_debug" ++var_opt_val_set["x_optimize_debug"] = 1 + var_opt_val_type[2] = "char " + var_opt_hash[2] = 1; + var_opt_val[3] = "x_optimize_fast" ++var_opt_val_set["x_optimize_fast"] = 1 + var_opt_val_type[3] = "char " + var_opt_hash[3] = 1; + for (i = 0; i < n_opts; i++) { +@@ -1291,6 +1546,7 @@ for (i = 0; i < n_opts; i++) { + otype = var_type_struct(flags[i]) + var_opt_val_type[n_opt_val] = otype; + var_opt_val[n_opt_val] = "x_" name; ++ var_opt_val_set["x_" name] = 1; + var_opt_hash[n_opt_val] = flag_set_p("Optimization", flags[i]); + var_opt_init[n_opt_val] = opt_args("Init", flags[i]); + n_opt_val++; +@@ -1415,6 +1671,5792 @@ for (i = 0; i < n_opt_val; i++) { + print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; + print " ptr->explicit_mask[i] = bp_unpack_value (bp, 64);"; + print "}"; ++ ++print ""; ++print "/* Stream in optimization options */"; ++print "void"; ++print "cl_optimization_stream_in_prev (struct data_in *data_in ATTRIBUTE_UNUSED,"; ++print " struct bitpack_d *bp ATTRIBUTE_UNUSED,"; ++print " struct cl_optimization *ptr ATTRIBUTE_UNUSED)"; ++print "{"; ++if ("x_optimize" in var_opt_val_set) { ++ print " ptr->x_optimize = (char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_optimize_size" in var_opt_val_set) { ++ print " ptr->x_optimize_size = (char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_optimize_debug" in var_opt_val_set) { ++ print " ptr->x_optimize_debug = (char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_optimize_fast" in var_opt_val_set) { ++ print " ptr->x_optimize_fast = (char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_align_loop_iterations" in var_opt_val_set) { ++ print " ptr->x_param_align_loop_iterations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4 > (int ) 10)" ++ print " ptr->x_param_align_loop_iterations ^= 4;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_align_threshold" in var_opt_val_set) { ++ print " ptr->x_param_align_threshold = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_align_threshold ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_protect_allocas" in var_opt_val_set) { ++ print " ptr->x_param_asan_protect_allocas = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_asan_protect_allocas ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_instrument_reads" in var_opt_val_set) { ++ print " ptr->x_param_asan_instrument_reads = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_asan_instrument_reads ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_instrument_writes" in var_opt_val_set) { ++ print " ptr->x_param_asan_instrument_writes = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_asan_instrument_writes ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_instrumentation_with_call_threshold" in var_opt_val_set) { ++ print " ptr->x_param_asan_instrumentation_with_call_threshold = (int ) bp_unpack_var_len_int (bp);" ++ print " if (7000 > (int ) 10)" ++ print " ptr->x_param_asan_instrumentation_with_call_threshold ^= 7000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_memintrin" in var_opt_val_set) { ++ print " ptr->x_param_asan_memintrin = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_asan_memintrin ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_stack" in var_opt_val_set) { ++ print " ptr->x_param_asan_stack = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_asan_stack ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_asan_use_after_return" in var_opt_val_set) { ++ print " ptr->x_param_asan_use_after_return = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_asan_use_after_return ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_avg_loop_niter" in var_opt_val_set) { ++ print " ptr->x_param_avg_loop_niter = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_avg_loop_niter ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_avoid_fma_max_bits" in var_opt_val_set) { ++ print " ptr->x_param_avoid_fma_max_bits = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_builtin_expect_probability" in var_opt_val_set) { ++ print " ptr->x_param_builtin_expect_probability = (int ) bp_unpack_var_len_int (bp);" ++ print " if (90 > (int ) 10)" ++ print " ptr->x_param_builtin_expect_probability ^= 90;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_builtin_string_cmp_inline_length" in var_opt_val_set) { ++ print " ptr->x_param_builtin_string_cmp_inline_length = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_builtin_string_cmp_inline_length ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_case_values_threshold" in var_opt_val_set) { ++ print " ptr->x_param_case_values_threshold = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_comdat_sharing_probability" in var_opt_val_set) { ++ print " ptr->x_param_comdat_sharing_probability = (int ) bp_unpack_var_len_int (bp);" ++ print " if (20 > (int ) 10)" ++ print " ptr->x_param_comdat_sharing_probability ^= 20;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_pointer_compression_size" in var_opt_val_set) { ++ print " ptr->x_param_pointer_compression_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_pointer_compression_size ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_construct_interfere_size" in var_opt_val_set) { ++ print " ptr->x_param_construct_interfere_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (0 > (int ) 10)" ++ print " ptr->x_param_construct_interfere_size ^= 0;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_destruct_interfere_size" in var_opt_val_set) { ++ print " ptr->x_param_destruct_interfere_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (0 > (int ) 10)" ++ print " ptr->x_param_destruct_interfere_size ^= 0;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_dse_max_alias_queries_per_store" in var_opt_val_set) { ++ print " ptr->x_param_dse_max_alias_queries_per_store = (int ) bp_unpack_var_len_int (bp);" ++ print " if (256 > (int ) 10)" ++ print " ptr->x_param_dse_max_alias_queries_per_store ^= 256;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_dse_max_object_size" in var_opt_val_set) { ++ print " ptr->x_param_dse_max_object_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (256 > (int ) 10)" ++ print " ptr->x_param_dse_max_object_size ^= 256;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_early_inlining_insns" in var_opt_val_set) { ++ print " ptr->x_param_early_inlining_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (6 > (int ) 10)" ++ print " ptr->x_param_early_inlining_insns ^= 6;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_evrp_mode" in var_opt_val_set) { ++ print " ptr->x_param_evrp_mode = (enum evrp_mode ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_evrp_sparse_threshold" in var_opt_val_set) { ++ print " ptr->x_param_evrp_sparse_threshold = (int ) bp_unpack_var_len_int (bp);" ++ print " if (800 > (int ) 10)" ++ print " ptr->x_param_evrp_sparse_threshold ^= 800;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_evrp_switch_limit" in var_opt_val_set) { ++ print " ptr->x_param_evrp_switch_limit = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_evrp_switch_limit ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_fsm_scale_path_blocks" in var_opt_val_set) { ++ print " ptr->x_param_fsm_scale_path_blocks = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_fsm_scale_path_blocks ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_fsm_scale_path_stmts" in var_opt_val_set) { ++ print " ptr->x_param_fsm_scale_path_stmts = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_fsm_scale_path_stmts ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_gcse_after_reload_critical_fraction" in var_opt_val_set) { ++ print " ptr->x_param_gcse_after_reload_critical_fraction = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_gcse_after_reload_critical_fraction ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_gcse_after_reload_partial_fraction" in var_opt_val_set) { ++ print " ptr->x_param_gcse_after_reload_partial_fraction = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_gcse_after_reload_partial_fraction ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_gcse_cost_distance_ratio" in var_opt_val_set) { ++ print " ptr->x_param_gcse_cost_distance_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_gcse_cost_distance_ratio ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_gcse_unrestricted_cost" in var_opt_val_set) { ++ print " ptr->x_param_gcse_unrestricted_cost = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_gcse_unrestricted_cost ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_graphite_max_arrays_per_scop" in var_opt_val_set) { ++ print " ptr->x_param_graphite_max_arrays_per_scop = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_graphite_max_arrays_per_scop ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_graphite_max_nb_scop_params" in var_opt_val_set) { ++ print " ptr->x_param_graphite_max_nb_scop_params = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_graphite_max_nb_scop_params ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_hwasan_instrument_allocas" in var_opt_val_set) { ++ print " ptr->x_param_hwasan_instrument_allocas = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_hwasan_instrument_allocas ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_hwasan_instrument_mem_intrinsics" in var_opt_val_set) { ++ print " ptr->x_param_hwasan_instrument_mem_intrinsics = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_hwasan_instrument_mem_intrinsics ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_hwasan_instrument_reads" in var_opt_val_set) { ++ print " ptr->x_param_hwasan_instrument_reads = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_hwasan_instrument_reads ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_hwasan_instrument_stack" in var_opt_val_set) { ++ print " ptr->x_param_hwasan_instrument_stack = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_hwasan_instrument_stack ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_hwasan_instrument_writes" in var_opt_val_set) { ++ print " ptr->x_param_hwasan_instrument_writes = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_hwasan_instrument_writes ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_hwasan_random_frame_tag" in var_opt_val_set) { ++ print " ptr->x_param_hwasan_random_frame_tag = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_hwasan_random_frame_tag ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ifcvt_allow_register_renaming" in var_opt_val_set) { ++ print " ptr->x_param_ifcvt_allow_register_renaming = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_inline_heuristics_hint_percent" in var_opt_val_set) { ++ print " ptr->x_param_inline_heuristics_hint_percent = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_inline_heuristics_hint_percent ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_inline_min_speedup" in var_opt_val_set) { ++ print " ptr->x_param_inline_min_speedup = (int ) bp_unpack_var_len_int (bp);" ++ print " if (30 > (int ) 10)" ++ print " ptr->x_param_inline_min_speedup ^= 30;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_inline_unit_growth" in var_opt_val_set) { ++ print " ptr->x_param_inline_unit_growth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_inline_unit_growth ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_eval_threshold" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_eval_threshold = (int ) bp_unpack_var_len_int (bp);" ++ print " if (500 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_eval_threshold ^= 500;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_large_unit_insns" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_large_unit_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16000 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_large_unit_insns ^= 16000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_loop_hint_bonus" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_loop_hint_bonus = (int ) bp_unpack_var_len_int (bp);" ++ print " if (64 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_loop_hint_bonus ^= 64;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_max_recursive_depth" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_max_recursive_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_max_recursive_depth ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_min_recursive_probability" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_min_recursive_probability = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_min_recursive_probability ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_profile_count_base" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_profile_count_base = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_profile_count_base ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_recursion_penalty" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_recursion_penalty = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_recursion_penalty ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_recursive_freq_factor" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_recursive_freq_factor = (int ) bp_unpack_var_len_int (bp);" ++ print " if (6 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_recursive_freq_factor ^= 6;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_single_call_penalty" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_single_call_penalty = (int ) bp_unpack_var_len_int (bp);" ++ print " if (15 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_single_call_penalty ^= 15;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_unit_growth" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_unit_growth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_unit_growth ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_cp_value_list_size" in var_opt_val_set) { ++ print " ptr->x_param_ipa_cp_value_list_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_ipa_cp_value_list_size ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_jump_function_lookups" in var_opt_val_set) { ++ print " ptr->x_param_ipa_jump_function_lookups = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_ipa_jump_function_lookups ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_max_aa_steps" in var_opt_val_set) { ++ print " ptr->x_param_ipa_max_aa_steps = (int ) bp_unpack_var_len_int (bp);" ++ print " if (25000 > (int ) 10)" ++ print " ptr->x_param_ipa_max_aa_steps ^= 25000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_max_agg_items" in var_opt_val_set) { ++ print " ptr->x_param_ipa_max_agg_items = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_ipa_max_agg_items ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_max_loop_predicates" in var_opt_val_set) { ++ print " ptr->x_param_ipa_max_loop_predicates = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_ipa_max_loop_predicates ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_max_param_expr_ops" in var_opt_val_set) { ++ print " ptr->x_param_ipa_max_param_expr_ops = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_ipa_max_param_expr_ops ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_max_switch_predicate_bounds" in var_opt_val_set) { ++ print " ptr->x_param_ipa_max_switch_predicate_bounds = (int ) bp_unpack_var_len_int (bp);" ++ print " if (5 > (int ) 10)" ++ print " ptr->x_param_ipa_max_switch_predicate_bounds ^= 5;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_prefetch_distance_factor" in var_opt_val_set) { ++ print " ptr->x_param_ipa_prefetch_distance_factor = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4 > (int ) 10)" ++ print " ptr->x_param_ipa_prefetch_distance_factor ^= 4;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_prefetch_locality" in var_opt_val_set) { ++ print " ptr->x_param_ipa_prefetch_locality = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_ipa_prefetch_locality ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_prefetch_pagesize" in var_opt_val_set) { ++ print " ptr->x_param_ipa_prefetch_pagesize = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4096 > (int ) 10)" ++ print " ptr->x_param_ipa_prefetch_pagesize ^= 4096;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_sra_max_replacements" in var_opt_val_set) { ++ print " ptr->x_param_ipa_sra_max_replacements = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_ipa_sra_max_replacements ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ipa_sra_ptr_growth_factor" in var_opt_val_set) { ++ print " ptr->x_param_ipa_sra_ptr_growth_factor = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_ipa_sra_ptr_growth_factor ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ira_consider_dup_in_all_alts" in var_opt_val_set) { ++ print " ptr->x_param_ira_consider_dup_in_all_alts = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_ira_consider_dup_in_all_alts ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ira_loop_reserved_regs" in var_opt_val_set) { ++ print " ptr->x_param_ira_loop_reserved_regs = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_ira_loop_reserved_regs ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ira_max_conflict_table_size" in var_opt_val_set) { ++ print " ptr->x_param_ira_max_conflict_table_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_ira_max_conflict_table_size ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ira_max_loops_num" in var_opt_val_set) { ++ print " ptr->x_param_ira_max_loops_num = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_ira_max_loops_num ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_iv_always_prune_cand_set_bound" in var_opt_val_set) { ++ print " ptr->x_param_iv_always_prune_cand_set_bound = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_iv_always_prune_cand_set_bound ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_iv_consider_all_candidates_bound" in var_opt_val_set) { ++ print " ptr->x_param_iv_consider_all_candidates_bound = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_iv_consider_all_candidates_bound ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_iv_max_considered_uses" in var_opt_val_set) { ++ print " ptr->x_param_iv_max_considered_uses = (int ) bp_unpack_var_len_int (bp);" ++ print " if (250 > (int ) 10)" ++ print " ptr->x_param_iv_max_considered_uses ^= 250;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_jump_table_max_growth_ratio_for_size" in var_opt_val_set) { ++ print " ptr->x_param_jump_table_max_growth_ratio_for_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (300 > (int ) 10)" ++ print " ptr->x_param_jump_table_max_growth_ratio_for_size ^= 300;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_jump_table_max_growth_ratio_for_speed" in var_opt_val_set) { ++ print " ptr->x_param_jump_table_max_growth_ratio_for_speed = (int ) bp_unpack_var_len_int (bp);" ++ print " if (800 > (int ) 10)" ++ print " ptr->x_param_jump_table_max_growth_ratio_for_speed ^= 800;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_l1_cache_line_size" in var_opt_val_set) { ++ print " ptr->x_param_l1_cache_line_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_l1_cache_line_size ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_l1_cache_size" in var_opt_val_set) { ++ print " ptr->x_param_l1_cache_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (64 > (int ) 10)" ++ print " ptr->x_param_l1_cache_size ^= 64;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_l2_cache_size" in var_opt_val_set) { ++ print " ptr->x_param_l2_cache_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (512 > (int ) 10)" ++ print " ptr->x_param_l2_cache_size ^= 512;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_large_function_growth" in var_opt_val_set) { ++ print " ptr->x_param_large_function_growth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_large_function_growth ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_large_function_insns" in var_opt_val_set) { ++ print " ptr->x_param_large_function_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2700 > (int ) 10)" ++ print " ptr->x_param_large_function_insns ^= 2700;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_stack_frame_growth" in var_opt_val_set) { ++ print " ptr->x_param_stack_frame_growth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_stack_frame_growth ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_large_stack_frame" in var_opt_val_set) { ++ print " ptr->x_param_large_stack_frame = (int ) bp_unpack_var_len_int (bp);" ++ print " if (256 > (int ) 10)" ++ print " ptr->x_param_large_stack_frame ^= 256;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_large_unit_insns" in var_opt_val_set) { ++ print " ptr->x_param_large_unit_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10000 > (int ) 10)" ++ print " ptr->x_param_large_unit_insns ^= 10000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_lim_expensive" in var_opt_val_set) { ++ print " ptr->x_param_lim_expensive = (int ) bp_unpack_var_len_int (bp);" ++ print " if (20 > (int ) 10)" ++ print " ptr->x_param_lim_expensive ^= 20;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_block_tile_size" in var_opt_val_set) { ++ print " ptr->x_param_loop_block_tile_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (51 > (int ) 10)" ++ print " ptr->x_param_loop_block_tile_size ^= 51;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_interchange_max_num_stmts" in var_opt_val_set) { ++ print " ptr->x_param_loop_interchange_max_num_stmts = (int ) bp_unpack_var_len_int (bp);" ++ print " if (64 > (int ) 10)" ++ print " ptr->x_param_loop_interchange_max_num_stmts ^= 64;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_interchange_stride_ratio" in var_opt_val_set) { ++ print " ptr->x_param_loop_interchange_stride_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_loop_interchange_stride_ratio ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_invariant_max_bbs_in_loop" in var_opt_val_set) { ++ print " ptr->x_param_loop_invariant_max_bbs_in_loop = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10000 > (int ) 10)" ++ print " ptr->x_param_loop_invariant_max_bbs_in_loop ^= 10000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_max_datarefs_for_datadeps" in var_opt_val_set) { ++ print " ptr->x_param_loop_max_datarefs_for_datadeps = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_loop_max_datarefs_for_datadeps ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_versioning_max_inner_insns" in var_opt_val_set) { ++ print " ptr->x_param_loop_versioning_max_inner_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_loop_versioning_max_inner_insns ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_loop_versioning_max_outer_insns" in var_opt_val_set) { ++ print " ptr->x_param_loop_versioning_max_outer_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_loop_versioning_max_outer_insns ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_lra_inheritance_ebb_probability_cutoff" in var_opt_val_set) { ++ print " ptr->x_param_lra_inheritance_ebb_probability_cutoff = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_lra_inheritance_ebb_probability_cutoff ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_lra_max_considered_reload_pseudos" in var_opt_val_set) { ++ print " ptr->x_param_lra_max_considered_reload_pseudos = (int ) bp_unpack_var_len_int (bp);" ++ print " if (500 > (int ) 10)" ++ print " ptr->x_param_lra_max_considered_reload_pseudos ^= 500;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_average_unrolled_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_average_unrolled_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (80 > (int ) 10)" ++ print " ptr->x_param_max_average_unrolled_insns ^= 80;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_combine_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_combine_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4 > (int ) 10)" ++ print " ptr->x_param_max_combine_insns ^= 4;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_unroll_iterations" in var_opt_val_set) { ++ print " ptr->x_param_max_unroll_iterations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_max_unroll_iterations ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_completely_peel_times" in var_opt_val_set) { ++ print " ptr->x_param_max_completely_peel_times = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_max_completely_peel_times ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_completely_peeled_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_completely_peeled_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_max_completely_peeled_insns ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_crossjump_edges" in var_opt_val_set) { ++ print " ptr->x_param_max_crossjump_edges = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_crossjump_edges ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_cse_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_cse_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_max_cse_insns ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_cse_path_length" in var_opt_val_set) { ++ print " ptr->x_param_max_cse_path_length = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_cse_path_length ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_cselib_memory_locations" in var_opt_val_set) { ++ print " ptr->x_param_max_cselib_memory_locations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (500 > (int ) 10)" ++ print " ptr->x_param_max_cselib_memory_locations ^= 500;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_debug_marker_count" in var_opt_val_set) { ++ print " ptr->x_param_max_debug_marker_count = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100000 > (int ) 10)" ++ print " ptr->x_param_max_debug_marker_count ^= 100000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_delay_slot_insn_search" in var_opt_val_set) { ++ print " ptr->x_param_max_delay_slot_insn_search = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_delay_slot_insn_search ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_delay_slot_live_search" in var_opt_val_set) { ++ print " ptr->x_param_max_delay_slot_live_search = (int ) bp_unpack_var_len_int (bp);" ++ print " if (333 > (int ) 10)" ++ print " ptr->x_param_max_delay_slot_live_search ^= 333;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_dse_active_local_stores" in var_opt_val_set) { ++ print " ptr->x_param_max_dse_active_local_stores = (int ) bp_unpack_var_len_int (bp);" ++ print " if (5000 > (int ) 10)" ++ print " ptr->x_param_max_dse_active_local_stores ^= 5000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_early_inliner_max_iterations" in var_opt_val_set) { ++ print " ptr->x_param_early_inliner_max_iterations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_early_inliner_max_iterations ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_find_base_term_values" in var_opt_val_set) { ++ print " ptr->x_param_max_find_base_term_values = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_max_find_base_term_values ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_fsm_thread_length" in var_opt_val_set) { ++ print " ptr->x_param_max_fsm_thread_length = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_fsm_thread_length ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_fsm_thread_path_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_fsm_thread_path_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_fsm_thread_path_insns ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_gcse_insertion_ratio" in var_opt_val_set) { ++ print " ptr->x_param_max_gcse_insertion_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (20 > (int ) 10)" ++ print " ptr->x_param_max_gcse_insertion_ratio ^= 20;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_gcse_memory" in var_opt_val_set) { ++ print " ptr->x_param_max_gcse_memory = (int ) bp_unpack_var_len_int (bp);" ++ print " if (131072 > (int ) 10)" ++ print " ptr->x_param_max_gcse_memory ^= 131072;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_goto_duplication_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_goto_duplication_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_max_goto_duplication_insns ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_grow_copy_bb_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_grow_copy_bb_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_max_grow_copy_bb_insns ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_hoist_depth" in var_opt_val_set) { ++ print " ptr->x_param_max_hoist_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (30 > (int ) 10)" ++ print " ptr->x_param_max_hoist_depth ^= 30;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_inline_functions_called_once_insns" in var_opt_val_set) { ++ print " ptr->x_param_inline_functions_called_once_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4000 > (int ) 10)" ++ print " ptr->x_param_inline_functions_called_once_insns ^= 4000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_inline_functions_called_once_loop_depth" in var_opt_val_set) { ++ print " ptr->x_param_inline_functions_called_once_loop_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (6 > (int ) 10)" ++ print " ptr->x_param_inline_functions_called_once_loop_depth ^= 6;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_insns_auto" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_insns_auto = (int ) bp_unpack_var_len_int (bp);" ++ print " if (15 > (int ) 10)" ++ print " ptr->x_param_max_inline_insns_auto ^= 15;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_insns_recursive_auto" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_insns_recursive_auto = (int ) bp_unpack_var_len_int (bp);" ++ print " if (450 > (int ) 10)" ++ print " ptr->x_param_max_inline_insns_recursive_auto ^= 450;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_insns_recursive" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_insns_recursive = (int ) bp_unpack_var_len_int (bp);" ++ print " if (450 > (int ) 10)" ++ print " ptr->x_param_max_inline_insns_recursive ^= 450;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_insns_single" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_insns_single = (int ) bp_unpack_var_len_int (bp);" ++ print " if (70 > (int ) 10)" ++ print " ptr->x_param_max_inline_insns_single ^= 70;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_insns_size" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_insns_size = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_insns_small" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_insns_small = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_recursive_depth_auto" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_recursive_depth_auto = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_max_inline_recursive_depth_auto ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_inline_recursive_depth" in var_opt_val_set) { ++ print " ptr->x_param_max_inline_recursive_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_max_inline_recursive_depth ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_isl_operations" in var_opt_val_set) { ++ print " ptr->x_param_max_isl_operations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (350000 > (int ) 10)" ++ print " ptr->x_param_max_isl_operations ^= 350000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_iterations_computation_cost" in var_opt_val_set) { ++ print " ptr->x_param_max_iterations_computation_cost = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_iterations_computation_cost ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_iterations_to_track" in var_opt_val_set) { ++ print " ptr->x_param_max_iterations_to_track = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_max_iterations_to_track ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_jump_thread_duplication_stmts" in var_opt_val_set) { ++ print " ptr->x_param_max_jump_thread_duplication_stmts = (int ) bp_unpack_var_len_int (bp);" ++ print " if (15 > (int ) 10)" ++ print " ptr->x_param_max_jump_thread_duplication_stmts ^= 15;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_last_value_rtl" in var_opt_val_set) { ++ print " ptr->x_param_max_last_value_rtl = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10000 > (int ) 10)" ++ print " ptr->x_param_max_last_value_rtl ^= 10000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_loop_header_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_loop_header_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (20 > (int ) 10)" ++ print " ptr->x_param_max_loop_header_insns ^= 20;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_modulo_backtrack_attempts" in var_opt_val_set) { ++ print " ptr->x_param_max_modulo_backtrack_attempts = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_max_modulo_backtrack_attempts ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_partial_antic_length" in var_opt_val_set) { ++ print " ptr->x_param_max_partial_antic_length = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_partial_antic_length ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_peel_branches" in var_opt_val_set) { ++ print " ptr->x_param_max_peel_branches = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_max_peel_branches ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_peel_times" in var_opt_val_set) { ++ print " ptr->x_param_max_peel_times = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_max_peel_times ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_peeled_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_peeled_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_peeled_insns ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_pending_list_length" in var_opt_val_set) { ++ print " ptr->x_param_max_pending_list_length = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_max_pending_list_length ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_pipeline_region_blocks" in var_opt_val_set) { ++ print " ptr->x_param_max_pipeline_region_blocks = (int ) bp_unpack_var_len_int (bp);" ++ print " if (15 > (int ) 10)" ++ print " ptr->x_param_max_pipeline_region_blocks ^= 15;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_pipeline_region_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_pipeline_region_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_max_pipeline_region_insns ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_pow_sqrt_depth" in var_opt_val_set) { ++ print " ptr->x_param_max_pow_sqrt_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (5 > (int ) 10)" ++ print " ptr->x_param_max_pow_sqrt_depth ^= 5;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_predicted_iterations" in var_opt_val_set) { ++ print " ptr->x_param_max_predicted_iterations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_predicted_iterations ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_reload_search_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_reload_search_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_reload_search_insns ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_rtl_if_conversion_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_rtl_if_conversion_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_rtl_if_conversion_insns ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_rtl_if_conversion_predictable_cost" in var_opt_val_set) { ++ print " ptr->x_param_max_rtl_if_conversion_predictable_cost = (int ) bp_unpack_var_len_int (bp);" ++ print " if (20 > (int ) 10)" ++ print " ptr->x_param_max_rtl_if_conversion_predictable_cost ^= 20;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_rtl_if_conversion_unpredictable_cost" in var_opt_val_set) { ++ print " ptr->x_param_max_rtl_if_conversion_unpredictable_cost = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_max_rtl_if_conversion_unpredictable_cost ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_sched_extend_regions_iters" in var_opt_val_set) { ++ print " ptr->x_param_max_sched_extend_regions_iters = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_sched_insn_conflict_delay" in var_opt_val_set) { ++ print " ptr->x_param_max_sched_insn_conflict_delay = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_max_sched_insn_conflict_delay ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_sched_ready_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_sched_ready_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_sched_ready_insns ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_sched_region_blocks" in var_opt_val_set) { ++ print " ptr->x_param_max_sched_region_blocks = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_sched_region_blocks ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_sched_region_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_sched_region_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_max_sched_region_insns ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_slsr_candidate_scan" in var_opt_val_set) { ++ print " ptr->x_param_max_slsr_candidate_scan = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_max_slsr_candidate_scan ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_speculative_devirt_maydefs" in var_opt_val_set) { ++ print " ptr->x_param_max_speculative_devirt_maydefs = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_max_speculative_devirt_maydefs ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_stores_to_merge" in var_opt_val_set) { ++ print " ptr->x_param_max_stores_to_merge = (int ) bp_unpack_var_len_int (bp);" ++ print " if (64 > (int ) 10)" ++ print " ptr->x_param_max_stores_to_merge ^= 64;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_stores_to_sink" in var_opt_val_set) { ++ print " ptr->x_param_max_stores_to_sink = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_max_stores_to_sink ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_tail_merge_comparisons" in var_opt_val_set) { ++ print " ptr->x_param_max_tail_merge_comparisons = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_tail_merge_comparisons ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_tail_merge_iterations" in var_opt_val_set) { ++ print " ptr->x_param_max_tail_merge_iterations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_max_tail_merge_iterations ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_tracked_strlens" in var_opt_val_set) { ++ print " ptr->x_param_max_tracked_strlens = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10000 > (int ) 10)" ++ print " ptr->x_param_max_tracked_strlens ^= 10000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_tree_if_conversion_phi_args" in var_opt_val_set) { ++ print " ptr->x_param_max_tree_if_conversion_phi_args = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4 > (int ) 10)" ++ print " ptr->x_param_max_tree_if_conversion_phi_args ^= 4;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_unroll_times" in var_opt_val_set) { ++ print " ptr->x_param_max_unroll_times = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_max_unroll_times ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_unrolled_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_unrolled_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_max_unrolled_insns ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_unswitch_insns" in var_opt_val_set) { ++ print " ptr->x_param_max_unswitch_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_max_unswitch_insns ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_unswitch_level" in var_opt_val_set) { ++ print " ptr->x_param_max_unswitch_level = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_max_unswitch_level ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_variable_expansions" in var_opt_val_set) { ++ print " ptr->x_param_max_variable_expansions = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_max_variable_expansions ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_vartrack_expr_depth" in var_opt_val_set) { ++ print " ptr->x_param_max_vartrack_expr_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (12 > (int ) 10)" ++ print " ptr->x_param_max_vartrack_expr_depth ^= 12;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_vartrack_reverse_op_size" in var_opt_val_set) { ++ print " ptr->x_param_max_vartrack_reverse_op_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_max_vartrack_reverse_op_size ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_vartrack_size" in var_opt_val_set) { ++ print " ptr->x_param_max_vartrack_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50000000 > (int ) 10)" ++ print " ptr->x_param_max_vartrack_size ^= 50000000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_max_vrp_switch_assertions" in var_opt_val_set) { ++ print " ptr->x_param_max_vrp_switch_assertions = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_max_vrp_switch_assertions ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_crossjump_insns" in var_opt_val_set) { ++ print " ptr->x_param_min_crossjump_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (5 > (int ) 10)" ++ print " ptr->x_param_min_crossjump_insns ^= 5;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_inline_recursive_probability" in var_opt_val_set) { ++ print " ptr->x_param_min_inline_recursive_probability = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_min_inline_recursive_probability ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_insn_to_prefetch_ratio" in var_opt_val_set) { ++ print " ptr->x_param_min_insn_to_prefetch_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (9 > (int ) 10)" ++ print " ptr->x_param_min_insn_to_prefetch_ratio ^= 9;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_loop_cond_split_prob" in var_opt_val_set) { ++ print " ptr->x_param_min_loop_cond_split_prob = (int ) bp_unpack_var_len_int (bp);" ++ print " if (30 > (int ) 10)" ++ print " ptr->x_param_min_loop_cond_split_prob ^= 30;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_pagesize" in var_opt_val_set) { ++ print " ptr->x_param_min_pagesize = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4096 > (int ) 10)" ++ print " ptr->x_param_min_pagesize ^= 4096;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_size_for_stack_sharing" in var_opt_val_set) { ++ print " ptr->x_param_min_size_for_stack_sharing = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_min_size_for_stack_sharing ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_spec_prob" in var_opt_val_set) { ++ print " ptr->x_param_min_spec_prob = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_min_spec_prob ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_min_vect_loop_bound" in var_opt_val_set) { ++ print " ptr->x_param_min_vect_loop_bound = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_accesses" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_accesses = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_modref_max_accesses ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_adjustments" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_adjustments = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_modref_max_adjustments ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_bases" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_bases = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_modref_max_bases ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_depth" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (256 > (int ) 10)" ++ print " ptr->x_param_modref_max_depth ^= 256;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_escape_points" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_escape_points = (int ) bp_unpack_var_len_int (bp);" ++ print " if (256 > (int ) 10)" ++ print " ptr->x_param_modref_max_escape_points ^= 256;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_refs" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_refs = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_modref_max_refs ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_modref_max_tests" in var_opt_val_set) { ++ print " ptr->x_param_modref_max_tests = (int ) bp_unpack_var_len_int (bp);" ++ print " if (64 > (int ) 10)" ++ print " ptr->x_param_modref_max_tests ^= 64;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ldp_dependency_search_range" in var_opt_val_set) { ++ print " ptr->x_param_ldp_dependency_search_range = (int ) bp_unpack_var_len_int (bp);" ++ print " if (16 > (int ) 10)" ++ print " ptr->x_param_ldp_dependency_search_range ^= 16;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_parloops_chunk_size" in var_opt_val_set) { ++ print " ptr->x_param_parloops_chunk_size = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_parloops_min_per_thread" in var_opt_val_set) { ++ print " ptr->x_param_parloops_min_per_thread = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_parloops_min_per_thread ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_parloops_schedule" in var_opt_val_set) { ++ print " ptr->x_param_parloops_schedule = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_partial_inlining_entry_probability" in var_opt_val_set) { ++ print " ptr->x_param_partial_inlining_entry_probability = (int ) bp_unpack_var_len_int (bp);" ++ print " if (70 > (int ) 10)" ++ print " ptr->x_param_partial_inlining_entry_probability ^= 70;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_predictable_branch_outcome" in var_opt_val_set) { ++ print " ptr->x_param_predictable_branch_outcome = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_predictable_branch_outcome ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_prefetch_dynamic_strides" in var_opt_val_set) { ++ print " ptr->x_param_prefetch_dynamic_strides = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_prefetch_dynamic_strides ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_prefetch_latency" in var_opt_val_set) { ++ print " ptr->x_param_prefetch_latency = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_prefetch_latency ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_prefetch_min_insn_to_mem_ratio" in var_opt_val_set) { ++ print " ptr->x_param_prefetch_min_insn_to_mem_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_prefetch_min_insn_to_mem_ratio ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_prefetch_minimum_stride" in var_opt_val_set) { ++ print " ptr->x_param_prefetch_minimum_stride = (int ) bp_unpack_var_len_int (bp);" ++ print " if (-1 > (int ) 10)" ++ print " ptr->x_param_prefetch_minimum_stride ^= -1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ranger_debug" in var_opt_val_set) { ++ print " ptr->x_param_ranger_debug = (enum ranger_debug ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ranger_logical_depth" in var_opt_val_set) { ++ print " ptr->x_param_ranger_logical_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (6 > (int ) 10)" ++ print " ptr->x_param_ranger_logical_depth ^= 6;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_relation_block_limit" in var_opt_val_set) { ++ print " ptr->x_param_relation_block_limit = (int ) bp_unpack_var_len_int (bp);" ++ print " if (200 > (int ) 10)" ++ print " ptr->x_param_relation_block_limit ^= 200;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_rpo_vn_max_loop_depth" in var_opt_val_set) { ++ print " ptr->x_param_rpo_vn_max_loop_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (7 > (int ) 10)" ++ print " ptr->x_param_rpo_vn_max_loop_depth ^= 7;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sccvn_max_alias_queries_per_access" in var_opt_val_set) { ++ print " ptr->x_param_sccvn_max_alias_queries_per_access = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_sccvn_max_alias_queries_per_access ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_scev_max_expr_complexity" in var_opt_val_set) { ++ print " ptr->x_param_scev_max_expr_complexity = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_scev_max_expr_complexity ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_scev_max_expr_size" in var_opt_val_set) { ++ print " ptr->x_param_scev_max_expr_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_scev_max_expr_size ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sched_autopref_queue_depth" in var_opt_val_set) { ++ print " ptr->x_param_sched_autopref_queue_depth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (-1 > (int ) 10)" ++ print " ptr->x_param_sched_autopref_queue_depth ^= -1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sched_mem_true_dep_cost" in var_opt_val_set) { ++ print " ptr->x_param_sched_mem_true_dep_cost = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_sched_mem_true_dep_cost ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sched_pressure_algorithm" in var_opt_val_set) { ++ print " ptr->x_param_sched_pressure_algorithm = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_sched_pressure_algorithm ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sched_spec_prob_cutoff" in var_opt_val_set) { ++ print " ptr->x_param_sched_spec_prob_cutoff = (int ) bp_unpack_var_len_int (bp);" ++ print " if (40 > (int ) 10)" ++ print " ptr->x_param_sched_spec_prob_cutoff ^= 40;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sched_state_edge_prob_cutoff" in var_opt_val_set) { ++ print " ptr->x_param_sched_state_edge_prob_cutoff = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_sched_state_edge_prob_cutoff ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_selsched_insns_to_rename" in var_opt_val_set) { ++ print " ptr->x_param_selsched_insns_to_rename = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_selsched_insns_to_rename ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_selsched_max_lookahead" in var_opt_val_set) { ++ print " ptr->x_param_selsched_max_lookahead = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_selsched_max_lookahead ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_selsched_max_sched_times" in var_opt_val_set) { ++ print " ptr->x_param_selsched_max_sched_times = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_selsched_max_sched_times ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_semi_relayout_level" in var_opt_val_set) { ++ print " ptr->x_semi_relayout_level = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_simultaneous_prefetches" in var_opt_val_set) { ++ print " ptr->x_param_simultaneous_prefetches = (int ) bp_unpack_var_len_int (bp);" ++ print " if (3 > (int ) 10)" ++ print " ptr->x_param_simultaneous_prefetches ^= 3;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sink_frequency_threshold" in var_opt_val_set) { ++ print " ptr->x_param_sink_frequency_threshold = (int ) bp_unpack_var_len_int (bp);" ++ print " if (75 > (int ) 10)" ++ print " ptr->x_param_sink_frequency_threshold ^= 75;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sms_dfa_history" in var_opt_val_set) { ++ print " ptr->x_param_sms_dfa_history = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sms_loop_average_count_threshold" in var_opt_val_set) { ++ print " ptr->x_param_sms_loop_average_count_threshold = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sms_max_ii_factor" in var_opt_val_set) { ++ print " ptr->x_param_sms_max_ii_factor = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_sms_max_ii_factor ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sms_min_sc" in var_opt_val_set) { ++ print " ptr->x_param_sms_min_sc = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_sms_min_sc ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sra_max_propagations" in var_opt_val_set) { ++ print " ptr->x_param_sra_max_propagations = (int ) bp_unpack_var_len_int (bp);" ++ print " if (32 > (int ) 10)" ++ print " ptr->x_param_sra_max_propagations ^= 32;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sra_max_scalarization_size_size" in var_opt_val_set) { ++ print " ptr->x_param_sra_max_scalarization_size_size = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_sra_max_scalarization_size_speed" in var_opt_val_set) { ++ print " ptr->x_param_sra_max_scalarization_size_speed = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ssa_name_def_chain_limit" in var_opt_val_set) { ++ print " ptr->x_param_ssa_name_def_chain_limit = (int ) bp_unpack_var_len_int (bp);" ++ print " if (512 > (int ) 10)" ++ print " ptr->x_param_ssa_name_def_chain_limit ^= 512;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_ssp_buffer_size" in var_opt_val_set) { ++ print " ptr->x_param_ssp_buffer_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_ssp_buffer_size ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_stack_clash_protection_guard_size" in var_opt_val_set) { ++ print " ptr->x_param_stack_clash_protection_guard_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (12 > (int ) 10)" ++ print " ptr->x_param_stack_clash_protection_guard_size ^= 12;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_stack_clash_protection_probe_interval" in var_opt_val_set) { ++ print " ptr->x_param_stack_clash_protection_probe_interval = (int ) bp_unpack_var_len_int (bp);" ++ print " if (12 > (int ) 10)" ++ print " ptr->x_param_stack_clash_protection_probe_interval ^= 12;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_store_merging_allow_unaligned" in var_opt_val_set) { ++ print " ptr->x_param_store_merging_allow_unaligned = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_store_merging_allow_unaligned ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_store_merging_max_size" in var_opt_val_set) { ++ print " ptr->x_param_store_merging_max_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (65536 > (int ) 10)" ++ print " ptr->x_param_store_merging_max_size ^= 65536;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_struct_reorg_cold_struct_ratio" in var_opt_val_set) { ++ print " ptr->x_param_struct_reorg_cold_struct_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_struct_reorg_cold_struct_ratio ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_switch_conversion_branch_ratio" in var_opt_val_set) { ++ print " ptr->x_param_switch_conversion_branch_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (8 > (int ) 10)" ++ print " ptr->x_param_switch_conversion_branch_ratio ^= 8;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_threader_debug" in var_opt_val_set) { ++ print " ptr->x_param_threader_debug = (enum threader_debug ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tm_max_aggregate_size" in var_opt_val_set) { ++ print " ptr->x_param_tm_max_aggregate_size = (int ) bp_unpack_var_len_int (bp);" ++ print " if (9 > (int ) 10)" ++ print " ptr->x_param_tm_max_aggregate_size ^= 9;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tracer_dynamic_coverage_feedback" in var_opt_val_set) { ++ print " ptr->x_param_tracer_dynamic_coverage_feedback = (int ) bp_unpack_var_len_int (bp);" ++ print " if (95 > (int ) 10)" ++ print " ptr->x_param_tracer_dynamic_coverage_feedback ^= 95;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tracer_dynamic_coverage" in var_opt_val_set) { ++ print " ptr->x_param_tracer_dynamic_coverage = (int ) bp_unpack_var_len_int (bp);" ++ print " if (75 > (int ) 10)" ++ print " ptr->x_param_tracer_dynamic_coverage ^= 75;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tracer_max_code_growth" in var_opt_val_set) { ++ print " ptr->x_param_tracer_max_code_growth = (int ) bp_unpack_var_len_int (bp);" ++ print " if (100 > (int ) 10)" ++ print " ptr->x_param_tracer_max_code_growth ^= 100;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tracer_min_branch_probability_feedback" in var_opt_val_set) { ++ print " ptr->x_param_tracer_min_branch_probability_feedback = (int ) bp_unpack_var_len_int (bp);" ++ print " if (80 > (int ) 10)" ++ print " ptr->x_param_tracer_min_branch_probability_feedback ^= 80;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tracer_min_branch_probability" in var_opt_val_set) { ++ print " ptr->x_param_tracer_min_branch_probability = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_tracer_min_branch_probability ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tracer_min_branch_ratio" in var_opt_val_set) { ++ print " ptr->x_param_tracer_min_branch_ratio = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_tracer_min_branch_ratio ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_tree_reassoc_width" in var_opt_val_set) { ++ print " ptr->x_param_tree_reassoc_width = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_uninit_control_dep_attempts" in var_opt_val_set) { ++ print " ptr->x_param_uninit_control_dep_attempts = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1000 > (int ) 10)" ++ print " ptr->x_param_uninit_control_dep_attempts ^= 1000;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_uninlined_function_insns" in var_opt_val_set) { ++ print " ptr->x_param_uninlined_function_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_uninlined_function_insns ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_uninlined_function_time" in var_opt_val_set) { ++ print " ptr->x_param_uninlined_function_time = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_uninlined_function_thunk_insns" in var_opt_val_set) { ++ print " ptr->x_param_uninlined_function_thunk_insns = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_uninlined_function_thunk_insns ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_uninlined_function_thunk_time" in var_opt_val_set) { ++ print " ptr->x_param_uninlined_function_thunk_time = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_uninlined_function_thunk_time ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_unlikely_bb_count_fraction" in var_opt_val_set) { ++ print " ptr->x_param_unlikely_bb_count_fraction = (int ) bp_unpack_var_len_int (bp);" ++ print " if (20 > (int ) 10)" ++ print " ptr->x_param_unlikely_bb_count_fraction ^= 20;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_unroll_jam_max_unroll" in var_opt_val_set) { ++ print " ptr->x_param_unroll_jam_max_unroll = (int ) bp_unpack_var_len_int (bp);" ++ print " if (4 > (int ) 10)" ++ print " ptr->x_param_unroll_jam_max_unroll ^= 4;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_unroll_jam_min_percent" in var_opt_val_set) { ++ print " ptr->x_param_unroll_jam_min_percent = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_unroll_jam_min_percent ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_use_after_scope_direct_emission_threshold" in var_opt_val_set) { ++ print " ptr->x_param_use_after_scope_direct_emission_threshold = (int ) bp_unpack_var_len_int (bp);" ++ print " if (256 > (int ) 10)" ++ print " ptr->x_param_use_after_scope_direct_emission_threshold ^= 256;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_flexible_seg_len" in var_opt_val_set) { ++ print " ptr->x_param_flexible_seg_len = (int ) bp_unpack_var_len_int (bp);" ++ print " if (0 > (int ) 10)" ++ print " ptr->x_param_flexible_seg_len ^= 0;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_epilogues_nomask" in var_opt_val_set) { ++ print " ptr->x_param_vect_epilogues_nomask = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_vect_epilogues_nomask ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_induction_float" in var_opt_val_set) { ++ print " ptr->x_param_vect_induction_float = (int ) bp_unpack_var_len_int (bp);" ++ print " if (1 > (int ) 10)" ++ print " ptr->x_param_vect_induction_float ^= 1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_inner_loop_cost_factor" in var_opt_val_set) { ++ print " ptr->x_param_vect_inner_loop_cost_factor = (int ) bp_unpack_var_len_int (bp);" ++ print " if (50 > (int ) 10)" ++ print " ptr->x_param_vect_inner_loop_cost_factor ^= 50;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_max_peeling_for_alignment" in var_opt_val_set) { ++ print " ptr->x_param_vect_max_peeling_for_alignment = (int ) bp_unpack_var_len_int (bp);" ++ print " if (-1 > (int ) 10)" ++ print " ptr->x_param_vect_max_peeling_for_alignment ^= -1;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_max_version_for_alias_checks" in var_opt_val_set) { ++ print " ptr->x_param_vect_max_version_for_alias_checks = (int ) bp_unpack_var_len_int (bp);" ++ print " if (10 > (int ) 10)" ++ print " ptr->x_param_vect_max_version_for_alias_checks ^= 10;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_max_version_for_alignment_checks" in var_opt_val_set) { ++ print " ptr->x_param_vect_max_version_for_alignment_checks = (int ) bp_unpack_var_len_int (bp);" ++ print " if (6 > (int ) 10)" ++ print " ptr->x_param_vect_max_version_for_alignment_checks ^= 6;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vect_partial_vector_usage" in var_opt_val_set) { ++ print " ptr->x_param_vect_partial_vector_usage = (int ) bp_unpack_var_len_int (bp);" ++ print " if (2 > (int ) 10)" ++ print " ptr->x_param_vect_partial_vector_usage ^= 2;" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vrp1_mode" in var_opt_val_set) { ++ print " ptr->x_param_vrp1_mode = (enum vrp_mode ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_param_vrp2_mode" in var_opt_val_set) { ++ print " ptr->x_param_vrp2_mode = (enum vrp_mode ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_warn_inline" in var_opt_val_set) { ++ print " ptr->x_warn_inline = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_aggressive_loop_optimizations" in var_opt_val_set) { ++ print " ptr->x_flag_aggressive_loop_optimizations = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_align_functions" in var_opt_val_set) { ++ print " ptr->x_flag_align_functions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_str_align_functions" in var_opt_val_set) { ++ print " ptr->x_str_align_functions = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_str_align_functions)" ++ print " ptr->x_str_align_functions = xstrdup (ptr->x_str_align_functions);" ++} ++else ++ print " bp_unpack_string (data_in, bp);" ++if ("x_flag_align_jumps" in var_opt_val_set) { ++ print " ptr->x_flag_align_jumps = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_str_align_jumps" in var_opt_val_set) { ++ print " ptr->x_str_align_jumps = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_str_align_jumps)" ++ print " ptr->x_str_align_jumps = xstrdup (ptr->x_str_align_jumps);" ++} ++else ++ print " bp_unpack_string (data_in, bp);" ++if ("x_flag_align_labels" in var_opt_val_set) { ++ print " ptr->x_flag_align_labels = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_str_align_labels" in var_opt_val_set) { ++ print " ptr->x_str_align_labels = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_str_align_labels)" ++ print " ptr->x_str_align_labels = xstrdup (ptr->x_str_align_labels);" ++} ++else ++ print " bp_unpack_string (data_in, bp);" ++if ("x_flag_align_loops" in var_opt_val_set) { ++ print " ptr->x_flag_align_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_str_align_loops" in var_opt_val_set) { ++ print " ptr->x_str_align_loops = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_str_align_loops)" ++ print " ptr->x_str_align_loops = xstrdup (ptr->x_str_align_loops);" ++} ++else ++ print " bp_unpack_string (data_in, bp);" ++if ("x_flag_allocation_dce" in var_opt_val_set) { ++ print " ptr->x_flag_allocation_dce = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_store_data_races" in var_opt_val_set) { ++ print " ptr->x_flag_store_data_races = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_array_widen_compare" in var_opt_val_set) { ++ print " ptr->x_flag_array_widen_compare = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_associative_math" in var_opt_val_set) { ++ print " ptr->x_flag_associative_math = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_asynchronous_unwind_tables" in var_opt_val_set) { ++ print " ptr->x_flag_asynchronous_unwind_tables = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_auto_inc_dec" in var_opt_val_set) { ++ print " ptr->x_flag_auto_inc_dec = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_bit_tests" in var_opt_val_set) { ++ print " ptr->x_flag_bit_tests = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_branch_on_count_reg" in var_opt_val_set) { ++ print " ptr->x_flag_branch_on_count_reg = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_branch_probabilities" in var_opt_val_set) { ++ print " ptr->x_flag_branch_probabilities = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_caller_saves" in var_opt_val_set) { ++ print " ptr->x_flag_caller_saves = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ccmp2" in var_opt_val_set) { ++ print " ptr->x_flag_ccmp2 = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_code_hoisting" in var_opt_val_set) { ++ print " ptr->x_flag_code_hoisting = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_combine_stack_adjustments" in var_opt_val_set) { ++ print " ptr->x_flag_combine_stack_adjustments = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_compare_elim_after_reload" in var_opt_val_set) { ++ print " ptr->x_flag_compare_elim_after_reload = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_conserve_stack" in var_opt_val_set) { ++ print " ptr->x_flag_conserve_stack = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_convert_minmax" in var_opt_val_set) { ++ print " ptr->x_flag_convert_minmax = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_cprop_registers" in var_opt_val_set) { ++ print " ptr->x_flag_cprop_registers = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_crossjumping" in var_opt_val_set) { ++ print " ptr->x_flag_crossjumping = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_crypto_accel_aes" in var_opt_val_set) { ++ print " ptr->x_flag_crypto_accel_aes = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_cse_follow_jumps" in var_opt_val_set) { ++ print " ptr->x_flag_cse_follow_jumps = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_cx_fortran_rules" in var_opt_val_set) { ++ print " ptr->x_flag_cx_fortran_rules = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_cx_limited_range" in var_opt_val_set) { ++ print " ptr->x_flag_cx_limited_range = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_dce" in var_opt_val_set) { ++ print " ptr->x_flag_dce = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_defer_pop" in var_opt_val_set) { ++ print " ptr->x_flag_defer_pop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_delayed_branch" in var_opt_val_set) { ++ print " ptr->x_flag_delayed_branch = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_delete_dead_exceptions" in var_opt_val_set) { ++ print " ptr->x_flag_delete_dead_exceptions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_delete_null_pointer_checks" in var_opt_val_set) { ++ print " ptr->x_flag_delete_null_pointer_checks = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_devirtualize" in var_opt_val_set) { ++ print " ptr->x_flag_devirtualize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_devirtualize_speculatively" in var_opt_val_set) { ++ print " ptr->x_flag_devirtualize_speculatively = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_dse" in var_opt_val_set) { ++ print " ptr->x_flag_dse = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_early_inlining" in var_opt_val_set) { ++ print " ptr->x_flag_early_inlining = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_exceptions" in var_opt_val_set) { ++ print " ptr->x_flag_exceptions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_excess_precision" in var_opt_val_set) { ++ print " ptr->x_flag_excess_precision = (enum excess_precision ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_expensive_optimizations" in var_opt_val_set) { ++ print " ptr->x_flag_expensive_optimizations = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_finite_loops" in var_opt_val_set) { ++ print " ptr->x_flag_finite_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_finite_math_only" in var_opt_val_set) { ++ print " ptr->x_flag_finite_math_only = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_float_store" in var_opt_val_set) { ++ print " ptr->x_flag_float_store = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_fold_simple_inlines" in var_opt_val_set) { ++ print " ptr->x_flag_fold_simple_inlines = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_forward_propagate" in var_opt_val_set) { ++ print " ptr->x_flag_forward_propagate = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_fp_contract_mode" in var_opt_val_set) { ++ print " ptr->x_flag_fp_contract_mode = (enum fp_contract_mode ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_fp_int_builtin_inexact" in var_opt_val_set) { ++ print " ptr->x_flag_fp_int_builtin_inexact = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ftz" in var_opt_val_set) { ++ print " ptr->x_flag_ftz = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_no_function_cse" in var_opt_val_set) { ++ print " ptr->x_flag_no_function_cse = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_gcse" in var_opt_val_set) { ++ print " ptr->x_flag_gcse = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_gcse_after_reload" in var_opt_val_set) { ++ print " ptr->x_flag_gcse_after_reload = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_gcse_las" in var_opt_val_set) { ++ print " ptr->x_flag_gcse_las = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_gcse_lm" in var_opt_val_set) { ++ print " ptr->x_flag_gcse_lm = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_gcse_sm" in var_opt_val_set) { ++ print " ptr->x_flag_gcse_sm = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_graphite" in var_opt_val_set) { ++ print " ptr->x_flag_graphite = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_graphite_identity" in var_opt_val_set) { ++ print " ptr->x_flag_graphite_identity = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_guess_branch_prob" in var_opt_val_set) { ++ print " ptr->x_flag_guess_branch_prob = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_harden_compares" in var_opt_val_set) { ++ print " ptr->x_flag_harden_compares = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_harden_conditional_branches" in var_opt_val_set) { ++ print " ptr->x_flag_harden_conditional_branches = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_hoist_adjacent_loads" in var_opt_val_set) { ++ print " ptr->x_flag_hoist_adjacent_loads = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_icp" in var_opt_val_set) { ++ print " ptr->x_flag_icp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_icp_speculatively" in var_opt_val_set) { ++ print " ptr->x_flag_icp_speculatively = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_if_conversion" in var_opt_val_set) { ++ print " ptr->x_flag_if_conversion = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_if_conversion_gimple" in var_opt_val_set) { ++ print " ptr->x_flag_if_conversion_gimple = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_if_conversion2" in var_opt_val_set) { ++ print " ptr->x_flag_if_conversion2 = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ifcvt_allow_complicated_cmps" in var_opt_val_set) { ++ print " ptr->x_flag_ifcvt_allow_complicated_cmps = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_indirect_inlining" in var_opt_val_set) { ++ print " ptr->x_flag_indirect_inlining = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_no_inline" in var_opt_val_set) { ++ print " ptr->x_flag_no_inline = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_inline_atomics" in var_opt_val_set) { ++ print " ptr->x_flag_inline_atomics = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_inline_functions" in var_opt_val_set) { ++ print " ptr->x_flag_inline_functions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_inline_functions_called_once" in var_opt_val_set) { ++ print " ptr->x_flag_inline_functions_called_once = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_inline_small_functions" in var_opt_val_set) { ++ print " ptr->x_flag_inline_small_functions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_bit_cp" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_bit_cp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_cp" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_cp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_cp_clone" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_cp_clone = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_ic" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_ic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_icf" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_icf = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_icf_functions" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_icf_functions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_icf_variables" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_icf_variables = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_modref" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_modref = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_prefetch" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_prefetch = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_profile" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_profile = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_pta" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_pta = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_pure_const" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_pure_const = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_ra" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_ra = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_reference" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_reference = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_reference_addressable" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_reference_addressable = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_reorder_fields" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_reorder_fields = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_sra" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_sra = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_stack_alignment" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_stack_alignment = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_strict_aliasing" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_strict_aliasing = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_struct_reorg" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_struct_reorg = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ipa_vrp" in var_opt_val_set) { ++ print " ptr->x_flag_ipa_vrp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ira_algorithm" in var_opt_val_set) { ++ print " ptr->x_flag_ira_algorithm = (enum ira_algorithm ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ira_hoist_pressure" in var_opt_val_set) { ++ print " ptr->x_flag_ira_hoist_pressure = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ira_loop_pressure" in var_opt_val_set) { ++ print " ptr->x_flag_ira_loop_pressure = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ira_region" in var_opt_val_set) { ++ print " ptr->x_flag_ira_region = (enum ira_region ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ira_share_save_slots" in var_opt_val_set) { ++ print " ptr->x_flag_ira_share_save_slots = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ira_share_spill_slots" in var_opt_val_set) { ++ print " ptr->x_flag_ira_share_spill_slots = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_isolate_erroneous_paths_attribute" in var_opt_val_set) { ++ print " ptr->x_flag_isolate_erroneous_paths_attribute = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_isolate_erroneous_paths_dereference" in var_opt_val_set) { ++ print " ptr->x_flag_isolate_erroneous_paths_dereference = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ivopts" in var_opt_val_set) { ++ print " ptr->x_flag_ivopts = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_jump_tables" in var_opt_val_set) { ++ print " ptr->x_flag_jump_tables = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_keep_gc_roots_live" in var_opt_val_set) { ++ print " ptr->x_flag_keep_gc_roots_live = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_kernel_pgo" in var_opt_val_set) { ++ print " ptr->x_flag_kernel_pgo = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_lifetime_dse" in var_opt_val_set) { ++ print " ptr->x_flag_lifetime_dse = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_limit_function_alignment" in var_opt_val_set) { ++ print " ptr->x_flag_limit_function_alignment = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_live_patching" in var_opt_val_set) { ++ print " ptr->x_flag_live_patching = (enum live_patching_level ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_live_range_shrinkage" in var_opt_val_set) { ++ print " ptr->x_flag_live_range_shrinkage = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_loop_crc" in var_opt_val_set) { ++ print " ptr->x_flag_loop_crc = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_loop_elim" in var_opt_val_set) { ++ print " ptr->x_flag_loop_elim = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_loop_interchange" in var_opt_val_set) { ++ print " ptr->x_flag_loop_interchange = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_loop_nest_optimize" in var_opt_val_set) { ++ print " ptr->x_flag_loop_nest_optimize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_loop_parallelize_all" in var_opt_val_set) { ++ print " ptr->x_flag_loop_parallelize_all = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unroll_jam" in var_opt_val_set) { ++ print " ptr->x_flag_unroll_jam = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_lra_remat" in var_opt_val_set) { ++ print " ptr->x_flag_lra_remat = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_errno_math" in var_opt_val_set) { ++ print " ptr->x_flag_errno_math = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_merge_mull" in var_opt_val_set) { ++ print " ptr->x_flag_merge_mull = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_modulo_sched" in var_opt_val_set) { ++ print " ptr->x_flag_modulo_sched = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_modulo_sched_allow_regmoves" in var_opt_val_set) { ++ print " ptr->x_flag_modulo_sched_allow_regmoves = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_move_loop_invariants" in var_opt_val_set) { ++ print " ptr->x_flag_move_loop_invariants = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_move_loop_stores" in var_opt_val_set) { ++ print " ptr->x_flag_move_loop_stores = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_non_call_exceptions" in var_opt_val_set) { ++ print " ptr->x_flag_non_call_exceptions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_nothrow_opt" in var_opt_val_set) { ++ print " ptr->x_flag_nothrow_opt = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_omit_frame_pointer" in var_opt_val_set) { ++ print " ptr->x_flag_omit_frame_pointer = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_opt_info" in var_opt_val_set) { ++ print " ptr->x_flag_opt_info = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_optimize_sibling_calls" in var_opt_val_set) { ++ print " ptr->x_flag_optimize_sibling_calls = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_optimize_strlen" in var_opt_val_set) { ++ print " ptr->x_flag_optimize_strlen = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_fp_model" in var_opt_val_set) { ++ print " ptr->x_flag_fp_model = (enum fp_model ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_pack_struct" in var_opt_val_set) { ++ print " ptr->x_flag_pack_struct = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_partial_inlining" in var_opt_val_set) { ++ print " ptr->x_flag_partial_inlining = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_patchable_function_entry" in var_opt_val_set) { ++ print " ptr->x_flag_patchable_function_entry = bp_unpack_string (data_in, bp);" ++ print " if (ptr->x_flag_patchable_function_entry)" ++ print " ptr->x_flag_patchable_function_entry = xstrdup (ptr->x_flag_patchable_function_entry);" ++} ++else ++ print " bp_unpack_string (data_in, bp);" ++if ("x_flag_peel_loops" in var_opt_val_set) { ++ print " ptr->x_flag_peel_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_no_peephole" in var_opt_val_set) { ++ print " ptr->x_flag_no_peephole = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_peephole2" in var_opt_val_set) { ++ print " ptr->x_flag_peephole2 = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_plt" in var_opt_val_set) { ++ print " ptr->x_flag_plt = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_predictive_commoning" in var_opt_val_set) { ++ print " ptr->x_flag_predictive_commoning = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_prefetch_loop_arrays" in var_opt_val_set) { ++ print " ptr->x_flag_prefetch_loop_arrays = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_printf_return_value" in var_opt_val_set) { ++ print " ptr->x_flag_printf_return_value = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_profile_partial_training" in var_opt_val_set) { ++ print " ptr->x_flag_profile_partial_training = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_profile_reorder_functions" in var_opt_val_set) { ++ print " ptr->x_flag_profile_reorder_functions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_reciprocal_math" in var_opt_val_set) { ++ print " ptr->x_flag_reciprocal_math = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ree" in var_opt_val_set) { ++ print " ptr->x_flag_ree = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_pcc_struct_return" in var_opt_val_set) { ++ print " ptr->x_flag_pcc_struct_return = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_rename_registers" in var_opt_val_set) { ++ print " ptr->x_flag_rename_registers = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_reorder_blocks" in var_opt_val_set) { ++ print " ptr->x_flag_reorder_blocks = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_reorder_blocks_algorithm" in var_opt_val_set) { ++ print " ptr->x_flag_reorder_blocks_algorithm = (enum reorder_blocks_algorithm ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_reorder_blocks_and_partition" in var_opt_val_set) { ++ print " ptr->x_flag_reorder_blocks_and_partition = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_reorder_functions" in var_opt_val_set) { ++ print " ptr->x_flag_reorder_functions = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_rerun_cse_after_loop" in var_opt_val_set) { ++ print " ptr->x_flag_rerun_cse_after_loop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_resched_modulo_sched" in var_opt_val_set) { ++ print " ptr->x_flag_resched_modulo_sched = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_rounding_math" in var_opt_val_set) { ++ print " ptr->x_flag_rounding_math = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_rtti" in var_opt_val_set) { ++ print " ptr->x_flag_rtti = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_save_optimization_record" in var_opt_val_set) { ++ print " ptr->x_flag_save_optimization_record = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_critical_path_heuristic" in var_opt_val_set) { ++ print " ptr->x_flag_sched_critical_path_heuristic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_dep_count_heuristic" in var_opt_val_set) { ++ print " ptr->x_flag_sched_dep_count_heuristic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_group_heuristic" in var_opt_val_set) { ++ print " ptr->x_flag_sched_group_heuristic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_interblock" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_interblock = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_last_insn_heuristic" in var_opt_val_set) { ++ print " ptr->x_flag_sched_last_insn_heuristic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_pressure" in var_opt_val_set) { ++ print " ptr->x_flag_sched_pressure = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_rank_heuristic" in var_opt_val_set) { ++ print " ptr->x_flag_sched_rank_heuristic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_speculative" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_speculative = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_spec_insn_heuristic" in var_opt_val_set) { ++ print " ptr->x_flag_sched_spec_insn_heuristic = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_speculative_load" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_speculative_load = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_speculative_load_dangerous" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_speculative_load_dangerous = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_stalled_insns" in var_opt_val_set) { ++ print " ptr->x_flag_sched_stalled_insns = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched_stalled_insns_dep" in var_opt_val_set) { ++ print " ptr->x_flag_sched_stalled_insns_dep = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sched2_use_superblocks" in var_opt_val_set) { ++ print " ptr->x_flag_sched2_use_superblocks = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_fusion" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_fusion = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_insns" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_insns = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_schedule_insns_after_reload" in var_opt_val_set) { ++ print " ptr->x_flag_schedule_insns_after_reload = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_section_anchors" in var_opt_val_set) { ++ print " ptr->x_flag_section_anchors = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sel_sched_pipelining" in var_opt_val_set) { ++ print " ptr->x_flag_sel_sched_pipelining = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sel_sched_pipelining_outer_loops" in var_opt_val_set) { ++ print " ptr->x_flag_sel_sched_pipelining_outer_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_sel_sched_reschedule_pipelined" in var_opt_val_set) { ++ print " ptr->x_flag_sel_sched_reschedule_pipelined = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_selective_scheduling" in var_opt_val_set) { ++ print " ptr->x_flag_selective_scheduling = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_selective_scheduling2" in var_opt_val_set) { ++ print " ptr->x_flag_selective_scheduling2 = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_semantic_interposition" in var_opt_val_set) { ++ print " ptr->x_flag_semantic_interposition = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_short_enums" in var_opt_val_set) { ++ print " ptr->x_flag_short_enums = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_short_wchar" in var_opt_val_set) { ++ print " ptr->x_flag_short_wchar = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_shrink_wrap" in var_opt_val_set) { ++ print " ptr->x_flag_shrink_wrap = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_shrink_wrap_separate" in var_opt_val_set) { ++ print " ptr->x_flag_shrink_wrap_separate = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_signaling_nans" in var_opt_val_set) { ++ print " ptr->x_flag_signaling_nans = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_signed_zeros" in var_opt_val_set) { ++ print " ptr->x_flag_signed_zeros = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_simd_cost_model" in var_opt_val_set) { ++ print " ptr->x_flag_simd_cost_model = (enum vect_cost_model ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_simdmath" in var_opt_val_set) { ++ print " ptr->x_flag_simdmath = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_single_precision_constant" in var_opt_val_set) { ++ print " ptr->x_flag_single_precision_constant = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_split_ivs_in_unroller" in var_opt_val_set) { ++ print " ptr->x_flag_split_ivs_in_unroller = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_split_ldp_stp" in var_opt_val_set) { ++ print " ptr->x_flag_split_ldp_stp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_split_loops" in var_opt_val_set) { ++ print " ptr->x_flag_split_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_split_paths" in var_opt_val_set) { ++ print " ptr->x_flag_split_paths = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_split_wide_types" in var_opt_val_set) { ++ print " ptr->x_flag_split_wide_types = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_split_wide_types_early" in var_opt_val_set) { ++ print " ptr->x_flag_split_wide_types_early = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ssa_backprop" in var_opt_val_set) { ++ print " ptr->x_flag_ssa_backprop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_ssa_phiopt" in var_opt_val_set) { ++ print " ptr->x_flag_ssa_phiopt = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_stack_clash_protection" in var_opt_val_set) { ++ print " ptr->x_flag_stack_clash_protection = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_stack_protect" in var_opt_val_set) { ++ print " ptr->x_flag_stack_protect = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_stack_reuse" in var_opt_val_set) { ++ print " ptr->x_flag_stack_reuse = (enum stack_reuse_level ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_stdarg_opt" in var_opt_val_set) { ++ print " ptr->x_flag_stdarg_opt = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_store_merging" in var_opt_val_set) { ++ print " ptr->x_flag_store_merging = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_strict_aliasing" in var_opt_val_set) { ++ print " ptr->x_flag_strict_aliasing = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_strict_enums" in var_opt_val_set) { ++ print " ptr->x_flag_strict_enums = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_strict_volatile_bitfields" in var_opt_val_set) { ++ print " ptr->x_flag_strict_volatile_bitfields = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_thread_jumps" in var_opt_val_set) { ++ print " ptr->x_flag_thread_jumps = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_threadsafe_statics" in var_opt_val_set) { ++ print " ptr->x_flag_threadsafe_statics = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_toplevel_reorder" in var_opt_val_set) { ++ print " ptr->x_flag_toplevel_reorder = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tracer" in var_opt_val_set) { ++ print " ptr->x_flag_tracer = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_trapping_math" in var_opt_val_set) { ++ print " ptr->x_flag_trapping_math = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_trapv" in var_opt_val_set) { ++ print " ptr->x_flag_trapv = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_bit_ccp" in var_opt_val_set) { ++ print " ptr->x_flag_tree_bit_ccp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_builtin_call_dce" in var_opt_val_set) { ++ print " ptr->x_flag_tree_builtin_call_dce = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_ccp" in var_opt_val_set) { ++ print " ptr->x_flag_tree_ccp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_ch" in var_opt_val_set) { ++ print " ptr->x_flag_tree_ch = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_coalesce_vars" in var_opt_val_set) { ++ print " ptr->x_flag_tree_coalesce_vars = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_copy_prop" in var_opt_val_set) { ++ print " ptr->x_flag_tree_copy_prop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_cselim" in var_opt_val_set) { ++ print " ptr->x_flag_tree_cselim = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_dce" in var_opt_val_set) { ++ print " ptr->x_flag_tree_dce = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_dom" in var_opt_val_set) { ++ print " ptr->x_flag_tree_dom = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_dse" in var_opt_val_set) { ++ print " ptr->x_flag_tree_dse = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_forwprop" in var_opt_val_set) { ++ print " ptr->x_flag_tree_forwprop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_fre" in var_opt_val_set) { ++ print " ptr->x_flag_tree_fre = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_distribute_patterns" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_distribute_patterns = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_distribution" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_distribution = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_if_convert" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_if_convert = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_im" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_im = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_ivcanon" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_ivcanon = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_optimize" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_optimize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_loop_vectorize" in var_opt_val_set) { ++ print " ptr->x_flag_tree_loop_vectorize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_live_range_split" in var_opt_val_set) { ++ print " ptr->x_flag_tree_live_range_split = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_parallelize_loops" in var_opt_val_set) { ++ print " ptr->x_flag_tree_parallelize_loops = (int ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_partial_pre" in var_opt_val_set) { ++ print " ptr->x_flag_tree_partial_pre = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_phiprop" in var_opt_val_set) { ++ print " ptr->x_flag_tree_phiprop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_pre" in var_opt_val_set) { ++ print " ptr->x_flag_tree_pre = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_pta" in var_opt_val_set) { ++ print " ptr->x_flag_tree_pta = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_reassoc" in var_opt_val_set) { ++ print " ptr->x_flag_tree_reassoc = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_scev_cprop" in var_opt_val_set) { ++ print " ptr->x_flag_tree_scev_cprop = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_sink" in var_opt_val_set) { ++ print " ptr->x_flag_tree_sink = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_slp_transpose_vectorize" in var_opt_val_set) { ++ print " ptr->x_flag_tree_slp_transpose_vectorize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_slp_vectorize" in var_opt_val_set) { ++ print " ptr->x_flag_tree_slp_vectorize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_slsr" in var_opt_val_set) { ++ print " ptr->x_flag_tree_slsr = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_sra" in var_opt_val_set) { ++ print " ptr->x_flag_tree_sra = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_switch_conversion" in var_opt_val_set) { ++ print " ptr->x_flag_tree_switch_conversion = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_tail_merge" in var_opt_val_set) { ++ print " ptr->x_flag_tree_tail_merge = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_ter" in var_opt_val_set) { ++ print " ptr->x_flag_tree_ter = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_vectorize" in var_opt_val_set) { ++ print " ptr->x_flag_tree_vectorize = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_tree_vrp" in var_opt_val_set) { ++ print " ptr->x_flag_tree_vrp = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_auto_var_init" in var_opt_val_set) { ++ print " ptr->x_flag_auto_var_init = (enum auto_init_type ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unconstrained_commons" in var_opt_val_set) { ++ print " ptr->x_flag_unconstrained_commons = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unroll_all_loops" in var_opt_val_set) { ++ print " ptr->x_flag_unroll_all_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_cunroll_grow_size" in var_opt_val_set) { ++ print " ptr->x_flag_cunroll_grow_size = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unroll_loops" in var_opt_val_set) { ++ print " ptr->x_flag_unroll_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unsafe_math_optimizations" in var_opt_val_set) { ++ print " ptr->x_flag_unsafe_math_optimizations = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unswitch_loops" in var_opt_val_set) { ++ print " ptr->x_flag_unswitch_loops = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_unwind_tables" in var_opt_val_set) { ++ print " ptr->x_flag_unwind_tables = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_var_tracking" in var_opt_val_set) { ++ print " ptr->x_flag_var_tracking = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_var_tracking_assignments" in var_opt_val_set) { ++ print " ptr->x_flag_var_tracking_assignments = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_var_tracking_assignments_toggle" in var_opt_val_set) { ++ print " ptr->x_flag_var_tracking_assignments_toggle = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_var_tracking_uninit" in var_opt_val_set) { ++ print " ptr->x_flag_var_tracking_uninit = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_variable_expansion_in_unroller" in var_opt_val_set) { ++ print " ptr->x_flag_variable_expansion_in_unroller = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_vect_cost_model" in var_opt_val_set) { ++ print " ptr->x_flag_vect_cost_model = (enum vect_cost_model ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_version_loops_for_strides" in var_opt_val_set) { ++ print " ptr->x_flag_version_loops_for_strides = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_value_profile_transformations" in var_opt_val_set) { ++ print " ptr->x_flag_value_profile_transformations = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_web" in var_opt_val_set) { ++ print " ptr->x_flag_web = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_wrapv" in var_opt_val_set) { ++ print " ptr->x_flag_wrapv = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_wrapv_pointer" in var_opt_val_set) { ++ print " ptr->x_flag_wrapv_pointer = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_debug_nonbind_markers_p" in var_opt_val_set) { ++ print " ptr->x_debug_nonbind_markers_p = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_cmlt_arith" in var_opt_val_set) { ++ print " ptr->x_flag_cmlt_arith = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_mlow_precision_div" in var_opt_val_set) { ++ print " ptr->x_flag_mlow_precision_div = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_mrecip_low_precision_sqrt" in var_opt_val_set) { ++ print " ptr->x_flag_mrecip_low_precision_sqrt = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_mlow_precision_sqrt" in var_opt_val_set) { ++ print " ptr->x_flag_mlow_precision_sqrt = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++if ("x_flag_simdmath_64" in var_opt_val_set) { ++ print " ptr->x_flag_simdmath_64 = (signed char ) bp_unpack_var_len_int (bp);" ++} ++else ++ print " bp_unpack_var_len_int (bp);" ++print " unsigned HOST_WIDE_INT explicit_mask_prev[9];" ++print " for (size_t i = 0; i < 9; i++)" ++print " explicit_mask_prev[i] = bp_unpack_value (bp, 64);" ++print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)" ++print " ptr->explicit_mask[i] = 0;" ++if ("param_align_loop_iterations" in var_opt_int_k) { ++ k = var_opt_int_k["param_align_loop_iterations"] ++ j = var_opt_int_j["param_align_loop_iterations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_align_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_align_threshold"] ++ j = var_opt_int_j["param_align_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_protect_allocas" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_protect_allocas"] ++ j = var_opt_int_j["param_asan_protect_allocas"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_instrument_reads" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_instrument_reads"] ++ j = var_opt_int_j["param_asan_instrument_reads"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_instrument_writes" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_instrument_writes"] ++ j = var_opt_int_j["param_asan_instrument_writes"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_instrumentation_with_call_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_instrumentation_with_call_threshold"] ++ j = var_opt_int_j["param_asan_instrumentation_with_call_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_memintrin" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_memintrin"] ++ j = var_opt_int_j["param_asan_memintrin"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_stack" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_stack"] ++ j = var_opt_int_j["param_asan_stack"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_asan_use_after_return" in var_opt_int_k) { ++ k = var_opt_int_k["param_asan_use_after_return"] ++ j = var_opt_int_j["param_asan_use_after_return"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_avg_loop_niter" in var_opt_int_k) { ++ k = var_opt_int_k["param_avg_loop_niter"] ++ j = var_opt_int_j["param_avg_loop_niter"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_avoid_fma_max_bits" in var_opt_int_k) { ++ k = var_opt_int_k["param_avoid_fma_max_bits"] ++ j = var_opt_int_j["param_avoid_fma_max_bits"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_builtin_expect_probability" in var_opt_int_k) { ++ k = var_opt_int_k["param_builtin_expect_probability"] ++ j = var_opt_int_j["param_builtin_expect_probability"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_builtin_string_cmp_inline_length" in var_opt_int_k) { ++ k = var_opt_int_k["param_builtin_string_cmp_inline_length"] ++ j = var_opt_int_j["param_builtin_string_cmp_inline_length"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_case_values_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_case_values_threshold"] ++ j = var_opt_int_j["param_case_values_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_comdat_sharing_probability" in var_opt_int_k) { ++ k = var_opt_int_k["param_comdat_sharing_probability"] ++ j = var_opt_int_j["param_comdat_sharing_probability"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_pointer_compression_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_pointer_compression_size"] ++ j = var_opt_int_j["param_pointer_compression_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_construct_interfere_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_construct_interfere_size"] ++ j = var_opt_int_j["param_construct_interfere_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_destruct_interfere_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_destruct_interfere_size"] ++ j = var_opt_int_j["param_destruct_interfere_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_dse_max_alias_queries_per_store" in var_opt_int_k) { ++ k = var_opt_int_k["param_dse_max_alias_queries_per_store"] ++ j = var_opt_int_j["param_dse_max_alias_queries_per_store"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_dse_max_object_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_dse_max_object_size"] ++ j = var_opt_int_j["param_dse_max_object_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_early_inlining_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_early_inlining_insns"] ++ j = var_opt_int_j["param_early_inlining_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_evrp_sparse_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_evrp_sparse_threshold"] ++ j = var_opt_int_j["param_evrp_sparse_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_evrp_switch_limit" in var_opt_int_k) { ++ k = var_opt_int_k["param_evrp_switch_limit"] ++ j = var_opt_int_j["param_evrp_switch_limit"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_fsm_scale_path_blocks" in var_opt_int_k) { ++ k = var_opt_int_k["param_fsm_scale_path_blocks"] ++ j = var_opt_int_j["param_fsm_scale_path_blocks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_fsm_scale_path_stmts" in var_opt_int_k) { ++ k = var_opt_int_k["param_fsm_scale_path_stmts"] ++ j = var_opt_int_j["param_fsm_scale_path_stmts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_gcse_after_reload_critical_fraction" in var_opt_int_k) { ++ k = var_opt_int_k["param_gcse_after_reload_critical_fraction"] ++ j = var_opt_int_j["param_gcse_after_reload_critical_fraction"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_gcse_after_reload_partial_fraction" in var_opt_int_k) { ++ k = var_opt_int_k["param_gcse_after_reload_partial_fraction"] ++ j = var_opt_int_j["param_gcse_after_reload_partial_fraction"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_gcse_cost_distance_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_gcse_cost_distance_ratio"] ++ j = var_opt_int_j["param_gcse_cost_distance_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_gcse_unrestricted_cost" in var_opt_int_k) { ++ k = var_opt_int_k["param_gcse_unrestricted_cost"] ++ j = var_opt_int_j["param_gcse_unrestricted_cost"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_graphite_max_arrays_per_scop" in var_opt_int_k) { ++ k = var_opt_int_k["param_graphite_max_arrays_per_scop"] ++ j = var_opt_int_j["param_graphite_max_arrays_per_scop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_graphite_max_nb_scop_params" in var_opt_int_k) { ++ k = var_opt_int_k["param_graphite_max_nb_scop_params"] ++ j = var_opt_int_j["param_graphite_max_nb_scop_params"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_hwasan_instrument_allocas" in var_opt_int_k) { ++ k = var_opt_int_k["param_hwasan_instrument_allocas"] ++ j = var_opt_int_j["param_hwasan_instrument_allocas"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_hwasan_instrument_mem_intrinsics" in var_opt_int_k) { ++ k = var_opt_int_k["param_hwasan_instrument_mem_intrinsics"] ++ j = var_opt_int_j["param_hwasan_instrument_mem_intrinsics"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_hwasan_instrument_reads" in var_opt_int_k) { ++ k = var_opt_int_k["param_hwasan_instrument_reads"] ++ j = var_opt_int_j["param_hwasan_instrument_reads"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_hwasan_instrument_stack" in var_opt_int_k) { ++ k = var_opt_int_k["param_hwasan_instrument_stack"] ++ j = var_opt_int_j["param_hwasan_instrument_stack"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_hwasan_instrument_writes" in var_opt_int_k) { ++ k = var_opt_int_k["param_hwasan_instrument_writes"] ++ j = var_opt_int_j["param_hwasan_instrument_writes"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_hwasan_random_frame_tag" in var_opt_int_k) { ++ k = var_opt_int_k["param_hwasan_random_frame_tag"] ++ j = var_opt_int_j["param_hwasan_random_frame_tag"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ifcvt_allow_register_renaming" in var_opt_int_k) { ++ k = var_opt_int_k["param_ifcvt_allow_register_renaming"] ++ j = var_opt_int_j["param_ifcvt_allow_register_renaming"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_inline_heuristics_hint_percent" in var_opt_int_k) { ++ k = var_opt_int_k["param_inline_heuristics_hint_percent"] ++ j = var_opt_int_j["param_inline_heuristics_hint_percent"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_inline_min_speedup" in var_opt_int_k) { ++ k = var_opt_int_k["param_inline_min_speedup"] ++ j = var_opt_int_j["param_inline_min_speedup"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_inline_unit_growth" in var_opt_int_k) { ++ k = var_opt_int_k["param_inline_unit_growth"] ++ j = var_opt_int_j["param_inline_unit_growth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_eval_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_eval_threshold"] ++ j = var_opt_int_j["param_ipa_cp_eval_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_large_unit_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_large_unit_insns"] ++ j = var_opt_int_j["param_ipa_cp_large_unit_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_loop_hint_bonus" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_loop_hint_bonus"] ++ j = var_opt_int_j["param_ipa_cp_loop_hint_bonus"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_max_recursive_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_max_recursive_depth"] ++ j = var_opt_int_j["param_ipa_cp_max_recursive_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_min_recursive_probability" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_min_recursive_probability"] ++ j = var_opt_int_j["param_ipa_cp_min_recursive_probability"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_profile_count_base" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_profile_count_base"] ++ j = var_opt_int_j["param_ipa_cp_profile_count_base"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_recursion_penalty" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_recursion_penalty"] ++ j = var_opt_int_j["param_ipa_cp_recursion_penalty"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_recursive_freq_factor" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_recursive_freq_factor"] ++ j = var_opt_int_j["param_ipa_cp_recursive_freq_factor"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_single_call_penalty" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_single_call_penalty"] ++ j = var_opt_int_j["param_ipa_cp_single_call_penalty"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_unit_growth" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_unit_growth"] ++ j = var_opt_int_j["param_ipa_cp_unit_growth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_cp_value_list_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_cp_value_list_size"] ++ j = var_opt_int_j["param_ipa_cp_value_list_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_jump_function_lookups" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_jump_function_lookups"] ++ j = var_opt_int_j["param_ipa_jump_function_lookups"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_max_aa_steps" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_max_aa_steps"] ++ j = var_opt_int_j["param_ipa_max_aa_steps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_max_agg_items" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_max_agg_items"] ++ j = var_opt_int_j["param_ipa_max_agg_items"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_max_loop_predicates" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_max_loop_predicates"] ++ j = var_opt_int_j["param_ipa_max_loop_predicates"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_max_param_expr_ops" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_max_param_expr_ops"] ++ j = var_opt_int_j["param_ipa_max_param_expr_ops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_max_switch_predicate_bounds" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_max_switch_predicate_bounds"] ++ j = var_opt_int_j["param_ipa_max_switch_predicate_bounds"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_prefetch_distance_factor" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_prefetch_distance_factor"] ++ j = var_opt_int_j["param_ipa_prefetch_distance_factor"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_prefetch_locality" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_prefetch_locality"] ++ j = var_opt_int_j["param_ipa_prefetch_locality"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_prefetch_pagesize" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_prefetch_pagesize"] ++ j = var_opt_int_j["param_ipa_prefetch_pagesize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_sra_max_replacements" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_sra_max_replacements"] ++ j = var_opt_int_j["param_ipa_sra_max_replacements"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ipa_sra_ptr_growth_factor" in var_opt_int_k) { ++ k = var_opt_int_k["param_ipa_sra_ptr_growth_factor"] ++ j = var_opt_int_j["param_ipa_sra_ptr_growth_factor"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ira_consider_dup_in_all_alts" in var_opt_int_k) { ++ k = var_opt_int_k["param_ira_consider_dup_in_all_alts"] ++ j = var_opt_int_j["param_ira_consider_dup_in_all_alts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[0] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ira_loop_reserved_regs" in var_opt_int_k) { ++ k = var_opt_int_k["param_ira_loop_reserved_regs"] ++ j = var_opt_int_j["param_ira_loop_reserved_regs"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ira_max_conflict_table_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_ira_max_conflict_table_size"] ++ j = var_opt_int_j["param_ira_max_conflict_table_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ira_max_loops_num" in var_opt_int_k) { ++ k = var_opt_int_k["param_ira_max_loops_num"] ++ j = var_opt_int_j["param_ira_max_loops_num"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_iv_always_prune_cand_set_bound" in var_opt_int_k) { ++ k = var_opt_int_k["param_iv_always_prune_cand_set_bound"] ++ j = var_opt_int_j["param_iv_always_prune_cand_set_bound"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_iv_consider_all_candidates_bound" in var_opt_int_k) { ++ k = var_opt_int_k["param_iv_consider_all_candidates_bound"] ++ j = var_opt_int_j["param_iv_consider_all_candidates_bound"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_iv_max_considered_uses" in var_opt_int_k) { ++ k = var_opt_int_k["param_iv_max_considered_uses"] ++ j = var_opt_int_j["param_iv_max_considered_uses"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_jump_table_max_growth_ratio_for_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_jump_table_max_growth_ratio_for_size"] ++ j = var_opt_int_j["param_jump_table_max_growth_ratio_for_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_jump_table_max_growth_ratio_for_speed" in var_opt_int_k) { ++ k = var_opt_int_k["param_jump_table_max_growth_ratio_for_speed"] ++ j = var_opt_int_j["param_jump_table_max_growth_ratio_for_speed"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_l1_cache_line_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_l1_cache_line_size"] ++ j = var_opt_int_j["param_l1_cache_line_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_l1_cache_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_l1_cache_size"] ++ j = var_opt_int_j["param_l1_cache_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_l2_cache_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_l2_cache_size"] ++ j = var_opt_int_j["param_l2_cache_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_large_function_growth" in var_opt_int_k) { ++ k = var_opt_int_k["param_large_function_growth"] ++ j = var_opt_int_j["param_large_function_growth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_large_function_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_large_function_insns"] ++ j = var_opt_int_j["param_large_function_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_stack_frame_growth" in var_opt_int_k) { ++ k = var_opt_int_k["param_stack_frame_growth"] ++ j = var_opt_int_j["param_stack_frame_growth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_large_stack_frame" in var_opt_int_k) { ++ k = var_opt_int_k["param_large_stack_frame"] ++ j = var_opt_int_j["param_large_stack_frame"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_large_unit_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_large_unit_insns"] ++ j = var_opt_int_j["param_large_unit_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_lim_expensive" in var_opt_int_k) { ++ k = var_opt_int_k["param_lim_expensive"] ++ j = var_opt_int_j["param_lim_expensive"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_block_tile_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_block_tile_size"] ++ j = var_opt_int_j["param_loop_block_tile_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_interchange_max_num_stmts" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_interchange_max_num_stmts"] ++ j = var_opt_int_j["param_loop_interchange_max_num_stmts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_interchange_stride_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_interchange_stride_ratio"] ++ j = var_opt_int_j["param_loop_interchange_stride_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_invariant_max_bbs_in_loop" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_invariant_max_bbs_in_loop"] ++ j = var_opt_int_j["param_loop_invariant_max_bbs_in_loop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_max_datarefs_for_datadeps" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_max_datarefs_for_datadeps"] ++ j = var_opt_int_j["param_loop_max_datarefs_for_datadeps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_versioning_max_inner_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_versioning_max_inner_insns"] ++ j = var_opt_int_j["param_loop_versioning_max_inner_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_loop_versioning_max_outer_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_loop_versioning_max_outer_insns"] ++ j = var_opt_int_j["param_loop_versioning_max_outer_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_lra_inheritance_ebb_probability_cutoff" in var_opt_int_k) { ++ k = var_opt_int_k["param_lra_inheritance_ebb_probability_cutoff"] ++ j = var_opt_int_j["param_lra_inheritance_ebb_probability_cutoff"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_lra_max_considered_reload_pseudos" in var_opt_int_k) { ++ k = var_opt_int_k["param_lra_max_considered_reload_pseudos"] ++ j = var_opt_int_j["param_lra_max_considered_reload_pseudos"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_average_unrolled_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_average_unrolled_insns"] ++ j = var_opt_int_j["param_max_average_unrolled_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_combine_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_combine_insns"] ++ j = var_opt_int_j["param_max_combine_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_unroll_iterations" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_unroll_iterations"] ++ j = var_opt_int_j["param_max_unroll_iterations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_completely_peel_times" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_completely_peel_times"] ++ j = var_opt_int_j["param_max_completely_peel_times"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_completely_peeled_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_completely_peeled_insns"] ++ j = var_opt_int_j["param_max_completely_peeled_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_crossjump_edges" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_crossjump_edges"] ++ j = var_opt_int_j["param_max_crossjump_edges"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_cse_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_cse_insns"] ++ j = var_opt_int_j["param_max_cse_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_cse_path_length" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_cse_path_length"] ++ j = var_opt_int_j["param_max_cse_path_length"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_cselib_memory_locations" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_cselib_memory_locations"] ++ j = var_opt_int_j["param_max_cselib_memory_locations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_debug_marker_count" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_debug_marker_count"] ++ j = var_opt_int_j["param_max_debug_marker_count"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_delay_slot_insn_search" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_delay_slot_insn_search"] ++ j = var_opt_int_j["param_max_delay_slot_insn_search"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_delay_slot_live_search" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_delay_slot_live_search"] ++ j = var_opt_int_j["param_max_delay_slot_live_search"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_dse_active_local_stores" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_dse_active_local_stores"] ++ j = var_opt_int_j["param_max_dse_active_local_stores"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_early_inliner_max_iterations" in var_opt_int_k) { ++ k = var_opt_int_k["param_early_inliner_max_iterations"] ++ j = var_opt_int_j["param_early_inliner_max_iterations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_find_base_term_values" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_find_base_term_values"] ++ j = var_opt_int_j["param_max_find_base_term_values"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_fsm_thread_length" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_fsm_thread_length"] ++ j = var_opt_int_j["param_max_fsm_thread_length"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_fsm_thread_path_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_fsm_thread_path_insns"] ++ j = var_opt_int_j["param_max_fsm_thread_path_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_gcse_insertion_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_gcse_insertion_ratio"] ++ j = var_opt_int_j["param_max_gcse_insertion_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_gcse_memory" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_gcse_memory"] ++ j = var_opt_int_j["param_max_gcse_memory"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_goto_duplication_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_goto_duplication_insns"] ++ j = var_opt_int_j["param_max_goto_duplication_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_grow_copy_bb_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_grow_copy_bb_insns"] ++ j = var_opt_int_j["param_max_grow_copy_bb_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_hoist_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_hoist_depth"] ++ j = var_opt_int_j["param_max_hoist_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_inline_functions_called_once_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_inline_functions_called_once_insns"] ++ j = var_opt_int_j["param_inline_functions_called_once_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_inline_functions_called_once_loop_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_inline_functions_called_once_loop_depth"] ++ j = var_opt_int_j["param_inline_functions_called_once_loop_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_insns_auto" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_insns_auto"] ++ j = var_opt_int_j["param_max_inline_insns_auto"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_insns_recursive_auto" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_insns_recursive_auto"] ++ j = var_opt_int_j["param_max_inline_insns_recursive_auto"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_insns_recursive" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_insns_recursive"] ++ j = var_opt_int_j["param_max_inline_insns_recursive"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_insns_single" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_insns_single"] ++ j = var_opt_int_j["param_max_inline_insns_single"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_insns_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_insns_size"] ++ j = var_opt_int_j["param_max_inline_insns_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_insns_small" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_insns_small"] ++ j = var_opt_int_j["param_max_inline_insns_small"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_recursive_depth_auto" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_recursive_depth_auto"] ++ j = var_opt_int_j["param_max_inline_recursive_depth_auto"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_inline_recursive_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_inline_recursive_depth"] ++ j = var_opt_int_j["param_max_inline_recursive_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_isl_operations" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_isl_operations"] ++ j = var_opt_int_j["param_max_isl_operations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_iterations_computation_cost" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_iterations_computation_cost"] ++ j = var_opt_int_j["param_max_iterations_computation_cost"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_iterations_to_track" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_iterations_to_track"] ++ j = var_opt_int_j["param_max_iterations_to_track"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_jump_thread_duplication_stmts" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_jump_thread_duplication_stmts"] ++ j = var_opt_int_j["param_max_jump_thread_duplication_stmts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_last_value_rtl" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_last_value_rtl"] ++ j = var_opt_int_j["param_max_last_value_rtl"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_loop_header_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_loop_header_insns"] ++ j = var_opt_int_j["param_max_loop_header_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[1] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_modulo_backtrack_attempts" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_modulo_backtrack_attempts"] ++ j = var_opt_int_j["param_max_modulo_backtrack_attempts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_partial_antic_length" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_partial_antic_length"] ++ j = var_opt_int_j["param_max_partial_antic_length"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_peel_branches" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_peel_branches"] ++ j = var_opt_int_j["param_max_peel_branches"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_peel_times" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_peel_times"] ++ j = var_opt_int_j["param_max_peel_times"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_peeled_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_peeled_insns"] ++ j = var_opt_int_j["param_max_peeled_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_pending_list_length" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_pending_list_length"] ++ j = var_opt_int_j["param_max_pending_list_length"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_pipeline_region_blocks" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_pipeline_region_blocks"] ++ j = var_opt_int_j["param_max_pipeline_region_blocks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_pipeline_region_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_pipeline_region_insns"] ++ j = var_opt_int_j["param_max_pipeline_region_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_pow_sqrt_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_pow_sqrt_depth"] ++ j = var_opt_int_j["param_max_pow_sqrt_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_predicted_iterations" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_predicted_iterations"] ++ j = var_opt_int_j["param_max_predicted_iterations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_reload_search_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_reload_search_insns"] ++ j = var_opt_int_j["param_max_reload_search_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_rtl_if_conversion_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_rtl_if_conversion_insns"] ++ j = var_opt_int_j["param_max_rtl_if_conversion_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_rtl_if_conversion_predictable_cost" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_rtl_if_conversion_predictable_cost"] ++ j = var_opt_int_j["param_max_rtl_if_conversion_predictable_cost"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_rtl_if_conversion_unpredictable_cost" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_rtl_if_conversion_unpredictable_cost"] ++ j = var_opt_int_j["param_max_rtl_if_conversion_unpredictable_cost"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_sched_extend_regions_iters" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_sched_extend_regions_iters"] ++ j = var_opt_int_j["param_max_sched_extend_regions_iters"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_sched_insn_conflict_delay" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_sched_insn_conflict_delay"] ++ j = var_opt_int_j["param_max_sched_insn_conflict_delay"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_sched_ready_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_sched_ready_insns"] ++ j = var_opt_int_j["param_max_sched_ready_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_sched_region_blocks" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_sched_region_blocks"] ++ j = var_opt_int_j["param_max_sched_region_blocks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_sched_region_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_sched_region_insns"] ++ j = var_opt_int_j["param_max_sched_region_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_slsr_candidate_scan" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_slsr_candidate_scan"] ++ j = var_opt_int_j["param_max_slsr_candidate_scan"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_speculative_devirt_maydefs" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_speculative_devirt_maydefs"] ++ j = var_opt_int_j["param_max_speculative_devirt_maydefs"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_stores_to_merge" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_stores_to_merge"] ++ j = var_opt_int_j["param_max_stores_to_merge"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_stores_to_sink" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_stores_to_sink"] ++ j = var_opt_int_j["param_max_stores_to_sink"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_tail_merge_comparisons" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_tail_merge_comparisons"] ++ j = var_opt_int_j["param_max_tail_merge_comparisons"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_tail_merge_iterations" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_tail_merge_iterations"] ++ j = var_opt_int_j["param_max_tail_merge_iterations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_tracked_strlens" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_tracked_strlens"] ++ j = var_opt_int_j["param_max_tracked_strlens"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_tree_if_conversion_phi_args" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_tree_if_conversion_phi_args"] ++ j = var_opt_int_j["param_max_tree_if_conversion_phi_args"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_unroll_times" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_unroll_times"] ++ j = var_opt_int_j["param_max_unroll_times"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_unrolled_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_unrolled_insns"] ++ j = var_opt_int_j["param_max_unrolled_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_unswitch_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_unswitch_insns"] ++ j = var_opt_int_j["param_max_unswitch_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_unswitch_level" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_unswitch_level"] ++ j = var_opt_int_j["param_max_unswitch_level"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_variable_expansions" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_variable_expansions"] ++ j = var_opt_int_j["param_max_variable_expansions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_vartrack_expr_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_vartrack_expr_depth"] ++ j = var_opt_int_j["param_max_vartrack_expr_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_vartrack_reverse_op_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_vartrack_reverse_op_size"] ++ j = var_opt_int_j["param_max_vartrack_reverse_op_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_vartrack_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_vartrack_size"] ++ j = var_opt_int_j["param_max_vartrack_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_max_vrp_switch_assertions" in var_opt_int_k) { ++ k = var_opt_int_k["param_max_vrp_switch_assertions"] ++ j = var_opt_int_j["param_max_vrp_switch_assertions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_crossjump_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_crossjump_insns"] ++ j = var_opt_int_j["param_min_crossjump_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_inline_recursive_probability" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_inline_recursive_probability"] ++ j = var_opt_int_j["param_min_inline_recursive_probability"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_insn_to_prefetch_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_insn_to_prefetch_ratio"] ++ j = var_opt_int_j["param_min_insn_to_prefetch_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_loop_cond_split_prob" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_loop_cond_split_prob"] ++ j = var_opt_int_j["param_min_loop_cond_split_prob"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_pagesize" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_pagesize"] ++ j = var_opt_int_j["param_min_pagesize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_size_for_stack_sharing" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_size_for_stack_sharing"] ++ j = var_opt_int_j["param_min_size_for_stack_sharing"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_spec_prob" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_spec_prob"] ++ j = var_opt_int_j["param_min_spec_prob"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_min_vect_loop_bound" in var_opt_int_k) { ++ k = var_opt_int_k["param_min_vect_loop_bound"] ++ j = var_opt_int_j["param_min_vect_loop_bound"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_accesses" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_accesses"] ++ j = var_opt_int_j["param_modref_max_accesses"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_adjustments" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_adjustments"] ++ j = var_opt_int_j["param_modref_max_adjustments"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_bases" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_bases"] ++ j = var_opt_int_j["param_modref_max_bases"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_depth"] ++ j = var_opt_int_j["param_modref_max_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_escape_points" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_escape_points"] ++ j = var_opt_int_j["param_modref_max_escape_points"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_refs" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_refs"] ++ j = var_opt_int_j["param_modref_max_refs"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_modref_max_tests" in var_opt_int_k) { ++ k = var_opt_int_k["param_modref_max_tests"] ++ j = var_opt_int_j["param_modref_max_tests"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ldp_dependency_search_range" in var_opt_int_k) { ++ k = var_opt_int_k["param_ldp_dependency_search_range"] ++ j = var_opt_int_j["param_ldp_dependency_search_range"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_parloops_chunk_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_parloops_chunk_size"] ++ j = var_opt_int_j["param_parloops_chunk_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_parloops_min_per_thread" in var_opt_int_k) { ++ k = var_opt_int_k["param_parloops_min_per_thread"] ++ j = var_opt_int_j["param_parloops_min_per_thread"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_parloops_schedule" in var_opt_int_k) { ++ k = var_opt_int_k["param_parloops_schedule"] ++ j = var_opt_int_j["param_parloops_schedule"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_partial_inlining_entry_probability" in var_opt_int_k) { ++ k = var_opt_int_k["param_partial_inlining_entry_probability"] ++ j = var_opt_int_j["param_partial_inlining_entry_probability"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_predictable_branch_outcome" in var_opt_int_k) { ++ k = var_opt_int_k["param_predictable_branch_outcome"] ++ j = var_opt_int_j["param_predictable_branch_outcome"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_prefetch_dynamic_strides" in var_opt_int_k) { ++ k = var_opt_int_k["param_prefetch_dynamic_strides"] ++ j = var_opt_int_j["param_prefetch_dynamic_strides"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_prefetch_latency" in var_opt_int_k) { ++ k = var_opt_int_k["param_prefetch_latency"] ++ j = var_opt_int_j["param_prefetch_latency"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_prefetch_min_insn_to_mem_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_prefetch_min_insn_to_mem_ratio"] ++ j = var_opt_int_j["param_prefetch_min_insn_to_mem_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_prefetch_minimum_stride" in var_opt_int_k) { ++ k = var_opt_int_k["param_prefetch_minimum_stride"] ++ j = var_opt_int_j["param_prefetch_minimum_stride"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ranger_logical_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_ranger_logical_depth"] ++ j = var_opt_int_j["param_ranger_logical_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_relation_block_limit" in var_opt_int_k) { ++ k = var_opt_int_k["param_relation_block_limit"] ++ j = var_opt_int_j["param_relation_block_limit"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_rpo_vn_max_loop_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_rpo_vn_max_loop_depth"] ++ j = var_opt_int_j["param_rpo_vn_max_loop_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[2] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sccvn_max_alias_queries_per_access" in var_opt_int_k) { ++ k = var_opt_int_k["param_sccvn_max_alias_queries_per_access"] ++ j = var_opt_int_j["param_sccvn_max_alias_queries_per_access"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_scev_max_expr_complexity" in var_opt_int_k) { ++ k = var_opt_int_k["param_scev_max_expr_complexity"] ++ j = var_opt_int_j["param_scev_max_expr_complexity"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_scev_max_expr_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_scev_max_expr_size"] ++ j = var_opt_int_j["param_scev_max_expr_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sched_autopref_queue_depth" in var_opt_int_k) { ++ k = var_opt_int_k["param_sched_autopref_queue_depth"] ++ j = var_opt_int_j["param_sched_autopref_queue_depth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sched_mem_true_dep_cost" in var_opt_int_k) { ++ k = var_opt_int_k["param_sched_mem_true_dep_cost"] ++ j = var_opt_int_j["param_sched_mem_true_dep_cost"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sched_pressure_algorithm" in var_opt_int_k) { ++ k = var_opt_int_k["param_sched_pressure_algorithm"] ++ j = var_opt_int_j["param_sched_pressure_algorithm"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sched_spec_prob_cutoff" in var_opt_int_k) { ++ k = var_opt_int_k["param_sched_spec_prob_cutoff"] ++ j = var_opt_int_j["param_sched_spec_prob_cutoff"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sched_state_edge_prob_cutoff" in var_opt_int_k) { ++ k = var_opt_int_k["param_sched_state_edge_prob_cutoff"] ++ j = var_opt_int_j["param_sched_state_edge_prob_cutoff"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_selsched_insns_to_rename" in var_opt_int_k) { ++ k = var_opt_int_k["param_selsched_insns_to_rename"] ++ j = var_opt_int_j["param_selsched_insns_to_rename"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_selsched_max_lookahead" in var_opt_int_k) { ++ k = var_opt_int_k["param_selsched_max_lookahead"] ++ j = var_opt_int_j["param_selsched_max_lookahead"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_selsched_max_sched_times" in var_opt_int_k) { ++ k = var_opt_int_k["param_selsched_max_sched_times"] ++ j = var_opt_int_j["param_selsched_max_sched_times"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("semi_relayout_level" in var_opt_int_k) { ++ k = var_opt_int_k["semi_relayout_level"] ++ j = var_opt_int_j["semi_relayout_level"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_simultaneous_prefetches" in var_opt_int_k) { ++ k = var_opt_int_k["param_simultaneous_prefetches"] ++ j = var_opt_int_j["param_simultaneous_prefetches"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sink_frequency_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_sink_frequency_threshold"] ++ j = var_opt_int_j["param_sink_frequency_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sms_dfa_history" in var_opt_int_k) { ++ k = var_opt_int_k["param_sms_dfa_history"] ++ j = var_opt_int_j["param_sms_dfa_history"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sms_loop_average_count_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_sms_loop_average_count_threshold"] ++ j = var_opt_int_j["param_sms_loop_average_count_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sms_max_ii_factor" in var_opt_int_k) { ++ k = var_opt_int_k["param_sms_max_ii_factor"] ++ j = var_opt_int_j["param_sms_max_ii_factor"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sms_min_sc" in var_opt_int_k) { ++ k = var_opt_int_k["param_sms_min_sc"] ++ j = var_opt_int_j["param_sms_min_sc"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sra_max_propagations" in var_opt_int_k) { ++ k = var_opt_int_k["param_sra_max_propagations"] ++ j = var_opt_int_j["param_sra_max_propagations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sra_max_scalarization_size_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_sra_max_scalarization_size_size"] ++ j = var_opt_int_j["param_sra_max_scalarization_size_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_sra_max_scalarization_size_speed" in var_opt_int_k) { ++ k = var_opt_int_k["param_sra_max_scalarization_size_speed"] ++ j = var_opt_int_j["param_sra_max_scalarization_size_speed"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ssa_name_def_chain_limit" in var_opt_int_k) { ++ k = var_opt_int_k["param_ssa_name_def_chain_limit"] ++ j = var_opt_int_j["param_ssa_name_def_chain_limit"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ssp_buffer_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_ssp_buffer_size"] ++ j = var_opt_int_j["param_ssp_buffer_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_stack_clash_protection_guard_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_stack_clash_protection_guard_size"] ++ j = var_opt_int_j["param_stack_clash_protection_guard_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_stack_clash_protection_probe_interval" in var_opt_int_k) { ++ k = var_opt_int_k["param_stack_clash_protection_probe_interval"] ++ j = var_opt_int_j["param_stack_clash_protection_probe_interval"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_store_merging_allow_unaligned" in var_opt_int_k) { ++ k = var_opt_int_k["param_store_merging_allow_unaligned"] ++ j = var_opt_int_j["param_store_merging_allow_unaligned"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_store_merging_max_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_store_merging_max_size"] ++ j = var_opt_int_j["param_store_merging_max_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_struct_reorg_cold_struct_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_struct_reorg_cold_struct_ratio"] ++ j = var_opt_int_j["param_struct_reorg_cold_struct_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_switch_conversion_branch_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_switch_conversion_branch_ratio"] ++ j = var_opt_int_j["param_switch_conversion_branch_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tm_max_aggregate_size" in var_opt_int_k) { ++ k = var_opt_int_k["param_tm_max_aggregate_size"] ++ j = var_opt_int_j["param_tm_max_aggregate_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tracer_dynamic_coverage_feedback" in var_opt_int_k) { ++ k = var_opt_int_k["param_tracer_dynamic_coverage_feedback"] ++ j = var_opt_int_j["param_tracer_dynamic_coverage_feedback"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tracer_dynamic_coverage" in var_opt_int_k) { ++ k = var_opt_int_k["param_tracer_dynamic_coverage"] ++ j = var_opt_int_j["param_tracer_dynamic_coverage"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tracer_max_code_growth" in var_opt_int_k) { ++ k = var_opt_int_k["param_tracer_max_code_growth"] ++ j = var_opt_int_j["param_tracer_max_code_growth"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tracer_min_branch_probability_feedback" in var_opt_int_k) { ++ k = var_opt_int_k["param_tracer_min_branch_probability_feedback"] ++ j = var_opt_int_j["param_tracer_min_branch_probability_feedback"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tracer_min_branch_probability" in var_opt_int_k) { ++ k = var_opt_int_k["param_tracer_min_branch_probability"] ++ j = var_opt_int_j["param_tracer_min_branch_probability"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tracer_min_branch_ratio" in var_opt_int_k) { ++ k = var_opt_int_k["param_tracer_min_branch_ratio"] ++ j = var_opt_int_j["param_tracer_min_branch_ratio"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_tree_reassoc_width" in var_opt_int_k) { ++ k = var_opt_int_k["param_tree_reassoc_width"] ++ j = var_opt_int_j["param_tree_reassoc_width"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_uninit_control_dep_attempts" in var_opt_int_k) { ++ k = var_opt_int_k["param_uninit_control_dep_attempts"] ++ j = var_opt_int_j["param_uninit_control_dep_attempts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_uninlined_function_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_uninlined_function_insns"] ++ j = var_opt_int_j["param_uninlined_function_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_uninlined_function_time" in var_opt_int_k) { ++ k = var_opt_int_k["param_uninlined_function_time"] ++ j = var_opt_int_j["param_uninlined_function_time"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_uninlined_function_thunk_insns" in var_opt_int_k) { ++ k = var_opt_int_k["param_uninlined_function_thunk_insns"] ++ j = var_opt_int_j["param_uninlined_function_thunk_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_uninlined_function_thunk_time" in var_opt_int_k) { ++ k = var_opt_int_k["param_uninlined_function_thunk_time"] ++ j = var_opt_int_j["param_uninlined_function_thunk_time"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_unlikely_bb_count_fraction" in var_opt_int_k) { ++ k = var_opt_int_k["param_unlikely_bb_count_fraction"] ++ j = var_opt_int_j["param_unlikely_bb_count_fraction"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_unroll_jam_max_unroll" in var_opt_int_k) { ++ k = var_opt_int_k["param_unroll_jam_max_unroll"] ++ j = var_opt_int_j["param_unroll_jam_max_unroll"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_unroll_jam_min_percent" in var_opt_int_k) { ++ k = var_opt_int_k["param_unroll_jam_min_percent"] ++ j = var_opt_int_j["param_unroll_jam_min_percent"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_use_after_scope_direct_emission_threshold" in var_opt_int_k) { ++ k = var_opt_int_k["param_use_after_scope_direct_emission_threshold"] ++ j = var_opt_int_j["param_use_after_scope_direct_emission_threshold"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_flexible_seg_len" in var_opt_int_k) { ++ k = var_opt_int_k["param_flexible_seg_len"] ++ j = var_opt_int_j["param_flexible_seg_len"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_epilogues_nomask" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_epilogues_nomask"] ++ j = var_opt_int_j["param_vect_epilogues_nomask"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_induction_float" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_induction_float"] ++ j = var_opt_int_j["param_vect_induction_float"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_inner_loop_cost_factor" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_inner_loop_cost_factor"] ++ j = var_opt_int_j["param_vect_inner_loop_cost_factor"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_max_peeling_for_alignment" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_max_peeling_for_alignment"] ++ j = var_opt_int_j["param_vect_max_peeling_for_alignment"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_max_version_for_alias_checks" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_max_version_for_alias_checks"] ++ j = var_opt_int_j["param_vect_max_version_for_alias_checks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_max_version_for_alignment_checks" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_max_version_for_alignment_checks"] ++ j = var_opt_int_j["param_vect_max_version_for_alignment_checks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vect_partial_vector_usage" in var_opt_int_k) { ++ k = var_opt_int_k["param_vect_partial_vector_usage"] ++ j = var_opt_int_j["param_vect_partial_vector_usage"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_stalled_insns" in var_opt_int_k) { ++ k = var_opt_int_k["flag_sched_stalled_insns"] ++ j = var_opt_int_j["flag_sched_stalled_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_stalled_insns_dep" in var_opt_int_k) { ++ k = var_opt_int_k["flag_sched_stalled_insns_dep"] ++ j = var_opt_int_j["flag_sched_stalled_insns_dep"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_parallelize_loops" in var_opt_int_k) { ++ k = var_opt_int_k["flag_tree_parallelize_loops"] ++ j = var_opt_int_j["flag_tree_parallelize_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_evrp_mode" in var_opt_enum_k) { ++ k = var_opt_enum_k["param_evrp_mode"] ++ j = var_opt_enum_j["param_evrp_mode"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_ranger_debug" in var_opt_enum_k) { ++ k = var_opt_enum_k["param_ranger_debug"] ++ j = var_opt_enum_j["param_ranger_debug"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_threader_debug" in var_opt_enum_k) { ++ k = var_opt_enum_k["param_threader_debug"] ++ j = var_opt_enum_j["param_threader_debug"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vrp1_mode" in var_opt_enum_k) { ++ k = var_opt_enum_k["param_vrp1_mode"] ++ j = var_opt_enum_j["param_vrp1_mode"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("param_vrp2_mode" in var_opt_enum_k) { ++ k = var_opt_enum_k["param_vrp2_mode"] ++ j = var_opt_enum_j["param_vrp2_mode"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_excess_precision" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_excess_precision"] ++ j = var_opt_enum_j["flag_excess_precision"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_fp_contract_mode" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_fp_contract_mode"] ++ j = var_opt_enum_j["flag_fp_contract_mode"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[3] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ira_algorithm" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_ira_algorithm"] ++ j = var_opt_enum_j["flag_ira_algorithm"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ira_region" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_ira_region"] ++ j = var_opt_enum_j["flag_ira_region"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_live_patching" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_live_patching"] ++ j = var_opt_enum_j["flag_live_patching"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_fp_model" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_fp_model"] ++ j = var_opt_enum_j["flag_fp_model"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_reorder_blocks_algorithm" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_reorder_blocks_algorithm"] ++ j = var_opt_enum_j["flag_reorder_blocks_algorithm"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_simd_cost_model" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_simd_cost_model"] ++ j = var_opt_enum_j["flag_simd_cost_model"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_stack_reuse" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_stack_reuse"] ++ j = var_opt_enum_j["flag_stack_reuse"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_auto_var_init" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_auto_var_init"] ++ j = var_opt_enum_j["flag_auto_var_init"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_vect_cost_model" in var_opt_enum_k) { ++ k = var_opt_enum_k["flag_vect_cost_model"] ++ j = var_opt_enum_j["flag_vect_cost_model"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("optimize" in var_opt_char_k) { ++ k = var_opt_char_k["optimize"] ++ j = var_opt_char_j["optimize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("optimize_size" in var_opt_char_k) { ++ k = var_opt_char_k["optimize_size"] ++ j = var_opt_char_j["optimize_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("optimize_debug" in var_opt_char_k) { ++ k = var_opt_char_k["optimize_debug"] ++ j = var_opt_char_j["optimize_debug"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("optimize_fast" in var_opt_char_k) { ++ k = var_opt_char_k["optimize_fast"] ++ j = var_opt_char_j["optimize_fast"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("warn_inline" in var_opt_char_k) { ++ k = var_opt_char_k["warn_inline"] ++ j = var_opt_char_j["warn_inline"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_aggressive_loop_optimizations" in var_opt_char_k) { ++ k = var_opt_char_k["flag_aggressive_loop_optimizations"] ++ j = var_opt_char_j["flag_aggressive_loop_optimizations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_align_functions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_align_functions"] ++ j = var_opt_char_j["flag_align_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_align_jumps" in var_opt_char_k) { ++ k = var_opt_char_k["flag_align_jumps"] ++ j = var_opt_char_j["flag_align_jumps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_align_labels" in var_opt_char_k) { ++ k = var_opt_char_k["flag_align_labels"] ++ j = var_opt_char_j["flag_align_labels"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_align_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_align_loops"] ++ j = var_opt_char_j["flag_align_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_allocation_dce" in var_opt_char_k) { ++ k = var_opt_char_k["flag_allocation_dce"] ++ j = var_opt_char_j["flag_allocation_dce"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_store_data_races" in var_opt_char_k) { ++ k = var_opt_char_k["flag_store_data_races"] ++ j = var_opt_char_j["flag_store_data_races"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_array_widen_compare" in var_opt_char_k) { ++ k = var_opt_char_k["flag_array_widen_compare"] ++ j = var_opt_char_j["flag_array_widen_compare"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_associative_math" in var_opt_char_k) { ++ k = var_opt_char_k["flag_associative_math"] ++ j = var_opt_char_j["flag_associative_math"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_asynchronous_unwind_tables" in var_opt_char_k) { ++ k = var_opt_char_k["flag_asynchronous_unwind_tables"] ++ j = var_opt_char_j["flag_asynchronous_unwind_tables"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_auto_inc_dec" in var_opt_char_k) { ++ k = var_opt_char_k["flag_auto_inc_dec"] ++ j = var_opt_char_j["flag_auto_inc_dec"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_bit_tests" in var_opt_char_k) { ++ k = var_opt_char_k["flag_bit_tests"] ++ j = var_opt_char_j["flag_bit_tests"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_branch_on_count_reg" in var_opt_char_k) { ++ k = var_opt_char_k["flag_branch_on_count_reg"] ++ j = var_opt_char_j["flag_branch_on_count_reg"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_branch_probabilities" in var_opt_char_k) { ++ k = var_opt_char_k["flag_branch_probabilities"] ++ j = var_opt_char_j["flag_branch_probabilities"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_caller_saves" in var_opt_char_k) { ++ k = var_opt_char_k["flag_caller_saves"] ++ j = var_opt_char_j["flag_caller_saves"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ccmp2" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ccmp2"] ++ j = var_opt_char_j["flag_ccmp2"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_code_hoisting" in var_opt_char_k) { ++ k = var_opt_char_k["flag_code_hoisting"] ++ j = var_opt_char_j["flag_code_hoisting"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_combine_stack_adjustments" in var_opt_char_k) { ++ k = var_opt_char_k["flag_combine_stack_adjustments"] ++ j = var_opt_char_j["flag_combine_stack_adjustments"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_compare_elim_after_reload" in var_opt_char_k) { ++ k = var_opt_char_k["flag_compare_elim_after_reload"] ++ j = var_opt_char_j["flag_compare_elim_after_reload"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_conserve_stack" in var_opt_char_k) { ++ k = var_opt_char_k["flag_conserve_stack"] ++ j = var_opt_char_j["flag_conserve_stack"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_convert_minmax" in var_opt_char_k) { ++ k = var_opt_char_k["flag_convert_minmax"] ++ j = var_opt_char_j["flag_convert_minmax"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_cprop_registers" in var_opt_char_k) { ++ k = var_opt_char_k["flag_cprop_registers"] ++ j = var_opt_char_j["flag_cprop_registers"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_crossjumping" in var_opt_char_k) { ++ k = var_opt_char_k["flag_crossjumping"] ++ j = var_opt_char_j["flag_crossjumping"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_crypto_accel_aes" in var_opt_char_k) { ++ k = var_opt_char_k["flag_crypto_accel_aes"] ++ j = var_opt_char_j["flag_crypto_accel_aes"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_cse_follow_jumps" in var_opt_char_k) { ++ k = var_opt_char_k["flag_cse_follow_jumps"] ++ j = var_opt_char_j["flag_cse_follow_jumps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_cx_fortran_rules" in var_opt_char_k) { ++ k = var_opt_char_k["flag_cx_fortran_rules"] ++ j = var_opt_char_j["flag_cx_fortran_rules"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_cx_limited_range" in var_opt_char_k) { ++ k = var_opt_char_k["flag_cx_limited_range"] ++ j = var_opt_char_j["flag_cx_limited_range"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_dce" in var_opt_char_k) { ++ k = var_opt_char_k["flag_dce"] ++ j = var_opt_char_j["flag_dce"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_defer_pop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_defer_pop"] ++ j = var_opt_char_j["flag_defer_pop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_delayed_branch" in var_opt_char_k) { ++ k = var_opt_char_k["flag_delayed_branch"] ++ j = var_opt_char_j["flag_delayed_branch"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_delete_dead_exceptions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_delete_dead_exceptions"] ++ j = var_opt_char_j["flag_delete_dead_exceptions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_delete_null_pointer_checks" in var_opt_char_k) { ++ k = var_opt_char_k["flag_delete_null_pointer_checks"] ++ j = var_opt_char_j["flag_delete_null_pointer_checks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_devirtualize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_devirtualize"] ++ j = var_opt_char_j["flag_devirtualize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_devirtualize_speculatively" in var_opt_char_k) { ++ k = var_opt_char_k["flag_devirtualize_speculatively"] ++ j = var_opt_char_j["flag_devirtualize_speculatively"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_dse" in var_opt_char_k) { ++ k = var_opt_char_k["flag_dse"] ++ j = var_opt_char_j["flag_dse"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_early_inlining" in var_opt_char_k) { ++ k = var_opt_char_k["flag_early_inlining"] ++ j = var_opt_char_j["flag_early_inlining"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_exceptions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_exceptions"] ++ j = var_opt_char_j["flag_exceptions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_expensive_optimizations" in var_opt_char_k) { ++ k = var_opt_char_k["flag_expensive_optimizations"] ++ j = var_opt_char_j["flag_expensive_optimizations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_finite_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_finite_loops"] ++ j = var_opt_char_j["flag_finite_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_finite_math_only" in var_opt_char_k) { ++ k = var_opt_char_k["flag_finite_math_only"] ++ j = var_opt_char_j["flag_finite_math_only"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_float_store" in var_opt_char_k) { ++ k = var_opt_char_k["flag_float_store"] ++ j = var_opt_char_j["flag_float_store"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_fold_simple_inlines" in var_opt_char_k) { ++ k = var_opt_char_k["flag_fold_simple_inlines"] ++ j = var_opt_char_j["flag_fold_simple_inlines"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_forward_propagate" in var_opt_char_k) { ++ k = var_opt_char_k["flag_forward_propagate"] ++ j = var_opt_char_j["flag_forward_propagate"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_fp_int_builtin_inexact" in var_opt_char_k) { ++ k = var_opt_char_k["flag_fp_int_builtin_inexact"] ++ j = var_opt_char_j["flag_fp_int_builtin_inexact"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ftz" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ftz"] ++ j = var_opt_char_j["flag_ftz"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_no_function_cse" in var_opt_char_k) { ++ k = var_opt_char_k["flag_no_function_cse"] ++ j = var_opt_char_j["flag_no_function_cse"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_gcse" in var_opt_char_k) { ++ k = var_opt_char_k["flag_gcse"] ++ j = var_opt_char_j["flag_gcse"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_gcse_after_reload" in var_opt_char_k) { ++ k = var_opt_char_k["flag_gcse_after_reload"] ++ j = var_opt_char_j["flag_gcse_after_reload"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_gcse_las" in var_opt_char_k) { ++ k = var_opt_char_k["flag_gcse_las"] ++ j = var_opt_char_j["flag_gcse_las"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_gcse_lm" in var_opt_char_k) { ++ k = var_opt_char_k["flag_gcse_lm"] ++ j = var_opt_char_j["flag_gcse_lm"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[4] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_gcse_sm" in var_opt_char_k) { ++ k = var_opt_char_k["flag_gcse_sm"] ++ j = var_opt_char_j["flag_gcse_sm"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_graphite" in var_opt_char_k) { ++ k = var_opt_char_k["flag_graphite"] ++ j = var_opt_char_j["flag_graphite"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_graphite_identity" in var_opt_char_k) { ++ k = var_opt_char_k["flag_graphite_identity"] ++ j = var_opt_char_j["flag_graphite_identity"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_guess_branch_prob" in var_opt_char_k) { ++ k = var_opt_char_k["flag_guess_branch_prob"] ++ j = var_opt_char_j["flag_guess_branch_prob"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_harden_compares" in var_opt_char_k) { ++ k = var_opt_char_k["flag_harden_compares"] ++ j = var_opt_char_j["flag_harden_compares"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_harden_conditional_branches" in var_opt_char_k) { ++ k = var_opt_char_k["flag_harden_conditional_branches"] ++ j = var_opt_char_j["flag_harden_conditional_branches"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_hoist_adjacent_loads" in var_opt_char_k) { ++ k = var_opt_char_k["flag_hoist_adjacent_loads"] ++ j = var_opt_char_j["flag_hoist_adjacent_loads"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_icp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_icp"] ++ j = var_opt_char_j["flag_icp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_icp_speculatively" in var_opt_char_k) { ++ k = var_opt_char_k["flag_icp_speculatively"] ++ j = var_opt_char_j["flag_icp_speculatively"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_if_conversion" in var_opt_char_k) { ++ k = var_opt_char_k["flag_if_conversion"] ++ j = var_opt_char_j["flag_if_conversion"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_if_conversion_gimple" in var_opt_char_k) { ++ k = var_opt_char_k["flag_if_conversion_gimple"] ++ j = var_opt_char_j["flag_if_conversion_gimple"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_if_conversion2" in var_opt_char_k) { ++ k = var_opt_char_k["flag_if_conversion2"] ++ j = var_opt_char_j["flag_if_conversion2"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ifcvt_allow_complicated_cmps" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ifcvt_allow_complicated_cmps"] ++ j = var_opt_char_j["flag_ifcvt_allow_complicated_cmps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_indirect_inlining" in var_opt_char_k) { ++ k = var_opt_char_k["flag_indirect_inlining"] ++ j = var_opt_char_j["flag_indirect_inlining"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_no_inline" in var_opt_char_k) { ++ k = var_opt_char_k["flag_no_inline"] ++ j = var_opt_char_j["flag_no_inline"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_inline_atomics" in var_opt_char_k) { ++ k = var_opt_char_k["flag_inline_atomics"] ++ j = var_opt_char_j["flag_inline_atomics"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_inline_functions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_inline_functions"] ++ j = var_opt_char_j["flag_inline_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_inline_functions_called_once" in var_opt_char_k) { ++ k = var_opt_char_k["flag_inline_functions_called_once"] ++ j = var_opt_char_j["flag_inline_functions_called_once"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_inline_small_functions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_inline_small_functions"] ++ j = var_opt_char_j["flag_inline_small_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_bit_cp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_bit_cp"] ++ j = var_opt_char_j["flag_ipa_bit_cp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_cp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_cp"] ++ j = var_opt_char_j["flag_ipa_cp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_cp_clone" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_cp_clone"] ++ j = var_opt_char_j["flag_ipa_cp_clone"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_ic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_ic"] ++ j = var_opt_char_j["flag_ipa_ic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_icf" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_icf"] ++ j = var_opt_char_j["flag_ipa_icf"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_icf_functions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_icf_functions"] ++ j = var_opt_char_j["flag_ipa_icf_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_icf_variables" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_icf_variables"] ++ j = var_opt_char_j["flag_ipa_icf_variables"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_modref" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_modref"] ++ j = var_opt_char_j["flag_ipa_modref"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_prefetch" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_prefetch"] ++ j = var_opt_char_j["flag_ipa_prefetch"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_profile" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_profile"] ++ j = var_opt_char_j["flag_ipa_profile"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_pta" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_pta"] ++ j = var_opt_char_j["flag_ipa_pta"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_pure_const" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_pure_const"] ++ j = var_opt_char_j["flag_ipa_pure_const"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_ra" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_ra"] ++ j = var_opt_char_j["flag_ipa_ra"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_reference" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_reference"] ++ j = var_opt_char_j["flag_ipa_reference"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_reference_addressable" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_reference_addressable"] ++ j = var_opt_char_j["flag_ipa_reference_addressable"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_reorder_fields" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_reorder_fields"] ++ j = var_opt_char_j["flag_ipa_reorder_fields"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_sra" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_sra"] ++ j = var_opt_char_j["flag_ipa_sra"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_stack_alignment" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_stack_alignment"] ++ j = var_opt_char_j["flag_ipa_stack_alignment"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_strict_aliasing" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_strict_aliasing"] ++ j = var_opt_char_j["flag_ipa_strict_aliasing"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_struct_reorg" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_struct_reorg"] ++ j = var_opt_char_j["flag_ipa_struct_reorg"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ipa_vrp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ipa_vrp"] ++ j = var_opt_char_j["flag_ipa_vrp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ira_hoist_pressure" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ira_hoist_pressure"] ++ j = var_opt_char_j["flag_ira_hoist_pressure"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ira_loop_pressure" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ira_loop_pressure"] ++ j = var_opt_char_j["flag_ira_loop_pressure"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ira_share_save_slots" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ira_share_save_slots"] ++ j = var_opt_char_j["flag_ira_share_save_slots"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ira_share_spill_slots" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ira_share_spill_slots"] ++ j = var_opt_char_j["flag_ira_share_spill_slots"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_isolate_erroneous_paths_attribute" in var_opt_char_k) { ++ k = var_opt_char_k["flag_isolate_erroneous_paths_attribute"] ++ j = var_opt_char_j["flag_isolate_erroneous_paths_attribute"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_isolate_erroneous_paths_dereference" in var_opt_char_k) { ++ k = var_opt_char_k["flag_isolate_erroneous_paths_dereference"] ++ j = var_opt_char_j["flag_isolate_erroneous_paths_dereference"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ivopts" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ivopts"] ++ j = var_opt_char_j["flag_ivopts"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_jump_tables" in var_opt_char_k) { ++ k = var_opt_char_k["flag_jump_tables"] ++ j = var_opt_char_j["flag_jump_tables"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_keep_gc_roots_live" in var_opt_char_k) { ++ k = var_opt_char_k["flag_keep_gc_roots_live"] ++ j = var_opt_char_j["flag_keep_gc_roots_live"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_kernel_pgo" in var_opt_char_k) { ++ k = var_opt_char_k["flag_kernel_pgo"] ++ j = var_opt_char_j["flag_kernel_pgo"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_lifetime_dse" in var_opt_char_k) { ++ k = var_opt_char_k["flag_lifetime_dse"] ++ j = var_opt_char_j["flag_lifetime_dse"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_limit_function_alignment" in var_opt_char_k) { ++ k = var_opt_char_k["flag_limit_function_alignment"] ++ j = var_opt_char_j["flag_limit_function_alignment"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_live_range_shrinkage" in var_opt_char_k) { ++ k = var_opt_char_k["flag_live_range_shrinkage"] ++ j = var_opt_char_j["flag_live_range_shrinkage"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_loop_crc" in var_opt_char_k) { ++ k = var_opt_char_k["flag_loop_crc"] ++ j = var_opt_char_j["flag_loop_crc"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_loop_elim" in var_opt_char_k) { ++ k = var_opt_char_k["flag_loop_elim"] ++ j = var_opt_char_j["flag_loop_elim"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_loop_interchange" in var_opt_char_k) { ++ k = var_opt_char_k["flag_loop_interchange"] ++ j = var_opt_char_j["flag_loop_interchange"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_loop_nest_optimize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_loop_nest_optimize"] ++ j = var_opt_char_j["flag_loop_nest_optimize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_loop_parallelize_all" in var_opt_char_k) { ++ k = var_opt_char_k["flag_loop_parallelize_all"] ++ j = var_opt_char_j["flag_loop_parallelize_all"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unroll_jam" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unroll_jam"] ++ j = var_opt_char_j["flag_unroll_jam"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_lra_remat" in var_opt_char_k) { ++ k = var_opt_char_k["flag_lra_remat"] ++ j = var_opt_char_j["flag_lra_remat"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_errno_math" in var_opt_char_k) { ++ k = var_opt_char_k["flag_errno_math"] ++ j = var_opt_char_j["flag_errno_math"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_merge_mull" in var_opt_char_k) { ++ k = var_opt_char_k["flag_merge_mull"] ++ j = var_opt_char_j["flag_merge_mull"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_modulo_sched" in var_opt_char_k) { ++ k = var_opt_char_k["flag_modulo_sched"] ++ j = var_opt_char_j["flag_modulo_sched"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_modulo_sched_allow_regmoves" in var_opt_char_k) { ++ k = var_opt_char_k["flag_modulo_sched_allow_regmoves"] ++ j = var_opt_char_j["flag_modulo_sched_allow_regmoves"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[5] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_move_loop_invariants" in var_opt_char_k) { ++ k = var_opt_char_k["flag_move_loop_invariants"] ++ j = var_opt_char_j["flag_move_loop_invariants"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_move_loop_stores" in var_opt_char_k) { ++ k = var_opt_char_k["flag_move_loop_stores"] ++ j = var_opt_char_j["flag_move_loop_stores"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_non_call_exceptions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_non_call_exceptions"] ++ j = var_opt_char_j["flag_non_call_exceptions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_nothrow_opt" in var_opt_char_k) { ++ k = var_opt_char_k["flag_nothrow_opt"] ++ j = var_opt_char_j["flag_nothrow_opt"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_omit_frame_pointer" in var_opt_char_k) { ++ k = var_opt_char_k["flag_omit_frame_pointer"] ++ j = var_opt_char_j["flag_omit_frame_pointer"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_opt_info" in var_opt_char_k) { ++ k = var_opt_char_k["flag_opt_info"] ++ j = var_opt_char_j["flag_opt_info"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_optimize_sibling_calls" in var_opt_char_k) { ++ k = var_opt_char_k["flag_optimize_sibling_calls"] ++ j = var_opt_char_j["flag_optimize_sibling_calls"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_optimize_strlen" in var_opt_char_k) { ++ k = var_opt_char_k["flag_optimize_strlen"] ++ j = var_opt_char_j["flag_optimize_strlen"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_pack_struct" in var_opt_char_k) { ++ k = var_opt_char_k["flag_pack_struct"] ++ j = var_opt_char_j["flag_pack_struct"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_partial_inlining" in var_opt_char_k) { ++ k = var_opt_char_k["flag_partial_inlining"] ++ j = var_opt_char_j["flag_partial_inlining"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_peel_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_peel_loops"] ++ j = var_opt_char_j["flag_peel_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_no_peephole" in var_opt_char_k) { ++ k = var_opt_char_k["flag_no_peephole"] ++ j = var_opt_char_j["flag_no_peephole"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_peephole2" in var_opt_char_k) { ++ k = var_opt_char_k["flag_peephole2"] ++ j = var_opt_char_j["flag_peephole2"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_plt" in var_opt_char_k) { ++ k = var_opt_char_k["flag_plt"] ++ j = var_opt_char_j["flag_plt"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_predictive_commoning" in var_opt_char_k) { ++ k = var_opt_char_k["flag_predictive_commoning"] ++ j = var_opt_char_j["flag_predictive_commoning"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_prefetch_loop_arrays" in var_opt_char_k) { ++ k = var_opt_char_k["flag_prefetch_loop_arrays"] ++ j = var_opt_char_j["flag_prefetch_loop_arrays"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_printf_return_value" in var_opt_char_k) { ++ k = var_opt_char_k["flag_printf_return_value"] ++ j = var_opt_char_j["flag_printf_return_value"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_profile_partial_training" in var_opt_char_k) { ++ k = var_opt_char_k["flag_profile_partial_training"] ++ j = var_opt_char_j["flag_profile_partial_training"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_profile_reorder_functions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_profile_reorder_functions"] ++ j = var_opt_char_j["flag_profile_reorder_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_reciprocal_math" in var_opt_char_k) { ++ k = var_opt_char_k["flag_reciprocal_math"] ++ j = var_opt_char_j["flag_reciprocal_math"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ree" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ree"] ++ j = var_opt_char_j["flag_ree"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_pcc_struct_return" in var_opt_char_k) { ++ k = var_opt_char_k["flag_pcc_struct_return"] ++ j = var_opt_char_j["flag_pcc_struct_return"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_rename_registers" in var_opt_char_k) { ++ k = var_opt_char_k["flag_rename_registers"] ++ j = var_opt_char_j["flag_rename_registers"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_reorder_blocks" in var_opt_char_k) { ++ k = var_opt_char_k["flag_reorder_blocks"] ++ j = var_opt_char_j["flag_reorder_blocks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_reorder_blocks_and_partition" in var_opt_char_k) { ++ k = var_opt_char_k["flag_reorder_blocks_and_partition"] ++ j = var_opt_char_j["flag_reorder_blocks_and_partition"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_reorder_functions" in var_opt_char_k) { ++ k = var_opt_char_k["flag_reorder_functions"] ++ j = var_opt_char_j["flag_reorder_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_rerun_cse_after_loop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_rerun_cse_after_loop"] ++ j = var_opt_char_j["flag_rerun_cse_after_loop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_resched_modulo_sched" in var_opt_char_k) { ++ k = var_opt_char_k["flag_resched_modulo_sched"] ++ j = var_opt_char_j["flag_resched_modulo_sched"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_rounding_math" in var_opt_char_k) { ++ k = var_opt_char_k["flag_rounding_math"] ++ j = var_opt_char_j["flag_rounding_math"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_rtti" in var_opt_char_k) { ++ k = var_opt_char_k["flag_rtti"] ++ j = var_opt_char_j["flag_rtti"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_save_optimization_record" in var_opt_char_k) { ++ k = var_opt_char_k["flag_save_optimization_record"] ++ j = var_opt_char_j["flag_save_optimization_record"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_critical_path_heuristic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_critical_path_heuristic"] ++ j = var_opt_char_j["flag_sched_critical_path_heuristic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_dep_count_heuristic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_dep_count_heuristic"] ++ j = var_opt_char_j["flag_sched_dep_count_heuristic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_group_heuristic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_group_heuristic"] ++ j = var_opt_char_j["flag_sched_group_heuristic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_interblock" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_interblock"] ++ j = var_opt_char_j["flag_schedule_interblock"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_last_insn_heuristic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_last_insn_heuristic"] ++ j = var_opt_char_j["flag_sched_last_insn_heuristic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_pressure" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_pressure"] ++ j = var_opt_char_j["flag_sched_pressure"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_rank_heuristic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_rank_heuristic"] ++ j = var_opt_char_j["flag_sched_rank_heuristic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_speculative" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_speculative"] ++ j = var_opt_char_j["flag_schedule_speculative"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched_spec_insn_heuristic" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched_spec_insn_heuristic"] ++ j = var_opt_char_j["flag_sched_spec_insn_heuristic"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_speculative_load" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_speculative_load"] ++ j = var_opt_char_j["flag_schedule_speculative_load"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_speculative_load_dangerous" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_speculative_load_dangerous"] ++ j = var_opt_char_j["flag_schedule_speculative_load_dangerous"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sched2_use_superblocks" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sched2_use_superblocks"] ++ j = var_opt_char_j["flag_sched2_use_superblocks"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_fusion" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_fusion"] ++ j = var_opt_char_j["flag_schedule_fusion"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_insns" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_insns"] ++ j = var_opt_char_j["flag_schedule_insns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_schedule_insns_after_reload" in var_opt_char_k) { ++ k = var_opt_char_k["flag_schedule_insns_after_reload"] ++ j = var_opt_char_j["flag_schedule_insns_after_reload"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_section_anchors" in var_opt_char_k) { ++ k = var_opt_char_k["flag_section_anchors"] ++ j = var_opt_char_j["flag_section_anchors"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sel_sched_pipelining" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sel_sched_pipelining"] ++ j = var_opt_char_j["flag_sel_sched_pipelining"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sel_sched_pipelining_outer_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sel_sched_pipelining_outer_loops"] ++ j = var_opt_char_j["flag_sel_sched_pipelining_outer_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_sel_sched_reschedule_pipelined" in var_opt_char_k) { ++ k = var_opt_char_k["flag_sel_sched_reschedule_pipelined"] ++ j = var_opt_char_j["flag_sel_sched_reschedule_pipelined"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_selective_scheduling" in var_opt_char_k) { ++ k = var_opt_char_k["flag_selective_scheduling"] ++ j = var_opt_char_j["flag_selective_scheduling"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_selective_scheduling2" in var_opt_char_k) { ++ k = var_opt_char_k["flag_selective_scheduling2"] ++ j = var_opt_char_j["flag_selective_scheduling2"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_semantic_interposition" in var_opt_char_k) { ++ k = var_opt_char_k["flag_semantic_interposition"] ++ j = var_opt_char_j["flag_semantic_interposition"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_short_enums" in var_opt_char_k) { ++ k = var_opt_char_k["flag_short_enums"] ++ j = var_opt_char_j["flag_short_enums"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_short_wchar" in var_opt_char_k) { ++ k = var_opt_char_k["flag_short_wchar"] ++ j = var_opt_char_j["flag_short_wchar"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_shrink_wrap" in var_opt_char_k) { ++ k = var_opt_char_k["flag_shrink_wrap"] ++ j = var_opt_char_j["flag_shrink_wrap"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_shrink_wrap_separate" in var_opt_char_k) { ++ k = var_opt_char_k["flag_shrink_wrap_separate"] ++ j = var_opt_char_j["flag_shrink_wrap_separate"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_signaling_nans" in var_opt_char_k) { ++ k = var_opt_char_k["flag_signaling_nans"] ++ j = var_opt_char_j["flag_signaling_nans"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_signed_zeros" in var_opt_char_k) { ++ k = var_opt_char_k["flag_signed_zeros"] ++ j = var_opt_char_j["flag_signed_zeros"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_simdmath" in var_opt_char_k) { ++ k = var_opt_char_k["flag_simdmath"] ++ j = var_opt_char_j["flag_simdmath"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_single_precision_constant" in var_opt_char_k) { ++ k = var_opt_char_k["flag_single_precision_constant"] ++ j = var_opt_char_j["flag_single_precision_constant"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_split_ivs_in_unroller" in var_opt_char_k) { ++ k = var_opt_char_k["flag_split_ivs_in_unroller"] ++ j = var_opt_char_j["flag_split_ivs_in_unroller"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_split_ldp_stp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_split_ldp_stp"] ++ j = var_opt_char_j["flag_split_ldp_stp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_split_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_split_loops"] ++ j = var_opt_char_j["flag_split_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[6] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_split_paths" in var_opt_char_k) { ++ k = var_opt_char_k["flag_split_paths"] ++ j = var_opt_char_j["flag_split_paths"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_split_wide_types" in var_opt_char_k) { ++ k = var_opt_char_k["flag_split_wide_types"] ++ j = var_opt_char_j["flag_split_wide_types"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_split_wide_types_early" in var_opt_char_k) { ++ k = var_opt_char_k["flag_split_wide_types_early"] ++ j = var_opt_char_j["flag_split_wide_types_early"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ssa_backprop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ssa_backprop"] ++ j = var_opt_char_j["flag_ssa_backprop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_ssa_phiopt" in var_opt_char_k) { ++ k = var_opt_char_k["flag_ssa_phiopt"] ++ j = var_opt_char_j["flag_ssa_phiopt"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_stack_clash_protection" in var_opt_char_k) { ++ k = var_opt_char_k["flag_stack_clash_protection"] ++ j = var_opt_char_j["flag_stack_clash_protection"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_stack_protect" in var_opt_char_k) { ++ k = var_opt_char_k["flag_stack_protect"] ++ j = var_opt_char_j["flag_stack_protect"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_stdarg_opt" in var_opt_char_k) { ++ k = var_opt_char_k["flag_stdarg_opt"] ++ j = var_opt_char_j["flag_stdarg_opt"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_store_merging" in var_opt_char_k) { ++ k = var_opt_char_k["flag_store_merging"] ++ j = var_opt_char_j["flag_store_merging"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_strict_aliasing" in var_opt_char_k) { ++ k = var_opt_char_k["flag_strict_aliasing"] ++ j = var_opt_char_j["flag_strict_aliasing"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_strict_enums" in var_opt_char_k) { ++ k = var_opt_char_k["flag_strict_enums"] ++ j = var_opt_char_j["flag_strict_enums"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_strict_volatile_bitfields" in var_opt_char_k) { ++ k = var_opt_char_k["flag_strict_volatile_bitfields"] ++ j = var_opt_char_j["flag_strict_volatile_bitfields"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_thread_jumps" in var_opt_char_k) { ++ k = var_opt_char_k["flag_thread_jumps"] ++ j = var_opt_char_j["flag_thread_jumps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_threadsafe_statics" in var_opt_char_k) { ++ k = var_opt_char_k["flag_threadsafe_statics"] ++ j = var_opt_char_j["flag_threadsafe_statics"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_toplevel_reorder" in var_opt_char_k) { ++ k = var_opt_char_k["flag_toplevel_reorder"] ++ j = var_opt_char_j["flag_toplevel_reorder"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tracer" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tracer"] ++ j = var_opt_char_j["flag_tracer"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_trapping_math" in var_opt_char_k) { ++ k = var_opt_char_k["flag_trapping_math"] ++ j = var_opt_char_j["flag_trapping_math"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_trapv" in var_opt_char_k) { ++ k = var_opt_char_k["flag_trapv"] ++ j = var_opt_char_j["flag_trapv"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_bit_ccp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_bit_ccp"] ++ j = var_opt_char_j["flag_tree_bit_ccp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 18) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_builtin_call_dce" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_builtin_call_dce"] ++ j = var_opt_char_j["flag_tree_builtin_call_dce"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 19) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_ccp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_ccp"] ++ j = var_opt_char_j["flag_tree_ccp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 20) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_ch" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_ch"] ++ j = var_opt_char_j["flag_tree_ch"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 21) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_coalesce_vars" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_coalesce_vars"] ++ j = var_opt_char_j["flag_tree_coalesce_vars"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 22) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_copy_prop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_copy_prop"] ++ j = var_opt_char_j["flag_tree_copy_prop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 23) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_cselim" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_cselim"] ++ j = var_opt_char_j["flag_tree_cselim"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 24) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_dce" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_dce"] ++ j = var_opt_char_j["flag_tree_dce"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 25) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_dom" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_dom"] ++ j = var_opt_char_j["flag_tree_dom"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 26) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_dse" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_dse"] ++ j = var_opt_char_j["flag_tree_dse"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 27) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_forwprop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_forwprop"] ++ j = var_opt_char_j["flag_tree_forwprop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 28) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_fre" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_fre"] ++ j = var_opt_char_j["flag_tree_fre"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 29) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_distribute_patterns" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_distribute_patterns"] ++ j = var_opt_char_j["flag_tree_loop_distribute_patterns"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 30) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_distribution" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_distribution"] ++ j = var_opt_char_j["flag_tree_loop_distribution"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 31) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_if_convert" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_if_convert"] ++ j = var_opt_char_j["flag_tree_loop_if_convert"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 32) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_im" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_im"] ++ j = var_opt_char_j["flag_tree_loop_im"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 33) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_ivcanon" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_ivcanon"] ++ j = var_opt_char_j["flag_tree_loop_ivcanon"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 34) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_optimize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_optimize"] ++ j = var_opt_char_j["flag_tree_loop_optimize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 35) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_loop_vectorize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_loop_vectorize"] ++ j = var_opt_char_j["flag_tree_loop_vectorize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 36) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_live_range_split" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_live_range_split"] ++ j = var_opt_char_j["flag_tree_live_range_split"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 37) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_partial_pre" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_partial_pre"] ++ j = var_opt_char_j["flag_tree_partial_pre"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 38) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_phiprop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_phiprop"] ++ j = var_opt_char_j["flag_tree_phiprop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 39) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_pre" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_pre"] ++ j = var_opt_char_j["flag_tree_pre"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 40) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_pta" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_pta"] ++ j = var_opt_char_j["flag_tree_pta"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 41) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_reassoc" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_reassoc"] ++ j = var_opt_char_j["flag_tree_reassoc"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 42) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_scev_cprop" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_scev_cprop"] ++ j = var_opt_char_j["flag_tree_scev_cprop"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 43) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_sink" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_sink"] ++ j = var_opt_char_j["flag_tree_sink"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 44) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_slp_transpose_vectorize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_slp_transpose_vectorize"] ++ j = var_opt_char_j["flag_tree_slp_transpose_vectorize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 45) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_slp_vectorize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_slp_vectorize"] ++ j = var_opt_char_j["flag_tree_slp_vectorize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 46) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_slsr" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_slsr"] ++ j = var_opt_char_j["flag_tree_slsr"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 47) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_sra" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_sra"] ++ j = var_opt_char_j["flag_tree_sra"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 48) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_switch_conversion" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_switch_conversion"] ++ j = var_opt_char_j["flag_tree_switch_conversion"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 49) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_tail_merge" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_tail_merge"] ++ j = var_opt_char_j["flag_tree_tail_merge"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 50) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_ter" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_ter"] ++ j = var_opt_char_j["flag_tree_ter"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 51) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_vectorize" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_vectorize"] ++ j = var_opt_char_j["flag_tree_vectorize"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 52) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_tree_vrp" in var_opt_char_k) { ++ k = var_opt_char_k["flag_tree_vrp"] ++ j = var_opt_char_j["flag_tree_vrp"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 53) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unconstrained_commons" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unconstrained_commons"] ++ j = var_opt_char_j["flag_unconstrained_commons"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 54) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unroll_all_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unroll_all_loops"] ++ j = var_opt_char_j["flag_unroll_all_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 55) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_cunroll_grow_size" in var_opt_char_k) { ++ k = var_opt_char_k["flag_cunroll_grow_size"] ++ j = var_opt_char_j["flag_cunroll_grow_size"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 56) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unroll_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unroll_loops"] ++ j = var_opt_char_j["flag_unroll_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 57) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unsafe_math_optimizations" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unsafe_math_optimizations"] ++ j = var_opt_char_j["flag_unsafe_math_optimizations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 58) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unswitch_loops" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unswitch_loops"] ++ j = var_opt_char_j["flag_unswitch_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 59) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_unwind_tables" in var_opt_char_k) { ++ k = var_opt_char_k["flag_unwind_tables"] ++ j = var_opt_char_j["flag_unwind_tables"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 60) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_var_tracking" in var_opt_char_k) { ++ k = var_opt_char_k["flag_var_tracking"] ++ j = var_opt_char_j["flag_var_tracking"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 61) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_var_tracking_assignments" in var_opt_char_k) { ++ k = var_opt_char_k["flag_var_tracking_assignments"] ++ j = var_opt_char_j["flag_var_tracking_assignments"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 62) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_var_tracking_assignments_toggle" in var_opt_char_k) { ++ k = var_opt_char_k["flag_var_tracking_assignments_toggle"] ++ j = var_opt_char_j["flag_var_tracking_assignments_toggle"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[7] >> 63) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_var_tracking_uninit" in var_opt_char_k) { ++ k = var_opt_char_k["flag_var_tracking_uninit"] ++ j = var_opt_char_j["flag_var_tracking_uninit"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 0) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_variable_expansion_in_unroller" in var_opt_char_k) { ++ k = var_opt_char_k["flag_variable_expansion_in_unroller"] ++ j = var_opt_char_j["flag_variable_expansion_in_unroller"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 1) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_version_loops_for_strides" in var_opt_char_k) { ++ k = var_opt_char_k["flag_version_loops_for_strides"] ++ j = var_opt_char_j["flag_version_loops_for_strides"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 2) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_value_profile_transformations" in var_opt_char_k) { ++ k = var_opt_char_k["flag_value_profile_transformations"] ++ j = var_opt_char_j["flag_value_profile_transformations"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 3) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_web" in var_opt_char_k) { ++ k = var_opt_char_k["flag_web"] ++ j = var_opt_char_j["flag_web"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 4) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_wrapv" in var_opt_char_k) { ++ k = var_opt_char_k["flag_wrapv"] ++ j = var_opt_char_j["flag_wrapv"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 5) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_wrapv_pointer" in var_opt_char_k) { ++ k = var_opt_char_k["flag_wrapv_pointer"] ++ j = var_opt_char_j["flag_wrapv_pointer"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 6) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("debug_nonbind_markers_p" in var_opt_char_k) { ++ k = var_opt_char_k["debug_nonbind_markers_p"] ++ j = var_opt_char_j["debug_nonbind_markers_p"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 7) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_cmlt_arith" in var_opt_char_k) { ++ k = var_opt_char_k["flag_cmlt_arith"] ++ j = var_opt_char_j["flag_cmlt_arith"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 8) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_mlow_precision_div" in var_opt_char_k) { ++ k = var_opt_char_k["flag_mlow_precision_div"] ++ j = var_opt_char_j["flag_mlow_precision_div"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 9) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_mrecip_low_precision_sqrt" in var_opt_char_k) { ++ k = var_opt_char_k["flag_mrecip_low_precision_sqrt"] ++ j = var_opt_char_j["flag_mrecip_low_precision_sqrt"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 10) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_mlow_precision_sqrt" in var_opt_char_k) { ++ k = var_opt_char_k["flag_mlow_precision_sqrt"] ++ j = var_opt_char_j["flag_mlow_precision_sqrt"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 11) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_simdmath_64" in var_opt_char_k) { ++ k = var_opt_char_k["flag_simdmath_64"] ++ j = var_opt_char_j["flag_simdmath_64"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 12) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("str_align_functions" in var_opt_string_k) { ++ k = var_opt_string_k["str_align_functions"] ++ j = var_opt_string_j["str_align_functions"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 13) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("str_align_jumps" in var_opt_string_k) { ++ k = var_opt_string_k["str_align_jumps"] ++ j = var_opt_string_j["str_align_jumps"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 14) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("str_align_labels" in var_opt_string_k) { ++ k = var_opt_string_k["str_align_labels"] ++ j = var_opt_string_j["str_align_labels"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 15) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("str_align_loops" in var_opt_string_k) { ++ k = var_opt_string_k["str_align_loops"] ++ j = var_opt_string_j["str_align_loops"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 16) & HOST_WIDE_INT_1U) << "j";" ++} ++if ("flag_patchable_function_entry" in var_opt_string_k) { ++ k = var_opt_string_k["flag_patchable_function_entry"] ++ j = var_opt_string_j["flag_patchable_function_entry"] ++ print " ptr->explicit_mask[" k "] |= ((explicit_mask_prev[8] >> 17) & HOST_WIDE_INT_1U) << "j";" ++} ++print "}"; ++print ""; ++ + print "/* Free heap memory used by optimization options */"; + print "void"; + print "cl_optimization_option_free (struct cl_optimization *ptr ATTRIBUTE_UNUSED)"; +-- +2.25.1 + diff --git a/0304-Add-multi-version-lto-symbol-parse-cross-lto-units-i.patch b/0304-Add-multi-version-lto-symbol-parse-cross-lto-units-i.patch new file mode 100644 index 0000000000000000000000000000000000000000..cdd28b19d8973b19bc8d8c9fa88df194bd4ab729 --- /dev/null +++ b/0304-Add-multi-version-lto-symbol-parse-cross-lto-units-i.patch @@ -0,0 +1,963 @@ +From f81a5b294711e3a420fe66702f0d9221332271c4 Mon Sep 17 00:00:00 2001 +From: h00564365 +Date: Wed, 13 Nov 2024 17:18:01 +0800 +Subject: [PATCH 2/2] Add multi-version lto symbol parse, cross lto units + ipa-inline extension, and lto compression algorithm specified. + +--- + gcc/common.opt | 20 +++ + gcc/config/aarch64/aarch64.cc | 41 ++++++ + gcc/doc/tm.texi | 6 + + gcc/doc/tm.texi.in | 2 + + gcc/ipa-inline.cc | 141 ++++++++++++++++++- + gcc/lto-compress.cc | 6 +- + gcc/lto-section-in.cc | 5 + + gcc/lto-streamer-out.cc | 7 +- + gcc/lto-wrapper.cc | 4 + + gcc/optc-save-gen.awk | 57 ++++++++ + gcc/opth-gen.awk | 3 + + gcc/opts.cc | 46 ++++++ + gcc/target.def | 10 ++ + gcc/testsuite/gcc.dg/lto/binary-inline-1_0.c | 15 ++ + gcc/testsuite/gcc.dg/lto/binary-inline-1_1.c | 6 + + gcc/testsuite/gcc.dg/lto/binary-inline-2_0.c | 15 ++ + gcc/testsuite/gcc.dg/lto/binary-inline-2_1.c | 5 + + gcc/testsuite/gcc.dg/lto/binary-inline-3_0.c | 15 ++ + gcc/testsuite/gcc.dg/lto/binary-inline-3_1.c | 10 ++ + gcc/tree-streamer-in.cc | 58 +++++++- + lto-plugin/lto-plugin.c | 83 +++++++++++ + 21 files changed, 547 insertions(+), 8 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/lto/binary-inline-1_0.c + create mode 100644 gcc/testsuite/gcc.dg/lto/binary-inline-1_1.c + create mode 100644 gcc/testsuite/gcc.dg/lto/binary-inline-2_0.c + create mode 100644 gcc/testsuite/gcc.dg/lto/binary-inline-2_1.c + create mode 100644 gcc/testsuite/gcc.dg/lto/binary-inline-3_0.c + create mode 100644 gcc/testsuite/gcc.dg/lto/binary-inline-3_1.c + +diff --git a/gcc/common.opt b/gcc/common.opt +index be5fcc681..78cfc333a 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1928,6 +1928,21 @@ finline-atomics + Common Var(flag_inline_atomics) Init(1) Optimization + Inline __atomic operations when a lock free instruction sequence is available. + ++fmulti-version-lib= ++Common Joined Var(multi_version_lib_string) ++Use specify LTO stream in mode for specified target (object or lib). If there ++are multiple target files, use commas (,) to separate them and without spaces. ++ ++finline-force ++Common Var(flag_inline_force) Init(0) Optimization ++Force perform ipa inline when march options are incompatible between functions. ++ ++finline-force= ++Common Joined Var(force_inline_targets_string) ++Force perform ipa inline specified target(object or lib) when march options are ++incompatible between functions. If there are multiple target files, use commas ++(,) to separate them and without spaces. ++ + fcf-protection + Common RejectNegative Alias(fcf-protection=,full) + +@@ -2168,6 +2183,11 @@ flto-partition= + Common Joined RejectNegative Enum(lto_partition_model) Var(flag_lto_partition) Init(LTO_PARTITION_BALANCED) + Specify the algorithm to partition symbols and vars at linktime. + ++flto-compression-algorithm= ++Common Joined Var(lto_compression_algorithm) ++-flto-compression-algorithm= Generate lto compression in zlib/zstd ++format . ++ + ; The initial value of -1 comes from Z_DEFAULT_COMPRESSION in zlib.h. + flto-compression-level= + Common Joined RejectNegative UInteger Var(flag_lto_compression_level) Init(-1) IntegerRange(0, 19) +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 025a3c478..f095f17aa 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -20829,6 +20829,44 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr) + arch->name, extension.c_str ()); + } + ++/* Implement TARGET_OPTION_PRINT_DIFF. */ ++ ++static void ++aarch64_option_print_diff (FILE *file, int indent, ++ struct cl_target_option *ptr1, ++ struct cl_target_option *ptr2) ++{ ++ const char *const cpu1 ++ = aarch64_get_tune_cpu (ptr1->x_selected_tune)->name; ++ const struct processor *arch1 = aarch64_get_arch (ptr1->x_selected_arch); ++ std::string extension1 ++ = aarch64_get_extension_string_for_isa_flags (ptr1->x_aarch64_isa_flags, ++ arch1->flags); ++ ++ const char *const cpu2 ++ = aarch64_get_tune_cpu (ptr2->x_selected_tune)->name; ++ const struct processor *arch2 = aarch64_get_arch (ptr2->x_selected_arch); ++ std::string extension2 ++ = aarch64_get_extension_string_for_isa_flags (ptr2->x_aarch64_isa_flags, ++ arch2->flags); ++ ++ if (cpu1 != cpu2 && (!cpu1 || !cpu2 || strcmp (cpu1, cpu2))) ++ fprintf (file, "%*s%s (%s/%s)\n", indent, "", ++ "cpu", cpu1 ? cpu1 : "(null)", cpu2 ? cpu2 : "(null)"); ++ ++ if (arch1->name != arch2->name ++ && (!arch1->name || !arch2->name || strcmp (arch1->name, arch2->name))) ++ fprintf (file, "%*s%s (%s/%s)\n", indent, "", ++ "arch", arch1->name ? arch1->name : "(null)", ++ arch2->name ? arch2->name : "(null)"); ++ ++ if (extension1 != extension2) ++ fprintf (file, "%*s%s (%s/%s)\n", indent, "", ++ "extension", ++ extension1.empty () ? "(null)" : extension1.c_str (), ++ extension2.empty () ? "(null)" : extension2.c_str ()); ++} ++ + static GTY(()) tree aarch64_previous_fndecl; + + void +@@ -31161,6 +31199,9 @@ aarch64_libgcc_floating_mode_supported_p + #undef TARGET_OPTION_PRINT + #define TARGET_OPTION_PRINT aarch64_option_print + ++#undef TARGET_OPTION_PRINT_DIFF ++#define TARGET_OPTION_PRINT_DIFF aarch64_option_print_diff ++ + #undef TARGET_OPTION_VALID_ATTRIBUTE_P + #define TARGET_OPTION_VALID_ATTRIBUTE_P aarch64_option_valid_attribute_p + +diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi +index 1e96521e6..50bbbbc42 100644 +--- a/gcc/doc/tm.texi ++++ b/gcc/doc/tm.texi +@@ -10589,6 +10589,12 @@ information in the @code{struct cl_target_option} structure for + function-specific options. + @end deftypefn + ++@deftypefn {Target Hook} void TARGET_OPTION_PRINT_DIFF (FILE *@var{file}, int @var{indent}, struct cl_target_option *@var{ptr1}, struct cl_target_option *@var{ptr2}) ++This hook is called to print diff additional target-specific ++information in the ptr1 and ptr2 @code{struct cl_target_option} structure for ++function-specific options. ++@end deftypefn ++ + @deftypefn {Target Hook} bool TARGET_OPTION_PRAGMA_PARSE (tree @var{args}, tree @var{pop_target}) + This target hook parses the options for @code{#pragma GCC target}, which + sets the target-specific options for functions that occur later in the +diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in +index 2dd515659..cfda60304 100644 +--- a/gcc/doc/tm.texi.in ++++ b/gcc/doc/tm.texi.in +@@ -6985,6 +6985,8 @@ on this implementation detail. + + @hook TARGET_OPTION_PRINT + ++@hook TARGET_OPTION_PRINT_DIFF ++ + @hook TARGET_OPTION_PRAGMA_PARSE + + @hook TARGET_OPTION_OVERRIDE +diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc +index f8bb072c4..8d5cc9a84 100644 +--- a/gcc/ipa-inline.cc ++++ b/gcc/ipa-inline.cc +@@ -90,6 +90,8 @@ along with GCC; see the file COPYING3. If not see + the need for offline copy of the function. */ + + #include "config.h" ++#define INCLUDE_SET ++#define INCLUDE_STRING + #include "system.h" + #include "coretypes.h" + #include "backend.h" +@@ -127,6 +129,7 @@ typedef fibonacci_node edge_heap_node_t; + static int overall_size; + static profile_count max_count; + static profile_count spec_rem; ++static std::set force_inline_targets; + + /* Return false when inlining edge E would lead to violating + limits on function unit growth or stack usage growth. +@@ -222,6 +225,38 @@ caller_growth_limits (struct cgraph_edge *e) + return true; + } + ++/* Warn and prompt the user, and output only once for the file pair where ++ the function is located. */ ++ ++static void ++prompt_inline_failed_target_option_reason (struct cgraph_edge *e) ++{ ++ static std::set> address_pair_set; ++ if (e->inline_failed == CIF_TARGET_OPTION_MISMATCH ++ && !cl_target_option_eq_major (target_opts_for_fn (e->caller->decl), ++ target_opts_for_fn (e->callee->ultimate_alias_target ()->decl)) ++ && e->caller->lto_file_data ++ && e->callee->ultimate_alias_target ()->lto_file_data) ++ { ++ std::pair addr_pair ++ = std::make_pair (&e->caller->lto_file_data, ++ &e->callee->ultimate_alias_target ()->lto_file_data); ++ if (address_pair_set.find (addr_pair) != address_pair_set.end ()) ++ return; ++ ++ address_pair_set.insert (addr_pair); ++ warning (0, "LTO objects caller in: %s, callee in: %s, not inlinable: %s." ++ " Try to use -finline-force=callee_object_or_lib_name to force " ++ "inline", e->caller->lto_file_data->file_name, ++ e->callee->ultimate_alias_target ()->lto_file_data->file_name, ++ cgraph_inline_failed_string (CIF_TARGET_OPTION_MISMATCH)); ++ ++ cl_target_option_print_diff ++ (stderr, 2, target_opts_for_fn (e->caller->decl), ++ target_opts_for_fn (e->callee->ultimate_alias_target ()->decl)); ++ } ++} ++ + /* Dump info about why inlining has failed. */ + + static void +@@ -254,6 +289,8 @@ report_inline_failed_reason (struct cgraph_edge *e) + (dump_file, 2, opts_for_fn (e->caller->decl), + opts_for_fn (e->callee->ultimate_alias_target ()->decl)); + } ++ ++ prompt_inline_failed_target_option_reason (e); + } + + /* Decide whether sanitizer-related attributes allow inlining. */ +@@ -310,6 +347,77 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee) + (opts_for_fn (caller->decl)->x_##flag \ + != opts_for_fn (callee->decl)->x_##flag) + ++/* find related node that has lto_file_data. */ ++ ++static cgraph_node * ++find_related_node_lto_file_data (cgraph_node *node) ++{ ++ cgraph_node *cur = node; ++ ++ while (cur->clone_of) ++ { ++ /* Switch to original node, for example xxx.constprop.x function. */ ++ cur = cur->clone_of; ++ if (cur->lto_file_data) ++ return cur; ++ ++ /* Find the lto_file_data information of referring. */ ++ struct ipa_ref *ref = NULL; ++ for (int i = 0; cur->iterate_referring (i, ref); i++) ++ { ++ struct cgraph_node *cnode = dyn_cast (ref->referring); ++ if (cnode && cnode->lto_file_data) ++ return cnode; ++ } ++ } ++ ++ return NULL; ++} ++ ++/* Determines whether to force inline or force inline only the specified ++ object. Use for 3 inline extensions: ++ 1) CIF_TARGET_OPTION_MISMATCH: cancel the restriction that the target options ++ of different compilation units are different. ++ 2) CIF_OVERWRITABLE: indicates that the function is available, which is ++ similar to the "inline" keyword indication. ++ 3) CIF_OPTIMIZATION_MISMATCH: cancel the check in the case of fp_expressions, ++ which is similar to the "always_inline" attribute. ++ */ ++ ++static bool ++can_force_inline_p (cgraph_node *callee) ++{ ++ if (!in_lto_p) ++ return false; ++ if (flag_inline_force) ++ return true; ++ if (force_inline_targets_string) ++ { ++ cgraph_node * node = callee; ++ std::string name = ""; ++ if (callee->ultimate_alias_target () == NULL ++ || callee->ultimate_alias_target ()->lto_file_data == NULL) ++ { ++ node = find_related_node_lto_file_data (callee); ++ if (node && node->lto_file_data) ++ name = node->lto_file_data->file_name; ++ } ++ else ++ name = node->ultimate_alias_target ()->lto_file_data->file_name; ++ while (!name.empty () && name.back () == '/') ++ name.erase (name.length () - 1); ++ if (name.empty ()) ++ return false; ++ size_t last_slash_pos = name.find_last_of ('/'); ++ if (last_slash_pos != std::string::npos ++ && last_slash_pos != name.length () - 1) ++ name = name.substr (last_slash_pos + 1); ++ if (force_inline_targets.find (name) != force_inline_targets.end ()) ++ return true; ++ } ++ return false; ++} ++ + /* Decide if we can inline the edge and possibly update + inline_failed reason. + We check whether inlining is possible at all and whether +@@ -352,7 +460,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, + e->inline_failed = CIF_USES_COMDAT_LOCAL; + inlinable = false; + } +- else if (avail <= AVAIL_INTERPOSABLE) ++ else if (avail <= AVAIL_INTERPOSABLE && !can_force_inline_p (callee)) + { + e->inline_failed = CIF_OVERWRITABLE; + inlinable = false; +@@ -378,8 +486,8 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, + inlinable = false; + } + /* Check compatibility of target optimization options. */ +- else if (!targetm.target_option.can_inline_p (caller->decl, +- callee->decl)) ++ else if (!can_force_inline_p (callee) ++ && !targetm.target_option.can_inline_p (caller->decl, callee->decl)) + { + e->inline_failed = CIF_TARGET_OPTION_MISMATCH; + inlinable = false; +@@ -495,7 +603,8 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report, + bool always_inline = + (DECL_DISREGARD_INLINE_LIMITS (callee->decl) + && lookup_attribute ("always_inline", +- DECL_ATTRIBUTES (callee->decl))); ++ DECL_ATTRIBUTES (callee->decl))) ++ || can_force_inline_p (callee); + ipa_fn_summary *caller_info = ipa_fn_summaries->get (caller); + ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee); + +@@ -2652,6 +2761,27 @@ flatten_remove_node_hook (struct cgraph_node *node, void *data) + removed->add (node); + } + ++/* Parse string that specify forced inlining, separated by commas. */ ++ ++static void ++parse_force_inline_targets_string (const char* s) ++{ ++ std::string target_string (s); ++ std::string delim = ","; ++ size_t start = 0; ++ size_t end = target_string.find (delim); ++ if (target_string.substr (start, end - start) == "") ++ return; ++ ++ while (end != std::string::npos) ++ { ++ force_inline_targets.insert (target_string.substr (start, end - start)); ++ start = end + delim.size (); ++ end = target_string.find (delim, start); ++ } ++ force_inline_targets.insert (target_string.substr (start, end - start)); ++} ++ + /* Decide on the inlining. We do so in the topological order to avoid + expenses on updating data structures. */ + +@@ -2665,6 +2795,9 @@ ipa_inline (void) + int cold; + bool remove_functions = false; + ++ if (force_inline_targets_string) ++ parse_force_inline_targets_string (force_inline_targets_string); ++ + order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); + + if (dump_file) +diff --git a/gcc/lto-compress.cc b/gcc/lto-compress.cc +index 27f0992a8..f9d0722a9 100644 +--- a/gcc/lto-compress.cc ++++ b/gcc/lto-compress.cc +@@ -305,7 +305,11 @@ void + lto_end_compression (struct lto_compression_stream *stream) + { + #ifdef HAVE_ZSTD_H +- lto_compression_zstd (stream); ++ if (lto_compression_algorithm ++ && strcmp (lto_compression_algorithm, "zstd") == 0) ++ lto_compression_zstd (stream); ++ else ++ lto_compression_zlib (stream); + #else + lto_compression_zlib (stream); + #endif +diff --git a/gcc/lto-section-in.cc b/gcc/lto-section-in.cc +index ba87c7276..947f8eb15 100644 +--- a/gcc/lto-section-in.cc ++++ b/gcc/lto-section-in.cc +@@ -448,6 +448,11 @@ lto_free_function_in_decl_state_for_node (symtab_node *node) + lto_free_function_in_decl_state (*slot); + node->lto_file_data->function_decl_states->clear_slot (slot); + } ++ ++ /* In force inline case, keep lto file path information. */ ++ if (in_lto_p && (flag_inline_force || force_inline_targets_string)) ++ return; ++ + node->lto_file_data = NULL; + } + +diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc +index 471f35c31..a574f0f1e 100644 +--- a/gcc/lto-streamer-out.cc ++++ b/gcc/lto-streamer-out.cc +@@ -2666,7 +2666,12 @@ produce_lto_section () + free (section_name); + + #ifdef HAVE_ZSTD_H +- lto_compression compression = ZSTD; ++ lto_compression compression = ZLIB; ++ if (lto_compression_algorithm ++ && strcmp (lto_compression_algorithm, "zstd") == 0) ++ compression = ZSTD; ++ else ++ compression = ZLIB; + #else + lto_compression compression = ZLIB; + #endif +diff --git a/gcc/lto-wrapper.cc b/gcc/lto-wrapper.cc +index 155ccce57..2b1994652 100644 +--- a/gcc/lto-wrapper.cc ++++ b/gcc/lto-wrapper.cc +@@ -491,6 +491,8 @@ merge_and_complain (vec &decoded_options, + || decoded_options[j].opt_index == OPT_fpic) + { + /* -fno-pic in one unit implies -fno-pic everywhere. */ ++ /* The -fno-pic adjustment here should provide some information hints, ++ but may affect the use case test of deja. */ + if (decoded_options[j].value == 0) + j++; + /* If we have no pic option or merge in -fno-pic, we still may turn +@@ -534,6 +536,8 @@ merge_and_complain (vec &decoded_options, + || decoded_options[j].opt_index == OPT_fpie) + { + /* -fno-pie in one unit implies -fno-pie everywhere. */ ++ /* The -fno-pie adjustment here should provide some information hints, ++ but may affect the use case test of deja. */ + if (decoded_options[j].value == 0) + j++; + /* If we have no pie option or merge in -fno-pie, we still preserve +diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk +index 7c012dd4e..94b85b331 100644 +--- a/gcc/optc-save-gen.awk ++++ b/gcc/optc-save-gen.awk +@@ -1043,6 +1043,10 @@ for (i = 0; i < n_target_string; i++) { + print ""; + } + ++print ""; ++print " if (targetm.target_option.print_diff)"; ++print " targetm.target_option.print_diff (file, indent, ptr1, ptr2);"; ++ + print "}"; + + print ""; +@@ -1160,6 +1164,59 @@ print " return true;"; + + print "}"; + ++print ""; ++print "/* Compare two target major options. */"; ++print "bool"; ++print "cl_target_option_eq_major (struct cl_target_option const *ptr1 ATTRIBUTE_UNUSED,"; ++print " struct cl_target_option const *ptr2 ATTRIBUTE_UNUSED)"; ++print "{"; ++n_target_val_major = 0; ++ ++for (i = 0; i < n_target_save; i++) { ++ var = target_save_decl[i]; ++ sub (" *=.*", "", var); ++ name = var; ++ type = var; ++ sub("^.*[ *]", "", name) ++ sub(" *" name "$", "", type) ++ if (target_save_decl[i] ~ "^const char \\*+[_" alnum "]+$") ++ continue; ++ if (target_save_decl[i] ~ " .*\\[.+\\]+$") ++ continue; ++ ++ var_target_val_major[n_target_val_major++] = name; ++} ++if (have_save) { ++ for (i = 0; i < n_opts; i++) { ++ if (flag_set_p("Save", flags[i])) { ++ name = var_name(flags[i]) ++ if(name == "") ++ name = "target_flags"; ++ ++ if(name in var_list_seen) ++ continue; ++ ++ var_list_seen[name]++; ++ otype = var_type_struct(flags[i]) ++ if (otype ~ "^const char \\**$") ++ continue; ++ var_target_val_major[n_target_val_major++] = "x_" name; ++ } ++ } ++} else { ++ var_target_val_major[n_target_val_major++] = "x_target_flags"; ++} ++ ++for (i = 0; i < n_target_val_major; i++) { ++ name = var_target_val_major[i] ++ print " if (ptr1->" name" != ptr2->" name ")"; ++ print " return false;"; ++} ++ ++print " return true;"; ++ ++print "}"; ++ + print ""; + print "/* Hash target options */"; + print "hashval_t"; +diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk +index 8bba8ec45..cb016e85d 100644 +--- a/gcc/opth-gen.awk ++++ b/gcc/opth-gen.awk +@@ -330,6 +330,9 @@ print ""; + print "/* Compare two target option variables from a structure. */"; + print "extern bool cl_target_option_eq (const struct cl_target_option *, const struct cl_target_option *);"; + print ""; ++print "/* Compare two target major option variables from a structure. */"; ++print "extern bool cl_target_option_eq_major (const struct cl_target_option *, const struct cl_target_option *);"; ++print ""; + print "/* Free heap memory used by target option variables. */"; + print "extern void cl_target_option_free (struct cl_target_option *);"; + print ""; +diff --git a/gcc/opts.cc b/gcc/opts.cc +index d97f6079f..d9de8747c 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -2611,6 +2611,32 @@ print_help (struct gcc_options *opts, unsigned int lang_mask, + lang_mask); + } + ++/* Checks whether the input forced inline string complies with the ++ restriction. */ ++ ++void ++check_force_inline_targets_string (const char *arg, location_t loc) ++{ ++ const int MAX_FORCE_INLINE_TARGET_LEN = 10000; ++ const int MAX_NUM_TARGET = 100; ++ __SIZE_TYPE__ length = strlen (arg); ++ int target_num = 1; ++ if (length > MAX_FORCE_INLINE_TARGET_LEN) ++ error_at (loc, ++ "input string exceeds %d characters to %<-finline_force=%> " ++ "option: %qs", MAX_FORCE_INLINE_TARGET_LEN, arg); ++ for (__SIZE_TYPE__ i = 0; i < length; i++) ++ { ++ if (arg[i] == ',') ++ { ++ target_num++; ++ if (target_num > MAX_NUM_TARGET) ++ error_at (loc, "input target exceeds %d to %<-finline_force=%> " ++ "option: %qs", MAX_NUM_TARGET, arg); ++ } ++ } ++} ++ + /* Handle target- and language-independent options. Return zero to + generate an "unknown option" message. Only options that need + extra handling need to be listed here; if you simply want +@@ -2952,6 +2978,14 @@ common_handle_option (struct gcc_options *opts, + value / 2); + break; + ++ case OPT_finline_force: ++ opts->x_force_inline_targets_string = value ? "" : NULL; ++ break; ++ ++ case OPT_finline_force_: ++ check_force_inline_targets_string (arg, loc); ++ break; ++ + case OPT_finstrument_functions_exclude_function_list_: + add_comma_separated_to_vector + (&opts->x_flag_instrument_functions_exclude_functions, arg); +@@ -3226,6 +3260,18 @@ common_handle_option (struct gcc_options *opts, + "unrecognized argument to %<-flto=%> option: %qs", arg); + break; + ++ case OPT_flto_compression_algorithm_: ++ if (atoi (arg) == 0 ++ && strcmp (arg, "zlib") != 0 ++#ifdef HAVE_ZSTD_H ++ && strcmp (arg, "zstd") != 0 ++#endif ++ ) ++ error_at (loc, ++ "unrecognized argument to %<-flto-compression-algorithm=%> " ++ "option: %qs", arg); ++ break; ++ + case OPT_w: + dc->dc_inhibit_warnings = true; + break; +diff --git a/gcc/target.def b/gcc/target.def +index 7183f363d..142858fa3 100644 +--- a/gcc/target.def ++++ b/gcc/target.def +@@ -6644,6 +6644,16 @@ information in the @code{struct cl_target_option} structure for\n\ + function-specific options.", + void, (FILE *file, int indent, struct cl_target_option *ptr), NULL) + ++/* Function to print any extra target state from the target options ++ structure. */ ++DEFHOOK ++(print_diff, ++ "This hook is called to print diff additional target-specific\n\ ++information in the ptr1 and ptr2 @code{struct cl_target_option} structure for\n\ ++function-specific options.", ++ void, (FILE *file, int indent, struct cl_target_option *ptr1, ++ struct cl_target_option *ptr2), NULL) ++ + /* Function to parse arguments to be validated for #pragma target, and to + change the state if the options are valid. If the first argument is + NULL, the second argument specifies the default options to use. Return +diff --git a/gcc/testsuite/gcc.dg/lto/binary-inline-1_0.c b/gcc/testsuite/gcc.dg/lto/binary-inline-1_0.c +new file mode 100644 +index 000000000..0b5cd5953 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/lto/binary-inline-1_0.c +@@ -0,0 +1,15 @@ ++/* { dg-lto-do link } */ ++/* { dg-require-effective-target shared } */ ++/* { dg-extra-ld-options {-shared -finline-force=c_lto_binary-inline-1_1.o} } */ ++/* { dg-lto-options {{-O3 -flto -march=armv8.2-a -fdump-ipa-inline-details}} } */ ++ ++extern double multi_op(float x); ++ ++double func_a (float x) ++{ ++ double res = 0; ++ res = multi_op (x); ++ return res; ++} ++ ++/* { dg-final { scan-wpa-ipa-dump "Inlined 1 calls" "inline" } } */ +diff --git a/gcc/testsuite/gcc.dg/lto/binary-inline-1_1.c b/gcc/testsuite/gcc.dg/lto/binary-inline-1_1.c +new file mode 100644 +index 000000000..8181384b7 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/lto/binary-inline-1_1.c +@@ -0,0 +1,6 @@ ++/* { dg-options "-march=armv8.3-a+sve+f64mm+crc+crypto+fp16+i8mm+simd" } */ ++ ++double multi_op (float x) ++{ ++ return x * 2 + 10; ++} +diff --git a/gcc/testsuite/gcc.dg/lto/binary-inline-2_0.c b/gcc/testsuite/gcc.dg/lto/binary-inline-2_0.c +new file mode 100644 +index 000000000..e873937d3 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/lto/binary-inline-2_0.c +@@ -0,0 +1,15 @@ ++/* { dg-lto-do link } */ ++/* { dg-require-effective-target shared } */ ++/* { dg-extra-ld-options {-shared -finline-force=c_lto_binary-inline-2_1.o} } */ ++/* { dg-lto-options {{-O3 -flto -fPIC -fdump-ipa-inline-details}} } */ ++ ++extern double multi_op(float x); ++ ++double func_a (float x) ++{ ++ double res = 0; ++ res = multi_op (x); ++ return res; ++} ++ ++/* { dg-final { scan-wpa-ipa-dump "Inlined 1 calls" "inline" } } */ +diff --git a/gcc/testsuite/gcc.dg/lto/binary-inline-2_1.c b/gcc/testsuite/gcc.dg/lto/binary-inline-2_1.c +new file mode 100644 +index 000000000..dc7c4fd9f +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/lto/binary-inline-2_1.c +@@ -0,0 +1,5 @@ ++ ++double multi_op (float x) ++{ ++ return x * 2 + 10; ++} +diff --git a/gcc/testsuite/gcc.dg/lto/binary-inline-3_0.c b/gcc/testsuite/gcc.dg/lto/binary-inline-3_0.c +new file mode 100644 +index 000000000..c78ba066d +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/lto/binary-inline-3_0.c +@@ -0,0 +1,15 @@ ++/* { dg-lto-do link } */ ++/* { dg-require-effective-target shared } */ ++/* { dg-extra-ld-options {-shared -finline-force=c_lto_binary-inline-3_1.o} } */ ++/* { dg-lto-options {{-O3 -flto -fdump-ipa-inline-details}} } */ ++ ++extern double multi_op(double x); ++ ++double func_a (double x) ++{ ++ double res = 0; ++ res = multi_op (x); ++ return res; ++} ++ ++/* { dg-final { scan-wpa-ipa-dump "Inlined 1 calls" "inline" } } */ +diff --git a/gcc/testsuite/gcc.dg/lto/binary-inline-3_1.c b/gcc/testsuite/gcc.dg/lto/binary-inline-3_1.c +new file mode 100644 +index 000000000..8b505fa0c +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/lto/binary-inline-3_1.c +@@ -0,0 +1,10 @@ ++/* { dg-options "-O2 -fno-math-errno" } */ ++ ++#include ++ ++double multi_op (double x) ++{ ++ double a = 0; ++ a = sqrt (x); ++ return a * 2 + 10; ++} +diff --git a/gcc/tree-streamer-in.cc b/gcc/tree-streamer-in.cc +index a35a810f4..79f819ad8 100644 +--- a/gcc/tree-streamer-in.cc ++++ b/gcc/tree-streamer-in.cc +@@ -20,6 +20,9 @@ along with GCC; see the file COPYING3. If not see + . */ + + #include "config.h" ++#include ++#define INCLUDE_SET ++#define INCLUDE_STRING + #include "system.h" + #include "coretypes.h" + #include "backend.h" +@@ -36,6 +39,47 @@ along with GCC; see the file COPYING3. If not see + #include "asan.h" + #include "opts.h" + ++/* Parse string that specify forced inlining, separated by commas. */ ++static std::set multi_version_libs; ++static void ++parse_multi_version_lib_string (const char* s) ++{ ++ std::string target_string (s); ++ std::string delim = ","; ++ size_t start = 0; ++ size_t end = target_string.find (delim); ++ if (target_string.substr (start, end - start) == "") ++ return; ++ ++ while (end != std::string::npos) ++ { ++ multi_version_libs.insert (target_string.substr (start, end - start)); ++ start = end + delim.size (); ++ end = target_string.find (delim, start); ++ } ++ multi_version_libs.insert (target_string.substr (start, end - start)); ++} ++ ++static bool ++target_lib_p (std::string name) ++{ ++ if (multi_version_libs.empty () && multi_version_lib_string) ++ parse_multi_version_lib_string (multi_version_lib_string); ++ if (multi_version_lib_string) ++ { ++ while (!name.empty () && name.back () == '/') ++ name.erase (name.length () - 1); ++ if (name.empty ()) ++ return false; ++ size_t last_slash_pos = name.find_last_of ('/'); ++ if (last_slash_pos != std::string::npos ++ && last_slash_pos != name.length () - 1) ++ name = name.substr (last_slash_pos + 1); ++ if (multi_version_libs.find (name) != multi_version_libs.end ()) ++ return true; ++ } ++ return false; ++} + + /* Read a STRING_CST from the string table in DATA_IN using input + block IB. */ +@@ -555,7 +599,12 @@ streamer_read_tree_bitfields (class lto_input_block *ib, + unpack_ts_translation_unit_decl_value_fields (data_in, &bp, expr); + + if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) +- cl_optimization_stream_in (data_in, &bp, TREE_OPTIMIZATION (expr)); ++ { ++ if (target_lib_p (data_in->file_data->file_name)) ++ cl_optimization_stream_in_prev (data_in, &bp, TREE_OPTIMIZATION (expr)); ++ else ++ cl_optimization_stream_in (data_in, &bp, TREE_OPTIMIZATION (expr)); ++ } + + if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) + { +@@ -569,7 +618,12 @@ streamer_read_tree_bitfields (class lto_input_block *ib, + #ifndef ACCEL_COMPILER + if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)) + { +- cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr)); ++ if (target_lib_p (data_in->file_data->file_name)) ++ cl_target_option_stream_in_prev ( ++ data_in, &bp, TREE_TARGET_OPTION (expr)); ++ else ++ cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr)); ++ + if (targetm.target_option.post_stream_in) + targetm.target_option.post_stream_in (TREE_TARGET_OPTION (expr)); + } +diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c +index 33d49571d..b3301a8a4 100644 +--- a/lto-plugin/lto-plugin.c ++++ b/lto-plugin/lto-plugin.c +@@ -89,6 +89,10 @@ along with this program; see the file COPYING3. If not see + + #define LTO_SEGMENT_NAME "__GNU_LTO" + ++#define GCC_major_version 12 ++#define LTO_major_version GCC_major_version ++#define LTO_minor_version 0 ++ + /* Return true if STR string starts with PREFIX. */ + + static inline bool +@@ -118,6 +122,18 @@ struct plugin_symtab + unsigned long long id; + }; + ++/* Structure that represents LTO ELF section with information ++ about the format. */ ++ ++struct lto_section ++{ ++ int16_t major_version; ++ int16_t minor_version; ++ unsigned char slim_object; ++ unsigned char _padding; ++ uint16_t flags; ++}; ++ + /* Encapsulates object file data during symbol scan. */ + struct plugin_objfile + { +@@ -126,6 +142,7 @@ struct plugin_objfile + simple_object_read *objfile; + struct plugin_symtab *out; + const struct ld_plugin_input_file *file; ++ struct lto_section version; + }; + + /* All that we have to remember about a file. */ +@@ -216,6 +233,8 @@ static int gold_version = -1; + (in fact, only first letter of style arg is checked.) */ + static enum symbol_style sym_style = ss_none; + ++static bool multi_version_lto_parse = false; ++ + static void + check_1 (int gate, enum ld_plugin_level level, const char *text) + { +@@ -1078,6 +1097,59 @@ err: + return 0; + } + ++/* Process version section of an object file. */ ++ ++static int ++process_lto_version (void *data, const char *name, off_t offset, off_t length) ++{ ++ struct plugin_objfile *obj = (struct plugin_objfile *)data; ++ char *s; ++ char *secdatastart, *secdata; ++ ++ if (!startswith (name, ".gnu.lto_.lto")) ++ return 1; ++ ++ s = strrchr (name, '.'); ++ if (s) ++ sscanf (s, ".%" PRI_LL "x", &obj->out->id); ++ secdata = secdatastart = xmalloc (length); ++ offset += obj->file->offset; ++ if (offset != lseek (obj->file->fd, offset, SEEK_SET)) ++ goto err; ++ ++ do ++ { ++ ssize_t got = read (obj->file->fd, secdata, length); ++ if (got == 0) ++ break; ++ else if (got > 0) ++ { ++ secdata += got; ++ length -= got; ++ } ++ else if (errno != EINTR) ++ goto err; ++ } ++ while (length > 0); ++ if (length > 0) ++ goto err; ++ ++ struct lto_section *lto_info = (struct lto_section *)secdatastart; ++ obj->version = *lto_info; ++ ++ obj->found++; ++ free (secdatastart); ++ return 1; ++ ++err: ++ if (message) ++ message (LDPL_FATAL, "%s: corrupt object file", obj->file->name); ++ /* Force claim_file_handler to abandon this file. */ ++ obj->found = 0; ++ free (secdatastart); ++ return 0; ++} ++ + /* Process one section of an object file. */ + + static int +@@ -1223,6 +1295,15 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed) + if (obj.found == 0 && obj.offload == 0) + goto err; + ++ if (multi_version_lto_parse) ++ { ++ simple_object_find_sections (obj.objfile, process_lto_version, &obj, ++ &err); ++ if (obj.version.major_version != LTO_major_version ++ || obj.version.minor_version != LTO_minor_version) ++ goto err; ++ } ++ + if (obj.found > 1) + resolve_conflicts (<o_file.symtab, <o_file.conflicts); + +@@ -1366,6 +1447,8 @@ process_option (const char *option) + } + else if (startswith (option, "-ltrans-objects=")) + ltrans_objects = xstrdup (option + strlen ("-ltrans-objects=")); ++ else if (strcmp (option, "-multi-version-lto-parse") == 0) ++ multi_version_lto_parse = true; + else + { + int size; +-- +2.25.1 + diff --git a/0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch b/0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch new file mode 100644 index 0000000000000000000000000000000000000000..e3bf4dc1812b555e09f277ef91d8f5202ef00589 --- /dev/null +++ b/0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch @@ -0,0 +1,296 @@ +From bbb4954294d010977fcfb96931384101cf015a44 Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Mon, 26 Feb 2024 17:55:07 +0100 +Subject: [PATCH] [Backport]varasm: Handle private COMDAT function symbol + reference in readonly data section [PR113617] + +If default_elf_select_rtx_section is called to put a reference to some +local symbol defined in a comdat section into memory, which happens more often +since the r14-4944 RA change, linking might fail. +default_elf_select_rtx_section puts such constants into .data.rel.ro.local +etc. sections and if linker chooses comdat sections from some other TU +and discards the one to which a relocation in .data.rel.ro.local remains, +linker diagnoses error. References to private comdat symbols can only appear +from functions or data objects in the same comdat group, so the following +patch arranges using .data.rel.ro.local.pool. and similar sections. + +2024-02-26 Jakub Jelinek + H.J. Lu + + PR rtl-optimization/113617 + * varasm.cc (default_elf_select_rtx_section): For + references to private symbols in comdat sections + use .data.relro.local.pool., .data.relro.pool. + or .rodata. comdat sections. + + * g++.dg/other/pr113617.C: New test. + * g++.dg/other/pr113617.h: New test. + * g++.dg/other/pr113617-aux.cc: New test. +--- + gcc/testsuite/g++.dg/other/pr113617-aux.cc | 9 ++ + gcc/testsuite/g++.dg/other/pr113617.C | 27 +++++ + gcc/testsuite/g++.dg/other/pr113617.h | 132 +++++++++++++++++++++ + gcc/varasm.cc | 48 +++++++- + 4 files changed, 215 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/g++.dg/other/pr113617-aux.cc + create mode 100644 gcc/testsuite/g++.dg/other/pr113617.C + create mode 100644 gcc/testsuite/g++.dg/other/pr113617.h + +diff --git a/gcc/testsuite/g++.dg/other/pr113617-aux.cc b/gcc/testsuite/g++.dg/other/pr113617-aux.cc +new file mode 100644 +index 000000000..e6900e05a +--- /dev/null ++++ b/gcc/testsuite/g++.dg/other/pr113617-aux.cc +@@ -0,0 +1,9 @@ ++// PR rtl-optimization/113617 ++// { dg-do link { target { c++17 && c++14_down } } } ++ ++#include "pr113617.h" ++ ++void qux() { ++ A a; ++ a.foo(0, 0); ++} +diff --git a/gcc/testsuite/g++.dg/other/pr113617.C b/gcc/testsuite/g++.dg/other/pr113617.C +new file mode 100644 +index 000000000..a02dda142 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/other/pr113617.C +@@ -0,0 +1,27 @@ ++// PR rtl-optimization/113617 ++// { dg-do link { target c++11 } } ++// { dg-options "-O2" } ++// { dg-additional-options "-fPIC" { target fpic } } */ ++// { dg-additional-options "-shared" { target shared } } */ ++// { dg-additional-sources pr113617-aux.cc } ++ ++#include "pr113617.h" ++ ++int z; ++long xx1; ++void corge() { ++ A a; ++ a.foo(xx1, 0); ++} ++ ++typedef unsigned long int VV __attribute__((vector_size (2 * sizeof (long)))); ++VV vv; ++__attribute__((noipa)) static void fn1 (void) {} ++__attribute__((noipa)) static void fn2 (void) {} ++ ++void ++fn3 () ++{ ++ VV a = { (unsigned long) &fn1, (unsigned long) &fn2 }; ++ vv = a; ++} +diff --git a/gcc/testsuite/g++.dg/other/pr113617.h b/gcc/testsuite/g++.dg/other/pr113617.h +new file mode 100644 +index 000000000..4d30eddbc +--- /dev/null ++++ b/gcc/testsuite/g++.dg/other/pr113617.h +@@ -0,0 +1,132 @@ ++namespace { ++template struct J { static constexpr int value = V; }; ++template using K = J; ++using M = K; ++template struct L { template using type = _Tp; }; ++template using N = typename L<_Cond>::type<_If, _Else>; ++M k; ++template struct O { using type = _Tp; }; ++template ++struct P : N, _Up> {}; ++template struct Q { using type = typename P<_Tp>::type; }; ++} ++namespace R { ++struct H; ++enum G {}; ++template class S; ++struct T { using U = bool (*) (H &, const H &, G); U F; }; ++template class B; ++template ++struct B<_R(_A...), _F> { ++ static bool F(H &, const H &, G) { return false; } ++ __attribute__((noipa)) static _R bar(const H &) {} ++}; ++template ++struct S<_R(_A...)> : T { ++ template using AH = B<_R(), _F>; ++ template S(_F) { ++ using AG = AH<_F>; ++ barr = AG::bar; ++ F = AG::F; ++ } ++ using AF = _R (*)(const H &); ++ AF barr; ++}; ++template class I; ++template ++struct I<_F(_B...)> {}; ++template using W = decltype(k); ++template struct V { ++ typedef I::type(typename Q<_B>::type...)> type; ++}; ++template ++__attribute__((noipa)) typename V::value, _F, _B...>::type ++baz(_F, _B...) { return typename V::value, _F, _B...>::type (); } ++template struct AJ { ++ template struct _Ptr { using type = _Up *; }; ++ using AI = typename _Ptr<_Tp>::type; ++}; ++template struct Y { ++ using AI = typename AJ<_Tp>::AI; ++ AI operator->(); ++}; ++} ++extern int z; ++namespace N1 { ++namespace N2 { ++namespace N3 { ++enum Z { Z1, Z2 }; ++template struct X { ++ template ++ __attribute__((noipa)) void boo(long long, long long, long long, _F &) {} ++}; ++struct AC { ++ AC(int); ++ void m1(R::S); ++}; ++template ++__attribute__((noipa)) void garply(void *, long long, long long, long long) {} ++template <> ++template ++void X::boo(long long, long long x, long long y, _F &fi) { ++ AC pool(z); ++ for (;;) { ++ auto job = R::baz(garply<_F>, &fi, y, y, x); ++ pool.m1(job); ++ } ++} ++struct AB { ++ static AB &bleh(); ++ template ++ void boo(long first, long x, long y, _F fi) { ++ switch (ab1) { ++ case Z1: ++ ab2->boo(first, x, y, fi); ++ case Z2: ++ ab3->boo(first, x, y, fi); ++ } ++ } ++ Z ab1; ++ R::Y> ab2; ++ R::Y> ab3; ++}; ++template struct C; ++template struct C<_F, false> { ++ __attribute__((noipa)) C(_F) {} ++ void boo(long first, long x, long y) { ++ auto u = AB::bleh(); ++ u.boo(first, x, y, *this); ++ } ++}; ++template struct AA { typedef C<_F, 0> type; }; ++} ++} ++} ++struct AD { ++ template ++ static void boo(long first, long x, long y, _F f) { ++ typename N1::N2::N3::AA<_F>::type fi(f); ++ fi.boo(first, x, y); ++ } ++ template ++ static void boo(long first, long x, _F f) { ++ boo(first, x, 0, f); ++ } ++}; ++template struct A { ++ void foo(long long, long long); ++ int *c; ++}; ++namespace { ++template struct D { __attribute__((noipa)) D(int *) {} }; ++} ++template ++void A::foo(long long x, long long y) ++{ ++ int e; ++ D d(&e); ++ AD::boo(0, y, d); ++ long p; ++ for (p = 0; p < x; p++) ++ c[p] = c[p - 1]; ++} +diff --git a/gcc/varasm.cc b/gcc/varasm.cc +index bae935694..d122730b5 100644 +--- a/gcc/varasm.cc ++++ b/gcc/varasm.cc +@@ -7317,17 +7317,63 @@ default_elf_select_rtx_section (machine_mode mode, rtx x, + unsigned HOST_WIDE_INT align) + { + int reloc = compute_reloc_for_rtx (x); ++ tree decl = nullptr; ++ const char *prefix = nullptr; ++ int flags = 0; ++ ++ /* If it is a private COMDAT function symbol reference, call ++ function_rodata_section for the read-only or relocated read-only ++ data section associated with function DECL so that the COMDAT ++ section will be used for the private COMDAT function symbol. */ ++ if (HAVE_COMDAT_GROUP) ++ { ++ if (GET_CODE (x) == CONST ++ && GET_CODE (XEXP (x, 0)) == PLUS ++ && CONST_INT_P (XEXP (XEXP (x, 0), 1))) ++ x = XEXP (XEXP (x, 0), 0); ++ ++ if (GET_CODE (x) == SYMBOL_REF) ++ { ++ decl = SYMBOL_REF_DECL (x); ++ if (decl ++ && (TREE_CODE (decl) != FUNCTION_DECL ++ || !DECL_COMDAT_GROUP (decl) ++ || TREE_PUBLIC (decl))) ++ decl = nullptr; ++ } ++ } + + /* ??? Handle small data here somehow. */ + + if (reloc & targetm.asm_out.reloc_rw_mask ()) + { +- if (reloc == 1) ++ if (decl) ++ { ++ prefix = reloc == 1 ? ".data.rel.ro.local" : ".data.rel.ro"; ++ flags = SECTION_WRITE | SECTION_RELRO; ++ } ++ else if (reloc == 1) + return get_named_section (NULL, ".data.rel.ro.local", 1); + else + return get_named_section (NULL, ".data.rel.ro", 3); + } + ++ if (decl) ++ { ++ const char *comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl)); ++ if (!prefix) ++ prefix = ".rodata"; ++ size_t prefix_len = strlen (prefix); ++ size_t comdat_len = strlen (comdat); ++ size_t len = prefix_len + sizeof (".pool.") + comdat_len; ++ char *name = XALLOCAVEC (char, len); ++ memcpy (name, prefix, prefix_len); ++ memcpy (name + prefix_len, ".pool.", sizeof (".pool.") - 1); ++ memcpy (name + prefix_len + sizeof (".pool.") - 1, comdat, ++ comdat_len + 1); ++ return get_section (name, flags | SECTION_LINKONCE, decl); ++ } ++ + return mergeable_constant_section (mode, align, 0); + } + +-- +2.33.0 + diff --git a/0306-RISC-V-Install-libstdc-libcc1-etc-to-lib64-instead-o.patch b/0306-RISC-V-Install-libstdc-libcc1-etc-to-lib64-instead-o.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c0c15a56ecac0fe0b025befc8b539fbe3b49834 --- /dev/null +++ b/0306-RISC-V-Install-libstdc-libcc1-etc-to-lib64-instead-o.patch @@ -0,0 +1,65 @@ +From 84edbc6544ed872aedb3cb6f6d0feb8647ff1d8b Mon Sep 17 00:00:00 2001 +From: YunQiang Su +Date: Mon, 14 Oct 2024 10:09:46 +0800 +Subject: [PATCH] RISC-V: Install libstdc++/libcc1 etc to /lib64 instead of lib + +The problem is that if we are configured with `--disable-multilib`, + gcc -print-multi-os-directory +outputs + . +Thus the dest to install libraries is set to + /usr/lib/. +While other platforms (x86-64, arm64) it will be + /usr/lib/../lib64 +Let's sync riscv64 with them + +Another problem is that + gcc -print-file-name=libzstd.so.1 +will output + /usr/lib64/lp64d/../lib64/libzstd.so.1 +which is also need to patched. +--- + gcc/config.gcc | 3 +++ + gcc/config/riscv/linux.h | 2 ++ + gcc/config/riscv/t-openEuler | 2 ++ + 3 files changed, 7 insertions(+) + create mode 100644 gcc/config/riscv/t-openEuler + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 19b21a280..23c5bee2b 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -2453,6 +2453,9 @@ riscv*-*-linux*) + xyes) tmake_file="${tmake_file} riscv/t-linux-multilib" ;; + *) echo "Unknown value for enable_multilib"; exit 1 + esac ++ case "x${target_vendor}" in ++ xopenEuler) tmake_file="${tmake_file} riscv/t-openEuler" ++ esac + tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux" + gnu_ld=yes + gas=yes +diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h +index b5c6c5027..a8d65f4e0 100644 +--- a/gcc/config/riscv/linux.h ++++ b/gcc/config/riscv/linux.h +@@ -62,6 +62,8 @@ along with GCC; see the file COPYING3. If not see + #define TARGET_ASM_FILE_END file_end_indicate_exec_stack + + #define STARTFILE_PREFIX_SPEC \ ++ "/lib" XLEN_SPEC "/ " \ ++ "/usr/lib" XLEN_SPEC "/ " \ + "/lib" XLEN_SPEC "/" ABI_SPEC "/ " \ + "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ " \ + "/lib/ " \ +diff --git a/gcc/config/riscv/t-openEuler b/gcc/config/riscv/t-openEuler +new file mode 100644 +index 000000000..26541dd08 +--- /dev/null ++++ b/gcc/config/riscv/t-openEuler +@@ -0,0 +1,2 @@ ++MULTILIB_OPTIONS = mabi=lp64d ++MULTILIB_DIRNAMES = ../lib64 +-- +2.39.5 (Apple Git-154) + diff --git a/0307-Set-fallback-value-for-print-multi-os-directory.patch b/0307-Set-fallback-value-for-print-multi-os-directory.patch new file mode 100644 index 0000000000000000000000000000000000000000..2032f6babfeec47a53f1e09b0d31d9cb66370d60 --- /dev/null +++ b/0307-Set-fallback-value-for-print-multi-os-directory.patch @@ -0,0 +1,105 @@ +From 0d157b14f361f8319f4694c54c6e01ac8f59d278 Mon Sep 17 00:00:00 2001 +From: YunQiang Su +Date: Tue, 8 Oct 2024 17:56:23 +0800 +Subject: [PATCH 1/2] Set fallback value for -print-multi-os-directory + +Clang doesn't support -print-multi-os-directory option. +So let's set the fallback value (../lib64) if it is empty. + +This is only needed for the projects built by hostcc: + gcc, libcc1, libiberty + +The projects for targets only, will always built by gcc itself. +--- + gcc/configure | 3 +++ + libcc1/configure | 6 ++++++ + libcc1/configure.ac | 3 +++ + libiberty/Makefile.in | 5 ++++- + libtool.m4 | 3 +++ + 5 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/gcc/configure b/gcc/configure +index 7e64599b0..ef0449edd 100755 +--- a/gcc/configure ++++ b/gcc/configure +@@ -18598,6 +18598,9 @@ if test "$GCC" = yes; then + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ if [ -z "$lt_multi_os_dir" ];then ++ lt_multi_os_dir=../lib64 ++ fi + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" +diff --git a/libcc1/configure b/libcc1/configure +index 01cfb2806..3c437d690 100755 +--- a/libcc1/configure ++++ b/libcc1/configure +@@ -9701,6 +9701,9 @@ if test "$GCC" = yes; then + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ if [ -z "$lt_multi_os_dir" ];then ++ lt_multi_os_dir=../lib64 ++ fi + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" +@@ -14865,6 +14868,9 @@ libsuffix= + if test "$GXX" = yes; then + libsuffix=`$CXX -print-multi-os-directory` + fi ++if [ -z "$libsuffix" ];then ++ libsuffix=../lib64 ++fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket libraries" >&5 +diff --git a/libcc1/configure.ac b/libcc1/configure.ac +index 36f5a7e09..acd7c4c04 100644 +--- a/libcc1/configure.ac ++++ b/libcc1/configure.ac +@@ -72,6 +72,9 @@ libsuffix= + if test "$GXX" = yes; then + libsuffix=`$CXX -print-multi-os-directory` + fi ++if [ -z "$libsuffix" ];then ++ libsuffix=../lib64 ++fi + AC_SUBST(libsuffix) + + dnl Test for -lsocket and -lnsl. Copied from libgo/configure.ac. +diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in +index 1b17c2e3a..2bfa00de5 100644 +--- a/libiberty/Makefile.in ++++ b/libiberty/Makefile.in +@@ -385,7 +385,10 @@ install-strip: install + # multilib-specific flags, it's overridden by FLAGS_TO_PASS from the + # default multilib, so we have to take CFLAGS into account as well, + # since it will be passed the multilib flags. +-MULTIOSDIR = `$(CC) $(CFLAGS) -print-multi-os-directory` ++MULTIOSDIR = `$(CC) $(CFLAGS) -print-multi-os-directory 2>/dev/null` ++ifeq ($(MULTIOSDIR),) ++ MULTIOSDIR = ../lib64 ++endif + install_to_libdir: all + if test -n "${target_header_dir}"; then \ + ${mkinstalldirs} $(DESTDIR)$(libdir)/$(MULTIOSDIR); \ +diff --git a/libtool.m4 b/libtool.m4 +index 17f8e5f30..86fc1e705 100644 +--- a/libtool.m4 ++++ b/libtool.m4 +@@ -2059,6 +2059,9 @@ if test "$GCC" = yes; then + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ if [ -z "$lt_multi_os_dir" ];then ++ lt_multi_os_dir=../lib64 ++ fi + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" +-- +2.47.0 + diff --git a/0308-Fix-enum-INPUT-MIDDLE-FINAL-aes_stage.patch b/0308-Fix-enum-INPUT-MIDDLE-FINAL-aes_stage.patch new file mode 100644 index 0000000000000000000000000000000000000000..a16e93722c9066aecd6191a69bf30f3d6ecc1320 --- /dev/null +++ b/0308-Fix-enum-INPUT-MIDDLE-FINAL-aes_stage.patch @@ -0,0 +1,108 @@ +From 1624bdceb341e0034c22ce46bc2e422726f76cce Mon Sep 17 00:00:00 2001 +From: YunQiang Su +Date: Tue, 8 Oct 2024 17:59:56 +0800 +Subject: [PATCH 2/2] Fix enum { INPUT, MIDDLE, FINAL } aes_stage + +The FINAL is defined in ansidecl.h. +Let's rename the elements to + aesINPUT, aseMIDDLE, aseFINAL +to avoid conflits. + +I find this problem when trying to build gcc with clang. +In fact FINAL is defined to empty for clang, and `final` for gcc. +So it coincidentally worked for gcc. +--- + gcc/crypto-accel.cc | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/gcc/crypto-accel.cc b/gcc/crypto-accel.cc +index e7766a585..716c4a38b 100644 +--- a/gcc/crypto-accel.cc ++++ b/gcc/crypto-accel.cc +@@ -1251,7 +1251,7 @@ public: + + /* AES stage description. Required for some specializations + for curtain rounds. */ +-typedef enum { INPUT, MIDDLE, FINAL } aes_stage; ++typedef enum { aesINPUT, aesMIDDLE, aesFINAL } aes_stage; + + /* AES entity description. It can be both round or state inside round. + It provides interface for unified analysis between blocks of 4 parts: +@@ -1356,7 +1356,7 @@ struct state_input + + /* Input round state uses special input. */ + template<> +-struct state_input ++struct state_input + { + typedef std::pair type; + +@@ -1389,7 +1389,7 @@ struct state_output + + /* Final round state generates special output. */ + template<> +-struct state_output ++struct state_output + { + typedef std::pair type; + +@@ -1409,7 +1409,7 @@ struct round_input + + /* Input round uses special input just as its state. */ + template<> +-struct round_input ++struct round_input + { + typedef std::pair type; + }; +@@ -1437,7 +1437,7 @@ struct round_output + AES encryption. */ + template<> + template<> +-void round_output::reorder (type &out) ++void round_output::reorder (type &out) + { + gcc_assert (out.size () == 4); + std::swap (out[1], out[3]); +@@ -1445,14 +1445,14 @@ void round_output::reorder (type &out) + + template<> + template<> +-void round_output::reorder (type &out) ++void round_output::reorder (type &out) + { +- round_output::reorder (out); ++ round_output::reorder (out); + } + + /* Final round generates special output. */ + template<> +-struct round_output : state_output ++struct round_output : state_output + { + template + static void finalize (type &out, const T &v) +@@ -1644,14 +1644,14 @@ public: + typedef std::map > table_ref_map; + + /* AES states typedefs. */ +- typedef aes_state aes_input_state; +- typedef aes_state, MIDDLE, T> aes_body_state; +- typedef aes_state, FINAL, T> aes_final_state; ++ typedef aes_state aes_input_state; ++ typedef aes_state, aesMIDDLE, T> aes_body_state; ++ typedef aes_state, aesFINAL, T> aes_final_state; + + /* AES rounds typedefs. */ +- typedef aes_round aes_input_round; +- typedef aes_round, MIDDLE, T> aes_body_round; +- typedef aes_round, FINAL, T> aes_final_round; ++ typedef aes_round aes_input_round; ++ typedef aes_round, aesMIDDLE, T> aes_body_round; ++ typedef aes_round, aesFINAL, T> aes_final_round; + + bool run (); + +-- +2.47.0 + diff --git a/0309-CSPGO-Add-context-sensitive-PGO.patch b/0309-CSPGO-Add-context-sensitive-PGO.patch new file mode 100644 index 0000000000000000000000000000000000000000..04174af2359e3f4b7e46d4f104e68068092d0782 --- /dev/null +++ b/0309-CSPGO-Add-context-sensitive-PGO.patch @@ -0,0 +1,1337 @@ +From 45a424e51c4c5de46062f2d7f355da8a99604d71 Mon Sep 17 00:00:00 2001 +From: liyancheng <412998149@qq.com> +Date: Tue, 19 Nov 2024 22:06:48 +0800 +Subject: [PATCH] [CSPGO] Add context sensitive PGO + +Same as LLVM, GCC PGO profile counts are not context sensitive. Therefore, +CSPGO is added to collect the profile again after PGO to obtain accurate +execution information after inline for better performance. +--- + gcc/auto-profile.cc | 2 +- + gcc/cgraph.cc | 47 ++++++++++ + gcc/cgraph.h | 8 +- + gcc/cgraphunit.cc | 63 ++++++++++++- + gcc/common.opt | 20 ++++ + gcc/coverage.cc | 162 +++++++++++++++++++++++--------- + gcc/coverage.h | 5 +- + gcc/gcc.cc | 5 +- + gcc/ipa-profile.cc | 4 +- + gcc/lto-cgraph.cc | 7 ++ + gcc/opts.cc | 18 ++++ + gcc/passes.cc | 71 ++++++++++++++ + gcc/passes.def | 1 + + gcc/profile.cc | 27 +++--- + gcc/profile.h | 2 +- + gcc/timevar.def | 1 + + gcc/tree-pass.h | 2 + + gcc/tree-profile.cc | 223 +++++++++++++++++++++++++++++++++++++++++++- + gcc/value-prof.cc | 9 +- + gcc/value-prof.h | 4 +- + 20 files changed, 611 insertions(+), 70 deletions(-) + +diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc +index f45f0ec66..5e85381ce 100644 +--- a/gcc/auto-profile.cc ++++ b/gcc/auto-profile.cc +@@ -1775,7 +1775,7 @@ auto_profile (void) + if (symtab->state == FINISHED) + return 0; + +- init_node_map (true); ++ init_node_map (true, false); + profile_info = autofdo::afdo_profile_info; + + FOR_EACH_FUNCTION (node) +diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc +index 7d738b891..95619aefa 100644 +--- a/gcc/cgraph.cc ++++ b/gcc/cgraph.cc +@@ -4076,6 +4076,53 @@ cgraph_node::get_body (void) + return updated; + } + ++/* Prepare function body. When doing LTO, read cgraph_node's body from disk ++ if it is not already present. When some IPA transformations are scheduled, ++ apply them. ++ Flag is used to control only skipping or enabling cspgo. */ ++ ++bool ++cgraph_node::ipa_transform_for_cspgo (bool is_cspgo) ++{ ++ bool updated; ++ ++ bitmap_obstack_initialize (NULL); ++ updated = get_untransformed_body (); ++ ++ /* Getting transformed body makes no sense for inline clones; ++ we should never use this on real clones because they are materialized ++ early. ++ TODO: Materializing clones here will likely lead to smaller LTRANS ++ footprint. */ ++ gcc_assert (!inlined_to && !clone_of); ++ if (ipa_transforms_to_apply.exists ()) ++ { ++ opt_pass *saved_current_pass = current_pass; ++ FILE *saved_dump_file = dump_file; ++ const char *saved_dump_file_name = dump_file_name; ++ dump_flags_t saved_dump_flags = dump_flags; ++ dump_file_name = NULL; ++ set_dump_file (NULL); ++ ++ push_cfun (DECL_STRUCT_FUNCTION (decl)); ++ ++ update_ssa (TODO_update_ssa_only_virtuals); ++ execute_all_ipa_transforms_for_cspgo (is_cspgo); ++ cgraph_edge::rebuild_edges (); ++ free_dominance_info (CDI_DOMINATORS); ++ free_dominance_info (CDI_POST_DOMINATORS); ++ pop_cfun (); ++ updated = true; ++ ++ current_pass = saved_current_pass; ++ set_dump_file (saved_dump_file); ++ dump_file_name = saved_dump_file_name; ++ dump_flags = saved_dump_flags; ++ } ++ bitmap_obstack_release (NULL); ++ return updated; ++} ++ + /* Return the DECL_STRUCT_FUNCTION of the function. */ + + struct function * +diff --git a/gcc/cgraph.h b/gcc/cgraph.h +index 2332539e5..3fdf36769 100644 +--- a/gcc/cgraph.h ++++ b/gcc/cgraph.h +@@ -1097,11 +1097,17 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node + present. */ + bool get_untransformed_body (); + +- /* Prepare function body. When doing LTO, read cgraph_node's body from disk ++ /* Prepare function body. When doing LTO, read cgraph_node's body from disk + if it is not already present. When some IPA transformations are scheduled, + apply them. */ + bool get_body (); + ++ /* Prepare function body. When doing LTO, read cgraph_node's body from disk ++ if it is not already present. When some IPA transformations are scheduled, ++ apply them. ++ Flag is used to control only skipping or enabling cspgo. */ ++ bool ipa_transform_for_cspgo (bool); ++ + void materialize_clone (void); + + /* Release memory used to represent body of function. +diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc +index 5aa7b57c9..37cc83eab 100644 +--- a/gcc/cgraphunit.cc ++++ b/gcc/cgraphunit.cc +@@ -208,6 +208,7 @@ along with GCC; see the file COPYING3. If not see + #include "ipa-inline.h" + #include "omp-offload.h" + #include "symtab-thunks.h" ++#include "profile.h" // for del_node_map + + /* Queue of cgraph nodes scheduled to be added into cgraph. This is a + secondary queue used during optimization to accommodate passes that +@@ -1928,6 +1929,29 @@ tp_first_run_node_cmp (const void *pa, const void *pb) + return tp_first_run_a - tp_first_run_b; + } + ++static bool ++expand_node_with_cspgo (cgraph_node *node, bool is_cspgo) ++{ ++ gcc_assert (node); ++ /* Nodes in other partition, inline to, and clone of are not ++ interesting in cspgo. */ ++ if (!node->has_gimple_body_p () ++ || node->in_other_partition ++ || node->inlined_to ++ || node->clone_of) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] node %s will not do" ++ " transform\n", node->dump_name ()); ++ return false; ++ } ++ ++ if (node->process) ++ node->ipa_transform_for_cspgo (is_cspgo); ++ return true; ++} ++ ++ + /* Expand all functions that must be output. + + Attempt to topologically sort the nodes so function is output when +@@ -1968,6 +1992,39 @@ expand_all_functions (void) + /* First output functions with time profile in specified order. */ + qsort (tp_first_run_order, tp_first_run_order_pos, + sizeof (cgraph_node *), tp_first_run_node_cmp); ++ ++ if (flag_csprofile_generate || flag_csprofile_use) ++ { ++ bool is_cspgo = false; ++ ++ /* We need to execute loop twice. The first performs all transforms ++ except cspgo, and the second performs cspgo transform. */ ++ for (int idx = 0; idx < 2; idx++) ++ { ++ for (i = 0; i < tp_first_run_order_pos; i++) ++ { ++ node = tp_first_run_order[i]; ++ if (!expand_node_with_cspgo (node, is_cspgo)) ++ continue; ++ } ++ ++ for (i = new_order_pos - 1; i >= 0; i--) ++ { ++ node = order[i]; ++ if (!expand_node_with_cspgo (node, is_cspgo)) ++ continue; ++ } ++ ++ is_cspgo = true; ++ } ++ ++ if (flag_csprofile_use) ++ handle_missing_profiles (); ++ ++ if (coverage_node_map_initialized_p ()) ++ del_node_map (); ++ } ++ + for (i = 0; i < tp_first_run_order_pos; i++) + { + node = tp_first_run_order[i]; +@@ -2009,6 +2066,10 @@ expand_all_functions (void) + fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n", + profiled_func_count, expanded_func_count); + ++ /* Generate coverage variables and constructor for cspgo. */ ++ if (flag_csprofile_generate) ++ coverage_finish (true); ++ + symtab->process_new_functions (); + free_gimplify_stack (); + delete ipa_saved_clone_sources; +@@ -2176,7 +2237,7 @@ ipa_passes (void) + if (!in_lto_p) + { + /* Generate coverage variables and constructors. */ +- coverage_finish (); ++ coverage_finish (false); + + /* Process new functions added. */ + set_cfun (NULL); +diff --git a/gcc/common.opt b/gcc/common.opt +index be5fcc681..fc2920cee 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -2397,6 +2397,10 @@ Common Joined RejectNegative Var(profile_data_prefix) + Set the top-level directory for storing the profile data. + The default is 'pwd'. + ++fcfgo-csprofile-dir= ++Common Joined RejectNegative Var(csprofile_data_prefix) ++Set the top-level directory for storing the cs profile data. ++ + fprofile-note= + Common Joined RejectNegative Var(profile_note_location) + Select the name for storing the profile note file. +@@ -2461,6 +2465,14 @@ fprofile-generate= + Common Joined RejectNegative + Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=. + ++fcfgo-csprofile-generate ++Common Var(flag_csprofile_generate) ++Enable common options for generating context sensitive profile info for profile feedback directed optimizations. ++ ++fcfgo-csprofile-generate= ++Common Joined RejectNegative ++Enable common options for generating context sensitive profile info for profile feedback directed optimizations, and set -fcfgo-csprofile-dir=. ++ + fkernel-pgo + Common Var(flag_kernel_pgo) Optimization Init(0) + Disable TLS setting of instrumentation variables to support PGO kernel compilation in -fprofile-generate, as kernel does not support TLS. +@@ -2485,6 +2497,14 @@ fprofile-use= + Common Joined RejectNegative + Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=. + ++fcfgo-csprofile-use ++Common Var(flag_csprofile_use) ++Enable common options for performing context sensitive profile feedback directed optimizations. ++ ++fcfgo-csprofile-use= ++Common Joined RejectNegative ++Enable common options for performing context sensitive profile feedback directed optimizations, and set -fcfgo-csprofile-dir=. ++ + fprofile-values + Common Var(flag_profile_values) + Insert code to profile values of expressions. +diff --git a/gcc/coverage.cc b/gcc/coverage.cc +index 8ece5db68..1a7fcb5df 100644 +--- a/gcc/coverage.cc ++++ b/gcc/coverage.cc +@@ -86,7 +86,6 @@ struct counts_entry : pointer_hash + + static GTY(()) struct coverage_data *functions_head = 0; + static struct coverage_data **functions_tail = &functions_head; +-static unsigned no_coverage = 0; + + /* Cumulative counter information for whole program. */ + static unsigned prg_ctr_mask; /* Mask of counter types generated. */ +@@ -114,6 +113,9 @@ static unsigned bbg_file_stamp; + /* Name of the count data (gcda) file. */ + static char *da_file_name; + ++/* Name of the cs count data (gcda) file. */ ++static char *cs_da_file_name; ++ + /* The names of merge functions for counters. */ + #define STR(str) #str + #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE), +@@ -173,23 +175,28 @@ counts_entry::remove (counts_entry *entry) + /* Hash table of count data. */ + static hash_table *counts_hash; + ++/* Hash table of cs count data. */ ++static hash_table *cs_counts_hash; ++ + /* Read in the counts file, if available. */ + + static void +-read_counts_file (void) ++read_counts_file (bool is_cspgo) + { + gcov_unsigned_t fn_ident = 0; + gcov_unsigned_t tag; + int is_error = 0; + unsigned lineno_checksum = 0; + unsigned cfg_checksum = 0; ++ char *gcda_file_name = (is_cspgo ? cs_da_file_name : da_file_name); + +- if (!gcov_open (da_file_name, 1)) ++ if (!gcov_open (gcda_file_name, 1)) + return; + + if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) + { +- warning (0, "%qs is not a gcov data file", da_file_name); ++ warning (0, "%qs is not a %s data file", gcda_file_name, ++ (is_cspgo ? "cs gcov" : "gcov")); + gcov_close (); + return; + } +@@ -201,7 +208,7 @@ read_counts_file (void) + GCOV_UNSIGNED2STRING (e, GCOV_VERSION); + + warning (0, "%qs is version %q.*s, expected version %q.*s", +- da_file_name, 4, v, 4, e); ++ gcda_file_name, 4, v, 4, e); + gcov_close (); + return; + } +@@ -213,7 +220,7 @@ read_counts_file (void) + /* Read checksum. */ + gcov_read_unsigned (); + +- counts_hash = new hash_table (10); ++ (is_cspgo ? cs_counts_hash : counts_hash) = new hash_table (10); + while ((tag = gcov_read_unsigned ())) + { + gcov_unsigned_t length; +@@ -234,9 +241,18 @@ read_counts_file (void) + } + else if (tag == GCOV_TAG_OBJECT_SUMMARY) + { +- profile_info = XCNEW (gcov_summary); +- profile_info->runs = gcov_read_unsigned (); +- profile_info->sum_max = gcov_read_unsigned (); ++ if (is_cspgo) ++ { ++ /* TODO: runs and sum_max need better handling for cspgo. */ ++ gcov_unsigned_t runs = gcov_read_unsigned (); ++ gcov_unsigned_t sum_max = gcov_read_unsigned (); ++ } ++ else ++ { ++ profile_info = XCNEW (gcov_summary); ++ profile_info->runs = gcov_read_unsigned (); ++ profile_info->sum_max = gcov_read_unsigned (); ++ } + } + else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident) + { +@@ -249,7 +265,9 @@ read_counts_file (void) + elt.ident = fn_ident; + elt.ctr = GCOV_COUNTER_FOR_TAG (tag); + +- slot = counts_hash->find_slot (&elt, INSERT); ++ slot = (is_cspgo ? cs_counts_hash->find_slot (&elt, INSERT) : ++ counts_hash->find_slot (&elt, INSERT)); ++ + entry = *slot; + if (!entry) + { +@@ -264,12 +282,21 @@ read_counts_file (void) + else if (entry->lineno_checksum != lineno_checksum + || entry->cfg_checksum != cfg_checksum) + { +- error ("profile data for function %u is corrupted", fn_ident); ++ error ("%s data for function %u is corrupted", ++ (is_cspgo ? "cs profile" : "profile"), fn_ident); + error ("checksum is (%x,%x) instead of (%x,%x)", + entry->lineno_checksum, entry->cfg_checksum, + lineno_checksum, cfg_checksum); +- delete counts_hash; +- counts_hash = NULL; ++ if (is_cspgo) ++ { ++ delete cs_counts_hash; ++ cs_counts_hash = NULL; ++ } ++ else ++ { ++ delete counts_hash; ++ counts_hash = NULL; ++ } + break; + } + if (read_length > 0) +@@ -282,9 +309,17 @@ read_counts_file (void) + error (is_error < 0 + ? G_("%qs has overflowed") + : G_("%qs is corrupted"), +- da_file_name); +- delete counts_hash; +- counts_hash = NULL; ++ gcda_file_name); ++ if (is_cspgo) ++ { ++ delete cs_counts_hash; ++ cs_counts_hash = NULL; ++ } ++ else ++ { ++ delete counts_hash; ++ counts_hash = NULL; ++ } + break; + } + } +@@ -296,26 +331,30 @@ read_counts_file (void) + + gcov_type * + get_coverage_counts (unsigned counter, unsigned cfg_checksum, +- unsigned lineno_checksum, unsigned int n_counts) ++ unsigned lineno_checksum, unsigned int n_counts, ++ bool is_cspgo) + { + counts_entry *entry, elt; ++ char *gcda_file_name = (is_cspgo ? cs_da_file_name : da_file_name); + + /* No hash table, no counts. */ +- if (!counts_hash) ++ if ((is_cspgo ? (!cs_counts_hash) : (!counts_hash))) + { + static int warned = 0; + + if (!warned++) + { + warning (OPT_Wmissing_profile, +- "%qs profile count data file not found", +- da_file_name); ++ "%qs %s count data file not found", ++ gcda_file_name, (is_cspgo ? "cs profile" : "profile")); + if (dump_enabled_p ()) + { + dump_user_location_t loc + = dump_user_location_t::from_location_t (input_location); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, +- "file %s not found, %s\n", da_file_name, ++ "%s file %s not found, %s\n", ++ (is_cspgo ? "cs profile" : "profile"), ++ gcda_file_name, + (flag_guess_branch_prob + ? "execution counts estimated" + : "execution counts assumed to be zero")); +@@ -331,13 +370,14 @@ get_coverage_counts (unsigned counter, unsigned cfg_checksum, + elt.ident = cgraph_node::get (current_function_decl)->profile_id; + } + elt.ctr = counter; +- entry = counts_hash->find (&elt); ++ entry = (is_cspgo ? cs_counts_hash->find (&elt) : counts_hash->find (&elt)); + if (!entry) + { + if (counter == GCOV_COUNTER_ARCS) + warning_at (DECL_SOURCE_LOCATION (current_function_decl), + OPT_Wmissing_profile, +- "profile for function %qD not found in profile data", ++ "%s for function %qD not found in profile data", ++ (is_cspgo ? "cs profile" : "profile"), + current_function_decl); + /* The function was not emitted, or is weak and not chosen in the + final executable. Silently fail, because there's nothing we +@@ -357,9 +397,10 @@ get_coverage_counts (unsigned counter, unsigned cfg_checksum, + warning_printed = + warning_at (DECL_SOURCE_LOCATION (current_function_decl), + OPT_Wcoverage_mismatch, +- "number of counters in profile data for function %qD " ++ "number of counters in %s data for function %qD " + "does not match " + "its profile data (counter %qs, expected %i and have %i)", ++ (is_cspgo ? "cs profile" : "profile"), + current_function_decl, + ctr_names[counter], entry->n_counts, n_counts); + else +@@ -367,7 +408,8 @@ get_coverage_counts (unsigned counter, unsigned cfg_checksum, + warning_at (DECL_SOURCE_LOCATION (current_function_decl), + OPT_Wcoverage_mismatch, + "the control flow of function %qD does not match " +- "its profile data (counter %qs)", current_function_decl, ++ "its %s data (counter %qs)", current_function_decl, ++ (is_cspgo ? "cs profile" : "profile"), + ctr_names[counter]); + if (warning_printed && dump_enabled_p ()) + { +@@ -413,9 +455,6 @@ get_coverage_counts (unsigned counter, unsigned cfg_checksum, + int + coverage_counter_alloc (unsigned counter, unsigned num) + { +- if (no_coverage) +- return 0; +- + if (!num) + return 1; + +@@ -623,7 +662,7 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum) + { + /* We don't need to output .gcno file unless we're under -ftest-coverage + (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */ +- if (no_coverage || !bbg_file_name) ++ if (!bbg_file_name) + return 0; + + expanded_location startloc +@@ -981,7 +1020,8 @@ build_info_type (tree type, tree fn_info_ptr_type) + function info objects. */ + + static tree +-build_info (tree info_type, tree fn_ary, unsigned object_checksum) ++build_info (tree info_type, tree fn_ary, unsigned object_checksum, ++ bool is_cspgo) + { + tree info_fields = TYPE_FIELDS (info_type); + tree merge_fn_type, n_funcs; +@@ -1014,8 +1054,16 @@ build_info (tree info_type, tree fn_ary, unsigned object_checksum) + info_fields = DECL_CHAIN (info_fields); + + /* Filename */ +- da_file_name_len = strlen (da_file_name); +- filename_string = build_string (da_file_name_len + 1, da_file_name); ++ if (is_cspgo) ++ { ++ da_file_name_len = strlen (cs_da_file_name); ++ filename_string = build_string (da_file_name_len + 1, cs_da_file_name); ++ } ++ else ++ { ++ da_file_name_len = strlen (da_file_name); ++ filename_string = build_string (da_file_name_len + 1, da_file_name); ++ } + TREE_TYPE (filename_string) = build_array_type + (char_type_node, build_index_type (size_int (da_file_name_len))); + CONSTRUCTOR_APPEND_ELT (v1, info_fields, +@@ -1142,7 +1190,7 @@ build_gcov_info_var_registration (tree gcov_info_type) + for the object. Returns TRUE if coverage data is being emitted. */ + + static bool +-coverage_obj_init (void) ++coverage_obj_init (bool is_cspgo) + { + tree gcov_info_type; + unsigned n_counters = 0; +@@ -1151,8 +1199,6 @@ coverage_obj_init (void) + struct coverage_data **fn_prev; + char name_buf[32]; + +- no_coverage = 1; /* Disable any further coverage. */ +- + if (!prg_ctr_mask) + return false; + +@@ -1161,7 +1207,9 @@ coverage_obj_init (void) + + /* Prune functions. */ + for (fn_prev = &functions_head; (fn = *fn_prev);) +- if (DECL_STRUCT_FUNCTION (fn->fn_decl)) ++ /* In cspgo, the DECL_STRUCT_FUNCTION attribute has been checked in ++ csprofile_transform. */ ++ if (is_cspgo || DECL_STRUCT_FUNCTION (fn->fn_decl)) + fn_prev = &fn->next; + else + /* The function is not being emitted, remove from list. */ +@@ -1225,7 +1273,7 @@ coverage_obj_fn (vec *ctor, tree fn, + + static void + coverage_obj_finish (vec *ctor, +- unsigned object_checksum) ++ unsigned object_checksum, bool is_cspgo) + { + unsigned n_functions = vec_safe_length (ctor); + tree fn_info_ary_type = build_array_type +@@ -1242,7 +1290,8 @@ coverage_obj_finish (vec *ctor, + varpool_node::finalize_decl (fn_info_ary); + + DECL_INITIAL (gcov_info_var) +- = build_info (TREE_TYPE (gcov_info_var), fn_info_ary, object_checksum); ++ = build_info (TREE_TYPE (gcov_info_var), fn_info_ary, object_checksum, ++ is_cspgo); + varpool_node::finalize_decl (gcov_info_var); + } + +@@ -1310,11 +1359,32 @@ coverage_init (const char *filename) + memcpy (da_file_name + prefix_len, filename, len); + strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX); + ++ /* Name of cspgo da file. */ ++ if (flag_csprofile_generate || flag_csprofile_use) ++ { ++ if (csprofile_data_prefix) ++ prefix_len = strlen (csprofile_data_prefix); ++ ++ cs_da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX) ++ + prefix_len + 2); ++ ++ if (csprofile_data_prefix) ++ { ++ memcpy (cs_da_file_name, csprofile_data_prefix, prefix_len); ++ cs_da_file_name[prefix_len++] = *separator; ++ } ++ memcpy (cs_da_file_name + prefix_len, filename, len); ++ strcpy (cs_da_file_name + prefix_len + len, GCOV_DATA_SUFFIX); ++ } ++ + bbg_file_stamp = local_tick; + if (flag_auto_profile) + read_autofdo_file (); + else if (flag_branch_probabilities) +- read_counts_file (); ++ read_counts_file (false); ++ ++ if (flag_csprofile_use) ++ read_counts_file (true); + + /* Name of bbg file. */ + if (flag_test_coverage && !flag_compare_debug) +@@ -1354,7 +1424,7 @@ coverage_init (const char *filename) + variables and constructor. */ + + void +-coverage_finish (void) ++coverage_finish (bool is_cspgo) + { + if (bbg_file_name && gcov_close ()) + unlink (bbg_file_name); +@@ -1368,7 +1438,7 @@ coverage_finish (void) + /* Global GCDA checksum that aggregates all functions. */ + unsigned object_checksum = 0; + +- if (coverage_obj_init ()) ++ if (coverage_obj_init (is_cspgo)) + { + vec *fn_ctor = NULL; + struct coverage_data *fn; +@@ -1382,11 +1452,17 @@ coverage_finish (void) + fn->lineno_checksum); + object_checksum = crc32_unsigned (object_checksum, fn->cfg_checksum); + } +- coverage_obj_finish (fn_ctor, object_checksum); ++ coverage_obj_finish (fn_ctor, object_checksum, is_cspgo); + } + +- XDELETEVEC (da_file_name); ++ if (da_file_name) ++ XDELETEVEC (da_file_name); + da_file_name = NULL; ++ if (is_cspgo) ++ { ++ XDELETEVEC (cs_da_file_name); ++ cs_da_file_name = NULL; ++ } + } + + #include "gt-coverage.h" +diff --git a/gcc/coverage.h b/gcc/coverage.h +index 0ac046c88..a4e90e8bd 100644 +--- a/gcc/coverage.h ++++ b/gcc/coverage.h +@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see + #include "gcov-io.h" + + extern void coverage_init (const char *); +-extern void coverage_finish (void); ++extern void coverage_finish (bool); + extern void coverage_remove_note_file (void); + + /* Start outputting coverage information for the current +@@ -53,7 +53,8 @@ extern tree tree_coverage_counter_addr (unsigned /*counter*/, unsigned/*num*/); + extern gcov_type *get_coverage_counts (unsigned /*counter*/, + unsigned /*cfg_checksum*/, + unsigned /*lineno_checksum*/, +- unsigned /*n_counts*/); ++ unsigned /*n_counts*/, ++ bool /*is_cspgo*/); + + extern tree get_gcov_type (void); + extern bool coverage_node_map_initialized_p (void); +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index 32e45adc2..b37b50be2 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -1147,7 +1147,8 @@ proper position among the other output files. */ + %:include(libgomp.spec)%(link_gomp)}\ + %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\ + %(mflib) " STACK_SPLIT_SPEC "\ +- %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \ ++ %{fprofile-arcs|fprofile-generate*|fcfgo-csprofile-generate*|coverage:-lgcov} \ ++ " SANITIZER_SPEC " \ + %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\ + %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*} \n%(post_link) }}}}}}" + #endif +@@ -1265,7 +1266,7 @@ static const char *cc1_options = + %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\ + %{fsyntax-only:-o %j} %{-param*}\ + %{coverage:-fprofile-arcs -ftest-coverage}\ +- %{fprofile-arcs|fprofile-generate*|coverage:\ ++ %{fprofile-arcs|fprofile-generate*|fcfgo-csprofile-generate*|coverage:\ + %{!fprofile-update=single:\ + %{pthread:-fprofile-update=prefer-atomic}}}"; + +diff --git a/gcc/ipa-profile.cc b/gcc/ipa-profile.cc +index ffdcb4476..27554e507 100644 +--- a/gcc/ipa-profile.cc ++++ b/gcc/ipa-profile.cc +@@ -827,7 +827,7 @@ ipa_profile (void) + if (dump_file) + { + if (!node_map_initialized) +- init_node_map (false); ++ init_node_map (false, false); + node_map_initialized = true; + + ipa_profile_dump_all_summaries (dump_file); +@@ -850,7 +850,7 @@ ipa_profile (void) + if (spec_count) + { + if (!node_map_initialized) +- init_node_map (false); ++ init_node_map (false, false); + node_map_initialized = true; + ncommon++; + +diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc +index 237743ef0..fd41941d1 100644 +--- a/gcc/lto-cgraph.cc ++++ b/gcc/lto-cgraph.cc +@@ -1677,6 +1677,13 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec) + if (flag_ltrans) + return; + ++ /* TODO: The different max_run values obtained during the cspgo GEN and USE ++ stages with unknown bug resulted in different scaling results, which led ++ different optimization decisions and finally led to coverage mismatch. ++ Therefore, skip the following processing steps when doing cspgo. */ ++ if (flag_csprofile_generate || flag_csprofile_use) ++ return; ++ + /* Now compute count_materialization_scale of each node. + During LTRANS we already have values of count_materialization_scale + computed, so just update them. */ +diff --git a/gcc/opts.cc b/gcc/opts.cc +index d97f6079f..7900a658f 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -3016,6 +3016,15 @@ common_handle_option (struct gcc_options *opts, + false); + break; + ++ case OPT_fcfgo_csprofile_use_: ++ opts->x_csprofile_data_prefix = xstrdup (arg); ++ value = true; ++ /* No break here - do -fcfgo-csprofile-use processing. */ ++ /* FALLTHRU */ ++ case OPT_fcfgo_csprofile_use: ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_csprofile_use, value); ++ break; ++ + case OPT_fauto_profile_: + opts->x_auto_profile_file = xstrdup (arg); + opts->x_flag_auto_profile = true; +@@ -3059,6 +3068,15 @@ common_handle_option (struct gcc_options *opts, + SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value); + break; + ++ case OPT_fcfgo_csprofile_generate_: ++ opts->x_csprofile_data_prefix = xstrdup (arg); ++ value = true; ++ /* No break here - do -fcfgo-csprofile-generate processing. */ ++ /* FALLTHRU */ ++ case OPT_fcfgo_csprofile_generate: ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_csprofile_generate, value); ++ break; ++ + case OPT_fprofile_info_section: + opts->x_profile_info_section = ".gcov_info"; + break; +diff --git a/gcc/passes.cc b/gcc/passes.cc +index 36e5b4ac4..154690d02 100644 +--- a/gcc/passes.cc ++++ b/gcc/passes.cc +@@ -2410,6 +2410,77 @@ execute_all_ipa_transforms (bool do_not_collect) + node->ipa_transforms_to_apply.release (); + } + ++/* When is_cspgo is true, execute all passes except cspgo and save the pointer ++ for the next execution. */ ++ ++void ++execute_all_ipa_transforms_for_cspgo (bool is_cspgo) ++{ ++ struct cgraph_node *node; ++ ipa_opt_pass_d *cspgo_pass = NULL; ++ node = cgraph_node::get (current_function_decl); ++ ++ cgraph_node *next_clone; ++ for (cgraph_node *n = node->clones; n; n = next_clone) ++ { ++ next_clone = n->next_sibling_clone; ++ if (n->decl != node->decl) ++ n->materialize_clone (); ++ } ++ ++ int j = 0; ++ gcc::pass_manager *passes = g->get_passes (); ++ bool report = profile_report && (cfun->curr_properties & PROP_gimple) != 0; ++ ++ if (report) ++ push_cfun (DECL_STRUCT_FUNCTION (node->decl)); ++ ++ for (auto p : node->ipa_transforms_to_apply) ++ { ++ /* Execute all passes except cspgo, and save the pointer of cspgo pass ++ for the next execution. */ ++ if (!is_cspgo && strstr (p->name, "csprofile") != NULL) ++ { ++ cspgo_pass = p; ++ continue; ++ } ++ /* To get consistent statistics, we need to account each functio ++ to each IPA pass. */ ++ if (report) ++ { ++ for (;j < p->static_pass_number; j++) ++ if (passes->get_pass_for_id (j) ++ && passes->get_pass_for_id (j)->type == IPA_PASS ++ && ((ipa_opt_pass_d *)passes->get_pass_for_id (j)) ++ ->function_transform) ++ { ++ check_profile_consistency (j, true); ++ account_profile (j, true); ++ } ++ gcc_checking_assert (passes->get_pass_for_id (j) == p); ++ } ++ execute_one_ipa_transform_pass (node, p, true); ++ } ++ /* Account remaining IPA passes. */ ++ if (report) ++ { ++ for (;!passes->get_pass_for_id (j) ++ || passes->get_pass_for_id (j)->type != RTL_PASS; j++) ++ if (passes->get_pass_for_id (j) ++ && passes->get_pass_for_id (j)->type == IPA_PASS ++ && ((ipa_opt_pass_d *)passes->get_pass_for_id (j)) ++ ->function_transform) ++ { ++ check_profile_consistency (j, true); ++ account_profile (j, true); ++ } ++ pop_cfun (); ++ } ++ node->ipa_transforms_to_apply.release (); ++ if (!is_cspgo) ++ node->ipa_transforms_to_apply.safe_push (cspgo_pass); ++} ++ + /* Check if PASS is explicitly disabled or enabled and return + the gate status. FUNC is the function to be processed, and + GATE_STATUS is the gate status determined by pass manager by +diff --git a/gcc/passes.def b/gcc/passes.def +index e945af96a..862ef0d8f 100644 +--- a/gcc/passes.def ++++ b/gcc/passes.def +@@ -164,6 +164,7 @@ along with GCC; see the file COPYING3. If not see + NEXT_PASS (pass_ipa_cdtor_merge); + NEXT_PASS (pass_ipa_fn_summary); + NEXT_PASS (pass_ipa_inline); ++ NEXT_PASS (pass_ipa_csprofile); + NEXT_PASS (pass_ipa_pure_const); + NEXT_PASS (pass_ipa_modref); + NEXT_PASS (pass_ipa_free_fn_summary, false /* small_p */); +diff --git a/gcc/profile.cc b/gcc/profile.cc +index 40e105258..0ffc1ba4f 100644 +--- a/gcc/profile.cc ++++ b/gcc/profile.cc +@@ -201,7 +201,7 @@ instrument_values (histogram_values values) + CFG_CHECKSUM is the precomputed checksum for the CFG. */ + + static gcov_type * +-get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum) ++get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum, bool is_cspgo) + { + unsigned num_edges = 0; + basic_block bb; +@@ -219,7 +219,7 @@ get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum) + } + + counts = get_coverage_counts (GCOV_COUNTER_ARCS, cfg_checksum, +- lineno_checksum, num_edges); ++ lineno_checksum, num_edges, is_cspgo); + if (!counts) + return NULL; + +@@ -418,7 +418,8 @@ cmp_stats (const void *ptr1, const void *ptr2) + CFG_CHECKSUM is the precomputed checksum for the CFG. */ + + static void +-compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum) ++compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum, ++ bool is_cspgo) + { + basic_block bb; + int i; +@@ -427,7 +428,8 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum) + int passes; + int hist_br_prob[20]; + int num_branches; +- gcov_type *exec_counts = get_exec_counts (cfg_checksum, lineno_checksum); ++ gcov_type *exec_counts = get_exec_counts (cfg_checksum, lineno_checksum, ++ is_cspgo); + int inconsistent = 0; + + /* Very simple sanity checks so we catch bugs in our profiling code. */ +@@ -868,7 +870,7 @@ sort_hist_values (histogram_value hist) + + static void + compute_value_histograms (histogram_values values, unsigned cfg_checksum, +- unsigned lineno_checksum) ++ unsigned lineno_checksum, bool is_cspgo) + { + unsigned i, j, t, any; + unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS]; +@@ -898,7 +900,8 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum, + histogram_counts[t] = get_coverage_counts (COUNTER_FOR_HIST_TYPE (t), + cfg_checksum, + lineno_checksum, +- n_histogram_counters[t]); ++ n_histogram_counters[t], ++ is_cspgo); + if (histogram_counts[t]) + any = 1; + act_count[t] = histogram_counts[t]; +@@ -1128,11 +1131,12 @@ compare_freqs (const void *p1, const void *p2) + /* Only read execution count for thunks. */ + + void +-read_thunk_profile (struct cgraph_node *node) ++read_thunk_profile (struct cgraph_node *node, bool is_cspgo) + { + tree old = current_function_decl; + current_function_decl = node->decl; +- gcov_type *counts = get_coverage_counts (GCOV_COUNTER_ARCS, 0, 0, 1); ++ gcov_type *counts = get_coverage_counts (GCOV_COUNTER_ARCS, 0, 0, 1, ++ is_cspgo); + if (counts) + { + node->callees->count = node->count +@@ -1164,7 +1168,7 @@ read_thunk_profile (struct cgraph_node *node) + Main entry point of this file. */ + + void +-branch_prob (bool thunk) ++branch_prob (bool thunk, bool is_cspgo) + { + basic_block bb; + unsigned i; +@@ -1507,9 +1511,10 @@ branch_prob (bool thunk) + + if (flag_branch_probabilities) + { +- compute_branch_probabilities (cfg_checksum, lineno_checksum); ++ compute_branch_probabilities (cfg_checksum, lineno_checksum, is_cspgo); + if (flag_profile_values) +- compute_value_histograms (values, cfg_checksum, lineno_checksum); ++ compute_value_histograms (values, cfg_checksum, lineno_checksum, ++ is_cspgo); + } + + remove_fake_edges (); +diff --git a/gcc/profile.h b/gcc/profile.h +index c5b6f4889..e92d6154c 100644 +--- a/gcc/profile.h ++++ b/gcc/profile.h +@@ -68,7 +68,7 @@ extern void mcf_smooth_cfg (void); + + extern gcov_type sum_edge_counts (vec *edges); + +-extern void init_node_map (bool); ++extern void init_node_map (bool, bool); + extern void del_node_map (void); + + extern void get_working_sets (void); +diff --git a/gcc/timevar.def b/gcc/timevar.def +index fc2b1e1e7..6fdb2c767 100644 +--- a/gcc/timevar.def ++++ b/gcc/timevar.def +@@ -104,6 +104,7 @@ DEFTIMEVAR (TV_WHOPR_PARTITIONING , "whopr partitioning") + DEFTIMEVAR (TV_WHOPR_LTRANS , "whopr ltrans") + DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference") + DEFTIMEVAR (TV_IPA_PROFILE , "ipa profile") ++DEFTIMEVAR (TV_IPA_CSPROFILE , "ipa csprofile") + DEFTIMEVAR (TV_IPA_AUTOFDO , "auto profile") + DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const") + DEFTIMEVAR (TV_IPA_ICF , "ipa icf") +diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h +index 18b0f8022..f9c2eed8b 100644 +--- a/gcc/tree-pass.h ++++ b/gcc/tree-pass.h +@@ -519,6 +519,7 @@ extern simple_ipa_opt_pass *make_pass_ipa_increase_alignment (gcc::context + *ctxt); + extern ipa_opt_pass_d *make_pass_ipa_fn_summary (gcc::context *ctxt); + extern ipa_opt_pass_d *make_pass_ipa_inline (gcc::context *ctxt); ++extern ipa_opt_pass_d *make_pass_ipa_csprofile (gcc::context *ctxt); + extern simple_ipa_opt_pass *make_pass_ipa_free_lang_data (gcc::context *ctxt); + extern simple_ipa_opt_pass *make_pass_ipa_free_fn_summary (gcc::context *ctxt); + extern ipa_opt_pass_d *make_pass_ipa_cp (gcc::context *ctxt); +@@ -667,6 +668,7 @@ extern void execute_pass_list (function *, opt_pass *); + extern void execute_ipa_pass_list (opt_pass *); + extern void execute_ipa_summary_passes (ipa_opt_pass_d *); + extern void execute_all_ipa_transforms (bool); ++extern void execute_all_ipa_transforms_for_cspgo (bool); + extern void execute_all_ipa_stmt_fixups (struct cgraph_node *, gimple **); + extern bool pass_init_dump_file (opt_pass *); + extern void pass_fini_dump_file (opt_pass *); +diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc +index e7646f1a1..aa3a2b3a9 100644 +--- a/gcc/tree-profile.cc ++++ b/gcc/tree-profile.cc +@@ -725,7 +725,7 @@ tree_profiling (void) + cgraphunit.cc:ipa_passes(). */ + gcc_assert (symtab->state == IPA_SSA); + +- init_node_map (true); ++ init_node_map (true, false); + parse_profile_file_filtering (); + + FOR_EACH_DEFINED_FUNCTION (node) +@@ -766,7 +766,7 @@ tree_profiling (void) + time. */ + else + { +- read_thunk_profile (node); ++ read_thunk_profile (node, false); + continue; + } + } +@@ -781,7 +781,7 @@ tree_profiling (void) + && (execute_fixup_cfg () & TODO_cleanup_cfg)) + cleanup_tree_cfg (); + +- branch_prob (thunk); ++ branch_prob (thunk, false); + + if (! flag_branch_probabilities + && flag_profile_values) +@@ -863,6 +863,170 @@ tree_profiling (void) + return 0; + } + ++/* Profile all functions in the callgraph with cs profile. */ ++ ++static unsigned int ++csprofile_transform (struct cgraph_node *node) ++{ ++ basic_block bb; ++ bool thunk = false; ++ ++ parse_profile_file_filtering (); ++ ++ if (dump_file) ++ { ++ fprintf (dump_file, "[cspgo] trying cspgo on function:\n"); ++ dump_function_header (dump_file, cfun->decl, dump_flags); ++ } ++ ++ if (!DECL_STRUCT_FUNCTION (current_function_decl)) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s without function decl, skip.\n", ++ node->dump_name ()); ++ return 0; ++ } ++ ++ if (!gimple_has_body_p (node->decl) && !node->thunk) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s without gimple body, skip.\n", ++ node->dump_name ()); ++ return 0; ++ } ++ ++ /* Don't profile functions produced for builtin stuff. */ ++ if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s with BUILTINS_LOCATION, skip.\n", ++ node->dump_name ()); ++ return 0; ++ } ++ ++ const char *file = LOCATION_FILE (DECL_SOURCE_LOCATION (node->decl)); ++ if (!file || !include_source_file_for_profile (file)) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s is sub func or in filter-files, " ++ "skip.\n", node->dump_name ()); ++ return 0; ++ } ++ ++ if (lookup_attribute ("no_profile_instrument_function", ++ DECL_ATTRIBUTES (node->decl))) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s is no_profile_instrument_function," ++ " skip.\n", node->dump_name ()); ++ return 0; ++ } ++ ++ /* Do not instrument extern inline functions. */ ++ if (DECL_EXTERNAL (node->decl)) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s is DECL_EXTERNAL, skip.\n", ++ node->dump_name ()); ++ return 0; ++ } ++ ++ if (!coverage_node_map_initialized_p ()) ++ init_node_map (true, true); ++ ++ /* Node without profile id should skip. */ ++ if (!node->profile_id) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s does not has profile_id, skip.\n", ++ node->dump_name ()); ++ return 0; ++ } ++ ++ if (flag_csprofile_generate) ++ { ++ profile_arc_flag = 1; ++ flag_branch_probabilities = 0; ++ } ++ ++ /* Process thunk function. */ ++ if (node->thunk) ++ { ++ /* We cannot expand variadic thunks to Gimple. */ ++ if (stdarg_p (TREE_TYPE (node->decl))) ++ { ++ if (dump_file) ++ fprintf (dump_file, "[cspgo] %s is DECL_EXTERNAL, skip.\n", ++ node->dump_name ()); ++ return 0; ++ } ++ thunk = true; ++ /* When generate profile, expand thunk to gimple so it can be ++ instrumented same way as other functions. */ ++ if (profile_arc_flag) ++ expand_thunk (node, false, true); ++ /* Read cgraph profile but keep function as thunk at profile-use ++ time. */ ++ else ++ { ++ read_thunk_profile (node, true); ++ return 0; ++ } ++ } ++ ++ /* Local pure-const may imply need to fixup the cfg. */ ++ if (gimple_has_body_p (node->decl) ++ && (execute_fixup_cfg () & TODO_cleanup_cfg)) ++ cleanup_tree_cfg (); ++ ++ branch_prob (thunk, true); ++ ++ if (! flag_branch_probabilities ++ && flag_profile_values) ++ gimple_gen_ic_func_profiler (); ++ ++ if (flag_branch_probabilities ++ && !thunk ++ && flag_profile_values ++ && flag_value_profile_transformations ++ && profile_status_for_fn (cfun) == PROFILE_READ) ++ gimple_value_profile_transformations (); ++ ++ /* The above could hose dominator info. Currently there is ++ none coming in, this is a safety valve. It should be ++ easy to adjust it, if and when there is some. */ ++ free_dominance_info (CDI_DOMINATORS); ++ free_dominance_info (CDI_POST_DOMINATORS); ++ ++ release_profile_file_filtering (); ++ ++ if (flag_csprofile_generate) ++ { ++ profile_arc_flag = 0; ++ flag_branch_probabilities = 1; ++ } ++ ++ /* Update call statements and rebuild the cgraph. */ ++ FOR_EACH_BB_FN (bb, cfun) ++ { ++ gimple_stmt_iterator gsi; ++ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) ++ { ++ gimple *stmt = gsi_stmt (gsi); ++ if (is_gimple_call (stmt)) ++ update_stmt (stmt); ++ } ++ } ++ ++ /* re-merge split blocks. */ ++ cleanup_tree_cfg (); ++ update_ssa (TODO_update_ssa); ++ ++ cgraph_edge::rebuild_edges (); ++ ++ return 0; ++} ++ + namespace { + + const pass_data pass_data_ipa_tree_profile = +@@ -910,4 +1074,57 @@ make_pass_ipa_tree_profile (gcc::context *ctxt) + return new pass_ipa_tree_profile (ctxt); + } + ++namespace { ++ ++const pass_data pass_data_ipa_csprofile = ++{ ++ IPA_PASS, /* type */ ++ "csprofile", /* name */ ++ OPTGROUP_NONE, /* optinfo_flags */ ++ TV_IPA_CSPROFILE, /* tv_id */ ++ 0, /* properties_required */ ++ 0, /* properties_provided */ ++ 0, /* properties_destroyed */ ++ 0, /* todo_flags_start */ ++ 0, /* todo_flags_finish */ ++}; ++ ++class pass_ipa_csprofile : public ipa_opt_pass_d ++{ ++public: ++ pass_ipa_csprofile (gcc::context *ctxt) ++ : ipa_opt_pass_d (pass_data_ipa_csprofile, ctxt, ++ NULL, /* generate_summary */ ++ NULL, /* write_summary */ ++ NULL, /* read_summary */ ++ NULL, /* write_optimization_summary */ ++ NULL, /* read_optimization_summary */ ++ NULL, /* stmt_fixup */ ++ 0, /* function_transform_todo_flags_start */ ++ csprofile_transform, /* function_transform */ ++ NULL) /* variable_transform */ ++ {} ++ ++ /* opt_pass methods: */ ++ virtual bool gate (function *) ++ { ++ return (flag_csprofile_generate || flag_csprofile_use); ++ } ++ /* The main process of cspgo is in csprofile_transform, execute does not need ++ to do anything. */ ++ virtual unsigned int execute (function *) ++ { ++ return 0; ++ } ++ ++}; // class pass_ipa_csprofile ++ ++} // anon namespace ++ ++ipa_opt_pass_d * ++make_pass_ipa_csprofile (gcc::context *ctxt) ++{ ++ return new pass_ipa_csprofile (ctxt); ++} ++ + #include "gt-tree-profile.h" +diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc +index c240a1863..9c7191287 100644 +--- a/gcc/value-prof.cc ++++ b/gcc/value-prof.cc +@@ -1234,7 +1234,7 @@ coverage_node_map_initialized_p (void) + that the PROFILE_IDs was already assigned. */ + + void +-init_node_map (bool local) ++init_node_map (bool local, bool is_cspgo) + { + struct cgraph_node *n; + cgraph_node_map = new hash_map; +@@ -1245,6 +1245,12 @@ init_node_map (bool local) + cgraph_node **val; + dump_user_location_t loc + = dump_user_location_t::from_function_decl (n->decl); ++ ++ /* In cspgo, inline and clone functions will not be expand, ++ so skipped. */ ++ if (is_cspgo && (n->inlined_to || n->clone_of)) ++ continue; ++ + if (local) + { + n->profile_id = coverage_compute_profile_id (n); +@@ -1290,6 +1296,7 @@ void + del_node_map (void) + { + delete cgraph_node_map; ++ cgraph_node_map = 0; + } + + /* Return cgraph node for function with pid */ +diff --git a/gcc/value-prof.h b/gcc/value-prof.h +index d852c41f3..0fe3821c3 100644 +--- a/gcc/value-prof.h ++++ b/gcc/value-prof.h +@@ -112,8 +112,8 @@ extern struct cgraph_node* find_func_by_profile_id (int func_id); + + /* In profile.cc. */ + extern void init_branch_prob (void); +-extern void branch_prob (bool); +-extern void read_thunk_profile (struct cgraph_node *); ++extern void branch_prob (bool, bool); ++extern void read_thunk_profile (struct cgraph_node *, bool); + extern void end_branch_prob (void); + + #endif /* GCC_VALUE_PROF_H */ +-- +2.25.1 + diff --git a/0310-CFGO-Add-cfgo-pgo-optimization.patch b/0310-CFGO-Add-cfgo-pgo-optimization.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a930aba6773ef382ee5c83821b5f3a1894aa8df --- /dev/null +++ b/0310-CFGO-Add-cfgo-pgo-optimization.patch @@ -0,0 +1,168 @@ +From 84635dc65ebe285457d0c16bbb5caf995f803436 Mon Sep 17 00:00:00 2001 +From: liyancheng <412998149@qq.com> +Date: Wed, 27 Nov 2024 18:36:27 +0800 +Subject: [PATCH] [CFGO] Add cfgo-pgo optimization + +Add a cfgo-pgo to better optimize with AI4C +--- + gcc/common.opt | 16 +++++++++++++ + gcc/gcc.cc | 4 ++-- + gcc/lto-cgraph.cc | 3 ++- + gcc/opts.cc | 57 +++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 77 insertions(+), 3 deletions(-) + +diff --git a/gcc/common.opt b/gcc/common.opt +index c9baa12be..a45fbfe1b 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -2485,6 +2485,14 @@ fprofile-generate= + Common Joined RejectNegative + Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=. + ++fcfgo-profile-generate ++Common Var(flag_cfgo_profile_generate) ++Enable common options for generating cfgo profile info for profile feedback directed optimizations. ++ ++fcfgo-profile-generate= ++Common Joined RejectNegative ++Enable common options for generating cfgo profile info for profile feedback directed optimizations, and set -fprofile-dir=. ++ + fcfgo-csprofile-generate + Common Var(flag_csprofile_generate) + Enable common options for generating context sensitive profile info for profile feedback directed optimizations. +@@ -2517,6 +2525,14 @@ fprofile-use= + Common Joined RejectNegative + Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=. + ++fcfgo-profile-use ++Common Var(flag_cfgo_profile_use) ++Enable common options for performing profile feedback directed optimizations. ++ ++fcfgo-profile-use= ++Common Joined RejectNegative ++Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=. ++ + fcfgo-csprofile-use + Common Var(flag_csprofile_use) + Enable common options for performing context sensitive profile feedback directed optimizations. +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index b37b50be2..e5c43dd90 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -1147,7 +1147,7 @@ proper position among the other output files. */ + %:include(libgomp.spec)%(link_gomp)}\ + %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\ + %(mflib) " STACK_SPLIT_SPEC "\ +- %{fprofile-arcs|fprofile-generate*|fcfgo-csprofile-generate*|coverage:-lgcov} \ ++ %{fprofile-arcs|fprofile-generate*|fcfgo-profile-generate*|fcfgo-csprofile-generate*|coverage:-lgcov} \ + " SANITIZER_SPEC " \ + %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\ + %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*} \n%(post_link) }}}}}}" +@@ -1266,7 +1266,7 @@ static const char *cc1_options = + %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\ + %{fsyntax-only:-o %j} %{-param*}\ + %{coverage:-fprofile-arcs -ftest-coverage}\ +- %{fprofile-arcs|fprofile-generate*|fcfgo-csprofile-generate*|coverage:\ ++ %{fprofile-arcs|fprofile-generate*|fcfgo-profile-generate*|fcfgo-csprofile-generate*|coverage:\ + %{!fprofile-update=single:\ + %{pthread:-fprofile-update=prefer-atomic}}}"; + +diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc +index fd41941d1..9a30f1190 100644 +--- a/gcc/lto-cgraph.cc ++++ b/gcc/lto-cgraph.cc +@@ -1681,7 +1681,8 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec) + stages with unknown bug resulted in different scaling results, which led + different optimization decisions and finally led to coverage mismatch. + Therefore, skip the following processing steps when doing cspgo. */ +- if (flag_csprofile_generate || flag_csprofile_use) ++ if (flag_csprofile_generate || flag_csprofile_use ++ || flag_cfgo_profile_generate || flag_cfgo_profile_use) + return; + + /* Now compute count_materialization_scale of each node. +diff --git a/gcc/opts.cc b/gcc/opts.cc +index 89d03e834..84dd8925a 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -2087,6 +2087,38 @@ enable_fdo_optimizations (struct gcc_options *opts, + SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribution, value); + } + ++/* Enable cfgo-related flags. */ ++ ++static void ++enable_cfgo_optimizations (struct gcc_options *opts, ++ struct gcc_options *opts_set, ++ int value) ++{ ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_modulo_sched, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_selective_scheduling, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_rename_registers, value); ++ ++ SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_auto, 185); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_inline_unit_growth, 66); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_recursive_depth_auto, ++ 31); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_large_function_insns, 7286); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_large_function_growth, 89); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_large_unit_insns, 11783); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_eval_threshold, 864); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_loop_hint_bonus, 440); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_max_recursive_depth, 29); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_min_recursive_probability, ++ 4); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_recursive_freq_factor, 18); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_recursion_penalty, 64); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_single_call_penalty, 43); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_unit_growth, 96); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_large_unit_insns, 47631); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_value_list_size, 12); ++ SET_OPTION_IF_UNSET (opts, opts_set, param_ipa_cp_profile_count_base, 54); ++} ++ + /* -f{,no-}sanitize{,-recover}= suboptions. */ + const struct sanitizer_opts_s sanitizer_opts[] = + { +@@ -3033,6 +3065,18 @@ common_handle_option (struct gcc_options *opts, + /* Deferred. */ + break; + ++ case OPT_fcfgo_profile_use_: ++ /* No break here - do -fcfgo-profile-use processing. */ ++ /* FALLTHRU */ ++ case OPT_fcfgo_profile_use: ++ value = true; ++ if (value) ++ { ++ enable_cfgo_optimizations (opts, opts_set, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_cfgo_profile_use, value); ++ } ++ /* No break here - do -fprofile-use processing. */ ++ /* FALLTHRU */ + case OPT_fprofile_use_: + opts->x_profile_data_prefix = xstrdup (arg); + opts->x_flag_profile_use = true; +@@ -3090,6 +3134,19 @@ common_handle_option (struct gcc_options *opts, + SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_struct_reorg, value); + break; + ++ case OPT_fcfgo_profile_generate_: ++ /* No break here - do -fcfgo-profile-generate processing. */ ++ /* FALLTHRU */ ++ case OPT_fcfgo_profile_generate: ++ value = true; ++ if (value) ++ { ++ enable_cfgo_optimizations (opts, opts_set, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_cfgo_profile_generate, ++ value); ++ } ++ /* No break here - do -fcfgo-profile-generate processing. */ ++ /* FALLTHRU */ + case OPT_fprofile_generate_: + opts->x_profile_data_prefix = xstrdup (arg); + value = true; +-- +2.25.1 + diff --git a/0311-PATCH-Add-if-split-optimization-pass.patch b/0311-PATCH-Add-if-split-optimization-pass.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e3b75e2435c857d786ded4f10a7eba6a5774987 --- /dev/null +++ b/0311-PATCH-Add-if-split-optimization-pass.patch @@ -0,0 +1,1203 @@ +From 899db9bca3c2ef3cd346814be761eed8b85f5e1e Mon Sep 17 00:00:00 2001 +From: liyancheng <412998149@qq.com> +Date: Wed, 27 Nov 2024 19:26:13 +0800 +Subject: [PATCH] [PATCH] Add if-split optimization pass + +This pass splits conditions like +if (cond1 or cond2) +to the sequense of separate conditions. + +This happens only if there is a function call under condition +Which depends on the condition variable. +--- + gcc/Makefile.in | 1 + + gcc/common.opt | 4 + + gcc/gimple-if-split.cc | 567 ++++++++++++++++++++ + gcc/opts.cc | 2 +- + gcc/passes.def | 1 + + gcc/testsuite/gcc.dg/tree-ssa/if-split-1.c | 24 + + gcc/testsuite/gcc.dg/tree-ssa/if-split-10.c | 45 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-2.c | 36 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-3.c | 36 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-4.c | 42 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-5.c | 42 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-6.c | 45 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-7.c | 45 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-8.c | 42 ++ + gcc/testsuite/gcc.dg/tree-ssa/if-split-9.c | 44 ++ + gcc/timevar.def | 1 + + gcc/tree-cfg.h | 2 + + gcc/tree-pass.h | 1 + + gcc/tree-ssa-ifcombine.cc | 6 +- + 19 files changed, 981 insertions(+), 5 deletions(-) + create mode 100644 gcc/gimple-if-split.cc + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-1.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-10.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-2.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-3.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-4.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-5.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-6.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-7.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-8.c + create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-split-9.c + +diff --git a/gcc/Makefile.in b/gcc/Makefile.in +index bb6197a8e..683b28896 100644 +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -1393,6 +1393,7 @@ OBJS = \ + gimple-builder.o \ + gimple-expr.o \ + gimple-if-to-switch.o \ ++ gimple-if-split.o \ + gimple-iterator.o \ + gimple-fold.o \ + gimple-harden-conditionals.o \ +diff --git a/gcc/common.opt b/gcc/common.opt +index a45fbfe1b..a52fa9814 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1981,6 +1981,10 @@ finstrument-functions-exclude-file-list= + Common RejectNegative Joined + -finstrument-functions-exclude-file-list=filename,... Do not instrument functions listed in files. + ++fif-split ++Common Var(flag_if_split) Init(0) Optimization ++Perform splitting if complex conditions on separate ones with clonning their bodies (gimple version). ++ + fipa-cp + Common Var(flag_ipa_cp) Optimization + Perform interprocedural constant propagation. +diff --git a/gcc/gimple-if-split.cc b/gcc/gimple-if-split.cc +new file mode 100644 +index 000000000..3446204ea +--- /dev/null ++++ b/gcc/gimple-if-split.cc +@@ -0,0 +1,567 @@ ++/* If-split. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 3, or (at your option) any later ++version. ++ ++GCC is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#include "config.h" ++#define INCLUDE_FUNCTIONAL ++#include "system.h" ++#include "coretypes.h" ++#include "tree.h" ++#include "tree-ssa.h" ++#include "tree-pass.h" ++#include "diagnostic-core.h" ++#include "function.h" ++#include "basic-block.h" ++#include "gimple.h" ++#include "gimple-pretty-print.h" ++#include "gimple-iterator.h" ++#include "cfg.h" ++#include "cfghooks.h" ++#include "ssa.h" ++#include "fold-const.h" ++#include "tree-into-ssa.h" ++#include "tree-cfg.h" ++#include "bitmap.h" ++#include "cfganal.h" ++ ++/* Perform splitting if-then-else patterns, whose complex OR condition in ++cond-bb contains comparison of some variable with constant and then-bb got ++function call, whose arg list contains this var (or this variable is a ++scalar of an aggregate which is an arg of this call). We split condition on ++two separate ones and duplicate then-bb for each one, thus help ipa const ++prop to propagate corresponding constant in function calls. ++Example: ++ Before: ++ if (n == const || some_cond) ++ func (n); ++ After: ++ if (n == const) ++ func (n); ++ else if (some_cond) ++ func (n); */ ++ ++//------------------------------------------------------------------------- ++// Auxiliary functions ++//------------------------------------------------------------------------- ++/* Check if arg list of call got n. */ ++bool ++got_in_args_p (gimple* call, tree n) ++{ ++ unsigned num_args = gimple_call_num_args (call); ++ ++ for (int i = 0; i < num_args; i++) ++ { ++ if (n == gimple_call_arg (call, i)) ++ return true; ++ } ++ ++ return false; ++} ++ ++#define SCALAR_NESTING 2 ++/* Check if call is "necessary" for n. Call is called "necessary" ++ * for n, if n is one of call args, or n is scalar of some aggregate, ++ * which is one of this call args. Nesting param determines how many ++ * levels of aggregate-scalar nesting we want to check. For example, ++ * if nesting == 2, we allow only 2 levels of nesting, like ++ * outer_aggr->inner_aggr->scalar. */ ++static bool ++necessary_call_p (gimple *call, tree n, unsigned nesting) ++{ ++ if (!call) ++ return false; ++ ++ if (got_in_args_p (call, n)) ++ return true; ++ ++ /* Else we need to check if n could be a scalar of some aggregate which ++ * is one of call args. */ ++ tree scalar = n; ++ tree aggregate = NULL_TREE; ++ ++ for (int i = 0; i < nesting; i++) ++ { ++ if (!scalar || TREE_CODE (scalar) != SSA_NAME) ++ return false; ++ ++ gimple *scalar_def = SSA_NAME_DEF_STMT (scalar); ++ ++ if (!is_gimple_assign (scalar_def) ++ || gimple_assign_rhs_code (scalar_def) != COMPONENT_REF) ++ return false; ++ ++ tree scalar_def_rhs = gimple_assign_rhs1 (scalar_def); ++ tree aggregate = TREE_OPERAND (scalar_def_rhs, 0); ++ ++ if (TREE_CODE (aggregate) == MEM_REF) ++ aggregate = TREE_OPERAND (aggregate, 0); ++ ++ if (aggregate && got_in_args_p (call, aggregate)) ++ return true; ++ ++ scalar = aggregate; ++ } ++ ++ return false; ++} ++ ++/* Check if bb got a "necessary" call statement. */ ++static bool ++bb_got_necessary_call_p (basic_block bb, tree n, unsigned nesting) ++{ ++ gimple *stmt = NULL; ++ ++ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ++ gsi_next (&gsi)) ++ { ++ gimple *stmt = gsi_stmt (gsi); ++ ++ if (is_gimple_call (stmt) && necessary_call_p (stmt, n, nesting)) ++ return true; ++ } ++ ++ return false; ++} ++ ++//------------------------------------------------------------------------- ++// Complex conditions ++//------------------------------------------------------------------------- ++/* Auxiliary struct which contains var and its constant of comaprison ++ * of expr: n == cst. */ ++struct var_const ++{ ++ tree n = NULL_TREE; ++ tree cst = NULL_TREE; ++}; ++ ++/* Check if var_def stmt got this pattern: ++ * var = (n == const); ++ * If it does, we need to set var_cst struct. */ ++static bool ++comp_with_const_p (gimple *var_def, var_const *var_cst) ++{ ++ if (gimple_expr_code (var_def) != EQ_EXPR) ++ return false; ++ ++ tree var_def_rhs2 = gimple_assign_rhs2 (var_def); ++ ++ if (TREE_CODE (var_def_rhs2) != INTEGER_CST) ++ return false; ++ ++ var_cst->n = gimple_assign_rhs1 (var_def); ++ var_cst->cst = var_def_rhs2; ++ ++ return true; ++} ++ ++/* Auxiliary struct which contains defenition of each part of ++ * complex condition, like: ++ * a = ... <- a_def ++ * b = ... <- b_def ++ * c = a | b <- complex_cond. */ ++struct cond_parts_defs ++{ ++ gimple *a_def = NULL; ++ gimple *b_def = NULL; ++}; ++ ++/* Check if cond got this pattern: ++ * a = ...; <- a_def ++ * b = ...; <- b_def ++ * c = a | b; ++ * if (c != 0) ++ * and a_def or b_def is comparison with constant. If it does, ++ * we need to set a with a_def and b with b_def. */ ++static bool ++necessary_complex_cond_p (const gimple *cond, basic_block then_bb, ++ cond_parts_defs *defs) ++{ ++ tree lhs = gimple_cond_lhs (cond); ++ tree rhs = gimple_cond_rhs (cond); ++ ++ /* As we look for: if (c != 0). */ ++ if (gimple_cond_code (cond) != NE_EXPR || TREE_CODE (lhs) != SSA_NAME ++ || !integer_zerop (rhs)) ++ return false; ++ ++ gimple *c_def = SSA_NAME_DEF_STMT (lhs); ++ ++ /* As we look for: c = a | b. */ ++ if (!c_def || !is_gimple_assign (c_def) || gimple_num_ops (c_def) != 3 ++ || gimple_expr_code (c_def) != BIT_IOR_EXPR) ++ return false; ++ ++ tree a_var = gimple_assign_rhs1 (c_def); ++ tree b_var = gimple_assign_rhs2 (c_def); ++ gimple *a_def = SSA_NAME_DEF_STMT (a_var); ++ gimple *b_def = SSA_NAME_DEF_STMT (b_var); ++ ++ if (!a_def || !is_gimple_assign (a_def) || !b_def ++ || !is_gimple_assign (b_def)) ++ return false; ++ ++ var_const var_cst; ++ ++ if (!(comp_with_const_p (a_def, &var_cst) ++ && bb_got_necessary_call_p (then_bb, var_cst.n, SCALAR_NESTING)) ++ && !(comp_with_const_p (b_def, &var_cst) ++ && bb_got_necessary_call_p (then_bb, var_cst.n, SCALAR_NESTING))) ++ return false; ++ ++ defs->a_def = a_def; ++ defs->b_def = b_def; ++ ++ return true; ++} ++ ++/* Check if our complex condition seems to be "necessary" ++ * and if it does split it on two separate ones. Like: ++ * a = (n == const); <- a_def ++ * b = smth; <- b_def ++ * c = a | b ++ * if (c != 0) ++ * call func (n, ...) ++ * Transform this to: ++ * if (n == const) ++ * goto then ++ * else if (b != 0) ++ * goto then ++ * then: ++ * call func (n, ...). ++ * A complex condition is called "necessary", if it is OR of two ++ * conditions, one of them is comparison with constant and then_bb ++ * of this cond got "necessary" function_call. To know, what ++ * "necessary" function call means look at necessary_call_p (). */ ++static void ++process_complex_cond (basic_block cond_bb, basic_block then_bb, ++ basic_block else_bb) ++{ ++ gimple *cond = last_stmt (cond_bb); ++ cond_parts_defs defs; ++ ++ if (!can_duplicate_block_p (then_bb) ++ || !necessary_complex_cond_p (cond, then_bb, &defs)) ++ return; ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, ++ "Recognized necessary complex condition: ", cond_bb->index); ++ print_gimple_stmt (dump_file, cond, 0, TDF_NONE); ++ } ++ ++ var_const var_cst; ++ ++ /* Setting cond. */ ++ if (comp_with_const_p (defs.a_def, &var_cst)) ++ /* Setting cond as: if (n == const). */ ++ gimple_cond_set_condition (as_a (cond), EQ_EXPR, var_cst.n, ++ var_cst.cst); ++ else ++ { ++ /* Setting cond as: if (a != 0). */ ++ tree cond_lhs = gimple_assign_lhs (defs.a_def); ++ gimple_cond_set_condition (as_a (cond), NE_EXPR, cond_lhs, ++ build_zero_cst (TREE_TYPE (cond_lhs))); ++ } ++ update_stmt (cond); ++ ++ /* Creating inner_cond_bb. */ ++ edge then_e = find_edge (cond_bb, then_bb); ++ edge else_e = find_edge (cond_bb, else_bb); ++ basic_block inner_cond_bb = split_edge (else_e); ++ ++ /* Setting inner_cond. */ ++ gcond *inner_cond = NULL; ++ if (comp_with_const_p (defs.b_def, &var_cst)) ++ { ++ /* Setting inner cond as: if (b == const). */ ++ inner_cond = gimple_build_cond (EQ_EXPR, var_cst.n, var_cst.cst, ++ NULL_TREE, NULL_TREE); ++ } ++ else ++ { ++ /* Setting inner cond as: if (b != 0). */ ++ tree inner_cond_lhs = gimple_assign_lhs (defs.b_def); ++ inner_cond = gimple_build_cond ( ++ NE_EXPR, inner_cond_lhs, build_zero_cst (TREE_TYPE (inner_cond_lhs)), ++ NULL_TREE, NULL_TREE); ++ } ++ gimple_stmt_iterator gsi = gsi_last_bb (inner_cond_bb); ++ gsi_insert_after (&gsi, inner_cond, GSI_NEW_STMT); ++ ++ /* Configuring edges. */ ++ edge inner_cond_then_e = make_edge (inner_cond_bb, then_bb, EDGE_TRUE_VALUE); ++ edge inner_cond_else_e = find_edge (inner_cond_bb, else_bb); ++ inner_cond_else_e->flags = EDGE_FALSE_VALUE; ++ ++ /* Setting phinode args in then_bb coming from inner_cond_bb the same as ++ * ones coming from cond_bb. */ ++ for (gphi_iterator psi = gsi_start_phis (then_bb); !gsi_end_p (psi); ++ gsi_next (&psi)) ++ { ++ gphi *phi = psi.phi (); ++ add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (phi, then_e), inner_cond_then_e, ++ UNKNOWN_LOCATION); ++ } ++ ++ /* Updating dominators. */ ++ set_immediate_dominator (CDI_DOMINATORS, inner_cond_bb, cond_bb); ++ basic_block cond_bb_postdominator ++ = get_immediate_dominator (CDI_POST_DOMINATORS, cond_bb); ++ set_immediate_dominator (CDI_POST_DOMINATORS, inner_cond_bb, ++ cond_bb_postdominator); ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "Successfully transformed:\n (o_cond) ", ++ cond_bb->index); ++ print_gimple_stmt (dump_file, cond, 0, TDF_NONE); ++ fprintf (dump_file, " (i_cond) ", inner_cond_bb->index); ++ print_gimple_stmt (dump_file, inner_cond, 0, TDF_NONE); ++ } ++} ++ ++//------------------------------------------------------------------------- ++// Condition pairs ++//------------------------------------------------------------------------- ++/* Transforming cfg if we recognized patern in process_condition_pair (). */ ++static basic_block ++make_two_separate_calls (basic_block outer_cond_bb, basic_block inner_cond_bb, ++ basic_block then_bb) ++{ ++ if (!can_duplicate_block_p (then_bb) || EDGE_COUNT (then_bb->succs) != 1) ++ return NULL; ++ ++ edge outer_then_e = find_edge (outer_cond_bb, then_bb); ++ ++ /* Making duplication of then_bb. */ ++ basic_block then_bb_dom = get_immediate_dominator (CDI_DOMINATORS, then_bb); ++ basic_block merge_bb = split_edge (single_succ_edge (then_bb)); ++ basic_block then_bb1 = duplicate_block (then_bb, outer_then_e, outer_cond_bb); ++ edge outer_then1_e = find_edge (outer_cond_bb, then_bb1); ++ ++ /* Setting phinode args in then_bb1 coming from outer_cond_bb by previously ++ * collected args_from_outer_cond_bb. */ ++ flush_pending_stmts (outer_then1_e); ++ ++ /* Updating dominators. */ ++ if (then_bb_dom == outer_cond_bb) ++ set_immediate_dominator (CDI_DOMINATORS, then_bb, inner_cond_bb); ++ ++ set_immediate_dominator (CDI_DOMINATORS, merge_bb, then_bb_dom); ++ set_immediate_dominator (CDI_DOMINATORS, then_bb1, outer_cond_bb); ++ ++ set_immediate_dominator (CDI_POST_DOMINATORS, then_bb, merge_bb); ++ set_immediate_dominator (CDI_POST_DOMINATORS, then_bb1, merge_bb); ++ set_immediate_dominator (CDI_POST_DOMINATORS, merge_bb, ++ single_succ (merge_bb)); ++ ++ return then_bb1; ++} ++ ++/* Here we check if cond of bb got this pattern: ++ * if (n == const) ++ * And if it does we need to set n. */ ++static bool ++got_necessary_cond_p (basic_block bb, tree *n) ++{ ++ gimple *stmt = last_stmt (bb); ++ if (!stmt || gimple_code (stmt) != GIMPLE_COND) ++ return false; ++ ++ gcond *cond = as_a (stmt); ++ ++ if (gimple_cond_code (cond) != EQ_EXPR ++ || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME ++ || TREE_CODE (gimple_cond_rhs (cond)) != INTEGER_CST) ++ return false; ++ ++ *n = gimple_cond_lhs (cond); ++ ++ return true; ++} ++ ++/* Recognize pattern: ++ * if (n == const) ++ * goto then ++ * else if (some_cond) ++ * goto then ++ * then: ++ * call func (n, ...) ++ * Transform this to: ++ * if (n == const) ++ * call func (n, ...) ++ * else if (some_cond) ++ * call func (n, ...). */ ++static void ++process_cond_pair (basic_block outer_cond_bb, basic_block inner_cond_bb, ++ basic_block then_bb) ++{ ++ tree n = NULL_TREE; ++ ++ if (inner_cond_bb == then_bb ++ || !recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb) ++ || !same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb) ++ || (!got_necessary_cond_p (outer_cond_bb, &n) ++ && !got_necessary_cond_p (inner_cond_bb, &n)) ++ || !bb_got_necessary_call_p (then_bb, n, SCALAR_NESTING)) ++ return; ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "Recognized necessary condition pair: (o_cond) "); ++ print_gimple_stmt (dump_file, last_stmt (outer_cond_bb), 0, TDF_NONE); ++ fprintf (dump_file, " (i_cond) "); ++ print_gimple_stmt (dump_file, last_stmt (inner_cond_bb), 0, TDF_NONE); ++ } ++ ++ basic_block then_bb1 ++ = make_two_separate_calls (outer_cond_bb, inner_cond_bb, then_bb); ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ if (then_bb1) ++ fprintf (dump_file, ++ "Successfully transformed: bb<%d> is a copy of bb<%d> \n", ++ then_bb1->index, then_bb->index); ++ else ++ fprintf (dump_file, "No transformation: bb<%d> cannot be duplicated \n", ++ then_bb->index); ++ } ++} ++ ++//------------------------------------------------------------------------- ++// Main logic ++//------------------------------------------------------------------------- ++/* If cond_bb suits if-then-else pattern and got single pred, execute func ++ * over it and its then, else basic blocks. */ ++template ++static void ++process_bb (basic_block cond_bb, F func) ++{ ++ basic_block then_bb = NULL, else_bb = NULL; ++ ++ if (!recognize_if_then_else (cond_bb, &then_bb, &else_bb)) ++ return; ++ ++ func (cond_bb, then_bb, else_bb); ++} ++ ++/* For each block, if it has condition, execute function over it. We walk ++ * the blocks in order that guarantees that a block with a single predecessor ++ * is processed after the predecessor. */ ++template ++static void ++execute_function_over_conditional_bbs (F func) ++{ ++ basic_block *bbs = single_pred_before_succ_order (); ++ for (int i = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--) ++ { ++ gimple *stmt = last_stmt (bbs[i]); ++ ++ if (stmt && gimple_code (stmt) == GIMPLE_COND) ++ { ++ process_bb (bbs[i], func); ++ } ++ } ++ update_ssa (TODO_update_ssa); ++ free (bbs); ++} ++ ++static void ++process_if_split_cfun () ++{ ++ /* First pass. Split complex conditions, so process_condition_pair_bb () ++ * will be able to recognize more necessary patterns. */ ++ execute_function_over_conditional_bbs (process_complex_cond); ++ ++ /* Second pass. Search each basic block for condition pair we may be ++ * able to optimize. */ ++ execute_function_over_conditional_bbs ( ++ [] (basic_block cond_bb, basic_block then_bb, basic_block else_bb) ++ { ++ if (!single_pred_p (cond_bb)) ++ return; ++ process_cond_pair (single_pred (cond_bb), cond_bb, then_bb); ++ }); ++} ++ ++namespace ++{ ++ ++const pass_data pass_data_if_split = { ++ GIMPLE_PASS, /* type. */ ++ "if-split", /* name. */ ++ OPTGROUP_NONE, /* optinfo_flags. */ ++ TV_TREE_IF_SPLIT, /* tv_id. */ ++ 0, /* properties_required. */ ++ 0, /* properties_provided. */ ++ 0, /* properties_destroyed. */ ++ 0, /* todo_flags_start. */ ++ 0 /* todo_flags_finish. */ ++}; ++ ++class pass_if_split : public gimple_opt_pass ++{ ++public: ++ pass_if_split (gcc::context *ctxt) ++ : gimple_opt_pass (pass_data_if_split, ctxt) ++ { ++ } ++ ++ /* opt_pass methods: */ ++ virtual bool ++ gate (function *) ++ { ++ /* Don't bother doing anything if the program has errors. */ ++ return (optimize >= 3 && flag_if_split && !seen_error ()); ++ } ++ ++ virtual unsigned int execute (function *); ++ ++}; // class pass_if_split ++ ++unsigned int ++pass_if_split::execute (function *fun) ++{ ++ calculate_dominance_info (CDI_DOMINATORS); ++ calculate_dominance_info (CDI_POST_DOMINATORS); ++ initialize_original_copy_tables (); ++ ++ process_if_split_cfun (); ++ ++ checking_verify_ssa (true, true); ++ checking_verify_flow_info (); ++ checking_verify_dominators (CDI_DOMINATORS); ++ checking_verify_dominators (CDI_POST_DOMINATORS); ++ ++ free_original_copy_tables (); ++ free_dominance_info (CDI_POST_DOMINATORS); ++ free_dominance_info (CDI_DOMINATORS); ++ ++ return 0; ++} ++ ++} // anon namespace ++ ++gimple_opt_pass * ++make_pass_if_split (gcc::context *ctxt) ++{ ++ return new pass_if_split (ctxt); ++} +\ No newline at end of file +diff --git a/gcc/opts.cc b/gcc/opts.cc +index 84dd8925a..4f3eb4bd4 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -3145,7 +3145,7 @@ common_handle_option (struct gcc_options *opts, + SET_OPTION_IF_UNSET (opts, opts_set, flag_cfgo_profile_generate, + value); + } +- /* No break here - do -fcfgo-profile-generate processing. */ ++ /* No break here - do -fprofile-generate processing. */ + /* FALLTHRU */ + case OPT_fprofile_generate_: + opts->x_profile_data_prefix = xstrdup (arg); +diff --git a/gcc/passes.def b/gcc/passes.def +index 862ef0d8f..fbe828439 100644 +--- a/gcc/passes.def ++++ b/gcc/passes.def +@@ -100,6 +100,7 @@ along with GCC; see the file COPYING3. If not see + NEXT_PASS (pass_if_to_switch); + NEXT_PASS (pass_convert_switch); + NEXT_PASS (pass_cleanup_eh); ++ NEXT_PASS (pass_if_split); + NEXT_PASS (pass_profile); + NEXT_PASS (pass_local_pure_const); + NEXT_PASS (pass_modref); +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-1.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-1.c +new file mode 100644 +index 000000000..5909dac41 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-1.c +@@ -0,0 +1,24 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int main(int argc, char** argv){ ++ int b = argc; ++ int res = 0; ++ ++ if (b == 5 || b == 52) ++ res = foo (b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 1 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-10.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-10.c +new file mode 100644 +index 000000000..20a45116b +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-10.c +@@ -0,0 +1,45 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int foo2 (); ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ int foo2_res = foo2(); ++ ++ if (data.y.b == 5 || data.y.b == 52 || foo2_res == 25) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 2 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-2.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-2.c +new file mode 100644 +index 000000000..1370f9474 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-2.c +@@ -0,0 +1,36 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct X ++{ ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_a (X* x, int val) ++{ ++ x->a = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int main(int argc, char** argv){ ++ X data; ++ set_a (&data, argc); ++ int res = 0; ++ ++ if (data.a == 5 || data.a == 52) ++ res = foo (data.a); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 1 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-3.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-3.c +new file mode 100644 +index 000000000..93a6eb6dd +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-3.c +@@ -0,0 +1,36 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct X ++{ ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_a (X* x, int val) ++{ ++ x->a = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int main(int argc, char** argv){ ++ X data; ++ set_a (&data, argc); ++ int res = 0; ++ ++ if (data.a == 5 || data.a == 52 || data.a == 25) ++ res = foo (data.a); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 2 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-4.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-4.c +new file mode 100644 +index 000000000..36f2a15b3 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-4.c +@@ -0,0 +1,42 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ ++ if (data.y.b == 5 || data.y.b == 52) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 1 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-5.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-5.c +new file mode 100644 +index 000000000..fbc3b0c19 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-5.c +@@ -0,0 +1,42 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ ++ if (data.y.b == 5 || data.y.b == 52 || data.y.b == 25) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 2 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-6.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-6.c +new file mode 100644 +index 000000000..185127c79 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-6.c +@@ -0,0 +1,45 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int foo2 (); ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ int foo2_res = foo2(); ++ ++ if (data.y.b == 5 || foo2_res == 52) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 1 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-7.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-7.c +new file mode 100644 +index 000000000..23f1a8f04 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-7.c +@@ -0,0 +1,45 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int foo2 (); ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ ++ if (data.y.b == 5 || foo2() == 52) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary complex condition:" 0 "if-split" } } */ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 0 "if-split" } } */ ++/* { dg-final { scan-tree-dump-times "Successfully transformed:" 0 "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-8.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-8.c +new file mode 100644 +index 000000000..028b6dc40 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-8.c +@@ -0,0 +1,42 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ ++ if (data.y.b == 5 || data.a == 52) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 1 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-split-9.c b/gcc/testsuite/gcc.dg/tree-ssa/if-split-9.c +new file mode 100644 +index 000000000..3ff7e2efc +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/if-split-9.c +@@ -0,0 +1,44 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fif-split -fdump-tree-if-split-details" } */ ++ ++typedef struct Y ++{ ++ int b; ++} Y; ++ ++typedef struct X ++{ ++ Y y; ++ int a; ++} X; ++ ++ ++void __attribute__ ((noinline)) set_b (Y* y, int val) ++{ ++ y->b = val; ++} ++ ++static __attribute__ ((noinline)) int foo (int b) ++{ ++ int res = 1; ++ for (int i = 0; i < b; i++) { ++ res*=3; ++ } ++ return res; ++} ++ ++int foo2 (); ++ ++int main(int argc, char** argv){ ++ X data; ++ set_b (&data.y, argc); ++ int res = 0; ++ ++ if (data.y.b == 5 || data.y.b == 52 || foo2() == 25) ++ res = foo (data.y.b); ++ ++ return res; ++} ++ ++/* { dg-final { scan-tree-dump-times "Recognized necessary condition pair:" 1 "if-split" } } */ ++/* { dg-final { scan-tree-dump "Successfully transformed:" "if-split" } } */ +\ No newline at end of file +diff --git a/gcc/timevar.def b/gcc/timevar.def +index 6fdb2c767..b0d3d1188 100644 +--- a/gcc/timevar.def ++++ b/gcc/timevar.def +@@ -306,6 +306,7 @@ DEFTIMEVAR (TV_VAR_TRACKING_DATAFLOW , "var-tracking dataflow") + DEFTIMEVAR (TV_VAR_TRACKING_EMIT , "var-tracking emit") + DEFTIMEVAR (TV_TREE_IFCOMBINE , "tree if-combine") + DEFTIMEVAR (TV_TREE_IF_TO_SWITCH , "if to switch conversion") ++DEFTIMEVAR (TV_TREE_IF_SPLIT , "gimple if splitting") + DEFTIMEVAR (TV_TREE_UNINIT , "uninit var analysis") + DEFTIMEVAR (TV_PLUGIN_INIT , "plugin initialization") + DEFTIMEVAR (TV_PLUGIN_RUN , "plugin execution") +diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h +index cb67cdf87..bfe44c073 100644 +--- a/gcc/tree-cfg.h ++++ b/gcc/tree-cfg.h +@@ -112,6 +112,8 @@ extern basic_block gimple_switch_default_bb (function *, gswitch *); + extern edge gimple_switch_edge (function *, gswitch *, unsigned); + extern edge gimple_switch_default_edge (function *, gswitch *); + extern bool cond_only_block_p (basic_block); ++extern bool recognize_if_then_else (basic_block, basic_block *, basic_block *); ++extern bool same_phi_args_p (basic_block, basic_block, basic_block); + + /* Return true if the LHS of a call should be removed. */ + +diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h +index f9c2eed8b..fb17b189c 100644 +--- a/gcc/tree-pass.h ++++ b/gcc/tree-pass.h +@@ -383,6 +383,7 @@ extern gimple_opt_pass *make_pass_graphite (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_graphite_transforms (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_if_conversion (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_if_to_switch (gcc::context *ctxt); ++extern gimple_opt_pass *make_pass_if_split (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_loop_distribution (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_vectorize (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_simduid_cleanup (gcc::context *ctxt); +diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc +index 264a8bcae..3b50fc114 100644 +--- a/gcc/tree-ssa-ifcombine.cc ++++ b/gcc/tree-ssa-ifcombine.cc +@@ -76,8 +76,7 @@ along with GCC; see the file COPYING3. If not see + match the then and else basic-blocks to make the pattern match. + Returns true if the pattern matched, false otherwise. */ + +-static bool +-recognize_if_then_else (basic_block cond_bb, ++bool recognize_if_then_else (basic_block cond_bb, + basic_block *then_bb, basic_block *else_bb) + { + edge t, e; +@@ -168,8 +167,7 @@ forwarder_block_to (basic_block bb, basic_block to_bb) + BB2 to DEST are the same. This makes the CFG merge point + free from side-effects. Return true in this case, else false. */ + +-static bool +-same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest) ++bool same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest) + { + edge e1 = find_edge (bb1, dest); + edge e2 = find_edge (bb2, dest); +-- +2.25.1 + diff --git a/0312-Add-late-slp-vectorization-pass-with-additional-chec.patch b/0312-Add-late-slp-vectorization-pass-with-additional-chec.patch new file mode 100644 index 0000000000000000000000000000000000000000..19e519f614622d61953da3eb4653d979248cdafd --- /dev/null +++ b/0312-Add-late-slp-vectorization-pass-with-additional-chec.patch @@ -0,0 +1,320 @@ +From 9df4a0bd76299734ae47f2f4e236b10f6c156994 Mon Sep 17 00:00:00 2001 +From: d84370931 +Date: Thu, 14 Nov 2024 17:08:40 +0800 +Subject: [PATCH 3/8] Add late slp vectorization pass with additional checks. + +Add expansion of data reference offset using affine trees to check +if data references may alias. + +Add check if a group of interleaving data references is smaller than +max vector register size. + +Add operands swap for commutative operations. +Swapping operands is necessary for better vector constructing. +For example for operations + _1 = a * b; + _2 = b * c; +Construction vectors (a, c) * (b, b) is more profitable +than (a, b) * (b, c). + +Add tests and special param flags for each check: + --param=vect-addr-expand-for-alias-check={0,1} + --param=vect-swap-operands={0,1} + --param=vect-register-size-check={0,1} + +Add enabling flag for late slp pass: + -ftree-slp-late +--- + gcc/common.opt | 4 ++ + gcc/params.opt | 12 ++++++ + gcc/passes.def | 4 ++ + gcc/testsuite/gcc.dg/vect/vect-alias-expand.c | 12 ++++++ + gcc/testsuite/gcc.dg/vect/vect-op-swap.c | 10 +++++ + gcc/testsuite/gcc.dg/vect/vect-regsize.c | 18 +++++++++ + gcc/timevar.def | 1 + + gcc/tree-data-ref.cc | 12 ++++++ + gcc/tree-pass.h | 1 + + gcc/tree-vect-data-refs.cc | 15 +++++++ + gcc/tree-vect-slp.cc | 28 +++++++++++++ + gcc/tree-vectorizer.cc | 39 +++++++++++++++++++ + 12 files changed, 156 insertions(+) + create mode 100644 gcc/testsuite/gcc.dg/vect/vect-alias-expand.c + create mode 100644 gcc/testsuite/gcc.dg/vect/vect-op-swap.c + create mode 100644 gcc/testsuite/gcc.dg/vect/vect-regsize.c + +diff --git a/gcc/common.opt b/gcc/common.opt +index 78cfc333a..c3c64ceaf 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -3268,6 +3268,10 @@ ftree-slp-transpose-vectorize + Common Var(flag_tree_slp_transpose_vectorize) Optimization Init(0) + Enable basic block vectorization (SLP) for transposed stores and loads on trees. + ++ftree-slp-late ++Common Var(flag_slp_late) Init(0) Optimization ++Enable additional SLP vectorization pass after reassociation. ++ + fvect-cost-model= + Common Joined RejectNegative Enum(vect_cost_model) Var(flag_vect_cost_model) Init(VECT_COST_MODEL_DEFAULT) Optimization + -fvect-cost-model=[unlimited|dynamic|cheap|very-cheap] Specifies the cost model for vectorization. +diff --git a/gcc/params.opt b/gcc/params.opt +index 3ddfaf5b2..bb4dc1825 100644 +--- a/gcc/params.opt ++++ b/gcc/params.opt +@@ -1213,6 +1213,18 @@ The maximum factor which the loop vectorizer applies to the cost of statements i + Common Joined UInteger Var(param_vect_induction_float) Init(1) IntegerRange(0, 1) Param Optimization + Enable loop vectorization of floating point inductions. + ++-param=vect-swap-operands= ++Common Joined UInteger Var(param_vect_swap_operands) Init(0) IntegerRange(0, 1) Param Optimization ++Enable swapping operands for commutative operations in vectorization analysis. ++ ++-param=addr-expand-for-alias-check= ++Common Joined UInteger Var(param_addr_expand_for_alias_check) Init(0) IntegerRange(0, 1) Param Optimization ++Enable data reference address expansion for alias check. ++ ++-param=vect-register-size-check= ++Common Joined UInteger Var(param_vect_register_size_check) Init(0) IntegerRange(0, 1) Param Optimization ++Enable checking if a group of interleaving data references may not fit in vector register. ++ + -param=vrp1-mode= + Common Joined Var(param_vrp1_mode) Enum(vrp_mode) Init(VRP_MODE_VRP) Param Optimization + --param=vrp1-mode=[vrp|ranger] Specifies the mode VRP1 should operate in. +diff --git a/gcc/passes.def b/gcc/passes.def +index e945af96a..529cc5093 100644 +--- a/gcc/passes.def ++++ b/gcc/passes.def +@@ -337,6 +337,10 @@ along with GCC; see the file COPYING3. If not see + NEXT_PASS (pass_lower_switch); + NEXT_PASS (pass_cse_reciprocals); + NEXT_PASS (pass_reassoc, false /* early_p */); ++ NEXT_PASS (pass_slp_vectorize_late); ++ PUSH_INSERT_PASSES_WITHIN (pass_slp_vectorize_late) ++ NEXT_PASS (pass_slp_vectorize); ++ POP_INSERT_PASSES () + NEXT_PASS (pass_strength_reduction); + NEXT_PASS (pass_split_paths); + NEXT_PASS (pass_tracer); +diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-expand.c b/gcc/testsuite/gcc.dg/vect/vect-alias-expand.c +new file mode 100644 +index 000000000..a68f4baf8 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/vect-alias-expand.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -ftree-vectorize --param=addr-expand-for-alias-check=1 -fdump-tree-slp-details" } */ ++ ++extern float arr[2][2]; ++ ++void foo (int i, int j, float a, float b) ++{ ++ arr[i][j] *= a; ++ arr[i][j+1] *= b; ++} ++ ++/* { dg-final { scan-tree-dump "Basic block will be vectorized using SLP" "slp2" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/vect-op-swap.c b/gcc/testsuite/gcc.dg/vect/vect-op-swap.c +new file mode 100644 +index 000000000..4872dc414 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/vect-op-swap.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -ftree-vectorize --param=vect-swap-operands=1 -fdump-tree-slp-details" } */ ++ ++void foo (float *res, float a, float b, float c) ++{ ++ res[0] = a * b; ++ res[1] = b * c; ++} ++ ++/* { dg-final { scan-tree-dump "Swapped operands for" "slp2" } } */ +diff --git a/gcc/testsuite/gcc.dg/vect/vect-regsize.c b/gcc/testsuite/gcc.dg/vect/vect-regsize.c +new file mode 100644 +index 000000000..bcd81e6df +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/vect/vect-regsize.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -ftree-vectorize --param=vect-register-size-check=1 -fdump-tree-slp-details" } */ ++ ++extern float arr[256][256][1024]; ++ ++void foo (int i, int j, float a, float b) ++{ ++ arr[i][j][0] += a; ++ arr[i][j][1] += b; ++ arr[i][j+1][0] += a; ++ arr[i][j+1][1] += b; ++ arr[i+1][j][0] += a; ++ arr[i+1][j][1] += b; ++ arr[i+1][j+1][0] += a; ++ arr[i+1][j+1][1] += b; ++} ++ ++/* { dg-final { scan-tree-dump "Basic block will be vectorized using SLP" "slp2" } } */ +diff --git a/gcc/timevar.def b/gcc/timevar.def +index fc2b1e1e7..7560e930a 100644 +--- a/gcc/timevar.def ++++ b/gcc/timevar.def +@@ -205,6 +205,7 @@ DEFTIMEVAR (TV_SCALAR_CLEANUP , "scalar cleanup") + DEFTIMEVAR (TV_TREE_PARALLELIZE_LOOPS, "tree parallelize loops") + DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization") + DEFTIMEVAR (TV_TREE_SLP_VECTORIZATION, "tree slp vectorization") ++DEFTIMEVAR (TV_TREE_LATE_SLP , "late slp vectorization") + DEFTIMEVAR (TV_GRAPHITE , "Graphite") + DEFTIMEVAR (TV_GRAPHITE_TRANSFORMS , "Graphite loop transforms") + DEFTIMEVAR (TV_GRAPHITE_DATA_DEPS , "Graphite data dep analysis") +diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc +index a05073c51..5eb4ac102 100644 +--- a/gcc/tree-data-ref.cc ++++ b/gcc/tree-data-ref.cc +@@ -3021,6 +3021,18 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, + get_inner_reference_aff (DR_REF (b), &off2, &size2); + aff_combination_scale (&off1, -1); + aff_combination_add (&off2, &off1); ++ ++ if (param_addr_expand_for_alias_check) ++ { ++ using tree_expand_map_t = hash_map; ++ /* Cache used by aff_combination_expand. */ ++ tree_expand_map_t *cache = NULL; ++ ++ if (off2.n) ++ aff_combination_expand (&off2, &cache); ++ free_affine_expand_cache (&cache); ++ } ++ + if (aff_comb_cannot_overlap_p (&off2, size1, size2)) + return false; + } +diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h +index 18b0f8022..2ed79f353 100644 +--- a/gcc/tree-pass.h ++++ b/gcc/tree-pass.h +@@ -390,6 +390,7 @@ extern gimple_opt_pass *make_pass_slp_vectorize (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_complete_unroll (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_complete_unrolli (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_pre_slp_scalar_cleanup (gcc::context *ctxt); ++extern gimple_opt_pass *make_pass_slp_vectorize_late (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_parallelize_loops (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_loop_prefetch (gcc::context *ctxt); + extern gimple_opt_pass *make_pass_iv_optimize (gcc::context *ctxt); +diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc +index aae7f62f3..ee58c8f6c 100644 +--- a/gcc/tree-vect-data-refs.cc ++++ b/gcc/tree-vect-data-refs.cc +@@ -3234,6 +3234,21 @@ vect_analyze_data_ref_accesses (vec_info *vinfo, + != type_size_a)) + break; + ++ if (param_vect_register_size_check) ++ { ++ tree scalar_type = TREE_TYPE (DR_REF (dra)); ++ tree vec_type = get_related_vectype_for_scalar_type ( ++ vinfo->vector_mode, scalar_type); ++ poly_uint64 vec_size = TYPE_VECTOR_SUBPARTS (vec_type); ++ ++ /* If we have a large interleaving group (especially a group ++ of loads with gaps) that does not fit in vector register, ++ we should split this group to chunks we support. */ ++ if (maybe_ge (((unsigned HOST_WIDE_INT)init_b - init_prev) ++ / type_size_a, vec_size)) ++ break; ++ } ++ + /* If the step (if not zero or non-constant) is smaller than the + difference between data-refs' inits this splits groups into + suitable sizes. */ +diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc +index fbd638333..79026fb5b 100644 +--- a/gcc/tree-vect-slp.cc ++++ b/gcc/tree-vect-slp.cc +@@ -687,6 +687,34 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char swap, + if (first) + return 0; + ++ /* If different statements in the group of commutative operations ++ have the same arguments but in different places, swap them to ++ group the same operands in one vector. ++ ++ Check if swapping is enabled, operation is commutative and has ++ two operands of the same type. ++ If one of the operands in current statement match the operand ++ on another place of the first statement in the group we ++ swap operands in current statement. */ ++ if (param_vect_swap_operands && commutative_op == 0 && !first ++ && is_a (vinfo) && number_of_oprnds == 2 ++ && vect_def_types_match (dts[0], dts[1])) ++ { ++ slp_oprnd_info oprnd_info0 = (*oprnds_info)[0]; ++ slp_oprnd_info oprnd_info1 = (*oprnds_info)[1]; ++ if (oprnd_info1->ops[stmt_num] == oprnd_info0->ops[0] ++ || oprnd_info0->ops[stmt_num] == oprnd_info1->ops[0]) ++ { ++ std::swap (oprnd_info0->def_stmts[stmt_num], ++ oprnd_info1->def_stmts[stmt_num]); ++ std::swap (oprnd_info0->ops[stmt_num], ++ oprnd_info1->ops[stmt_num]); ++ if (dump_enabled_p ()) ++ dump_printf_loc (MSG_NOTE, vect_location, ++ "Swapped operands for %G", stmt_info->stmt); ++ } ++ } ++ + /* Now match the operand definition types to that of the first stmt. */ + for (i = 0; i < number_of_oprnds;) + { +diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc +index a63fa3912..c363ce490 100644 +--- a/gcc/tree-vectorizer.cc ++++ b/gcc/tree-vectorizer.cc +@@ -1524,6 +1524,45 @@ make_pass_slp_vectorize (gcc::context *ctxt) + return new pass_slp_vectorize (ctxt); + } + ++/* The late SLP vectorization pass. */ ++ ++namespace { ++ ++const pass_data pass_data_slp_vectorize_late = ++{ ++ GIMPLE_PASS, /* type. */ ++ "slp_late", /* name. */ ++ OPTGROUP_NONE, /* optinfo_flags. */ ++ TV_TREE_LATE_SLP, /* tv_id. */ ++ PROP_cfg, /* properties_required. */ ++ 0, /* properties_provided. */ ++ 0, /* properties_destroyed. */ ++ 0, /* todo_flags_start. */ ++ 0, /* todo_flags_finish. */ ++}; ++ ++class pass_slp_vectorize_late : public gimple_opt_pass ++{ ++public: ++ pass_slp_vectorize_late (gcc::context *ctxt) ++ : gimple_opt_pass (pass_data_slp_vectorize_late, ctxt) ++ {} ++ ++ /* opt_pass methods: */ ++ virtual bool gate (function *) ++ { ++ return flag_slp_late != 0; ++ } ++ ++}; // class pass_slp_vectorize_late ++ ++} // anon namespace ++ ++gimple_opt_pass * ++make_pass_slp_vectorize_late (gcc::context *ctxt) ++{ ++ return new pass_slp_vectorize_late (ctxt); ++} + + /* Increase alignment of global arrays to improve vectorization potential. + TODO: +-- +2.33.0 + diff --git a/0313-Add-tracer-transformation-for-static-probabilities.patch b/0313-Add-tracer-transformation-for-static-probabilities.patch new file mode 100644 index 0000000000000000000000000000000000000000..53d233718de0f2c0015796ce14f49e9b1799840c --- /dev/null +++ b/0313-Add-tracer-transformation-for-static-probabilities.patch @@ -0,0 +1,130 @@ +From ed300a0b07e608efb756b623263f014c2cebdf08 Mon Sep 17 00:00:00 2001 +From: Egorov Ivan WX1280859 +Date: Tue, 26 Nov 2024 14:53:59 +0300 +Subject: [PATCH 6/8] Add tracer transformation for static probabilities + +--- + gcc/common.opt | 4 ++++ + gcc/opts.cc | 4 ++++ + gcc/params.opt | 8 ++++++++ + gcc/testsuite/gcc.dg/tracer-static-1.c | 28 ++++++++++++++++++++++++++ + gcc/tracer.cc | 11 ++++++++++ + 5 files changed, 55 insertions(+) + create mode 100644 gcc/testsuite/gcc.dg/tracer-static-1.c + +diff --git a/gcc/common.opt b/gcc/common.opt +index 96888cf1b..db35391c3 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -2990,6 +2990,10 @@ ftracer + Common Var(flag_tracer) Optimization + Perform superblock formation via tail duplication. + ++ftracer-static ++Common Var(flag_tracer_static) Init(0) Optimization ++Perform superblock formation via tail duplication for a given bb size. ++ + ftrampolines + Common Var(flag_trampolines) Init(0) + For targets that normally need trampolines for nested functions, always +diff --git a/gcc/opts.cc b/gcc/opts.cc +index 84dd8925a..34b84db8f 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -3180,6 +3180,10 @@ common_handle_option (struct gcc_options *opts, + } + break; + ++ case OPT_ftracer_static: ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_tracer, true); ++ break; ++ + case OPT_ftree_vectorize: + /* Automatically sets -ftree-loop-vectorize and + -ftree-slp-vectorize. Nothing more to do here. */ +diff --git a/gcc/params.opt b/gcc/params.opt +index bb4dc1825..e5472dfc8 100644 +--- a/gcc/params.opt ++++ b/gcc/params.opt +@@ -1116,6 +1116,10 @@ The percentage of function, weighted by execution frequency, that must be covere + Common Joined UInteger Var(param_tracer_max_code_growth) Init(100) Param Optimization + Maximal code growth caused by tail duplication (in percent). + ++-param=tracer-max-not-covered-insns-num= ++Common Joined UInteger Var(param_tracer_max_not_covered_insns_num) Init(12) Param Optimization ++Maximal number of instructions in the block, that must not be covered by trace formation. ++ + -param=tracer-min-branch-probability= + Common Joined UInteger Var(param_tracer_min_branch_probability) Init(50) IntegerRange(0, 100) Param Optimization + Stop forward growth if the probability of best edge is less than this threshold (in percent). Used when profile feedback is not available. +@@ -1128,6 +1132,10 @@ Stop forward growth if the probability of best edge is less than this threshold + Common Joined UInteger Var(param_tracer_min_branch_ratio) Init(10) IntegerRange(0, 100) Param Optimization + Stop reverse growth if the reverse probability of best edge is less than this threshold (in percent). + ++-param=tracer-min-not-covered-insns-num= ++Common Joined UInteger Var(param_tracer_min_not_covered_insns_num) Init(1) Param Optimization ++Minimal number of instructions in the block, that must not be covered by trace formation. ++ + -param=tree-reassoc-width= + Common Joined UInteger Var(param_tree_reassoc_width) Param Optimization + Set the maximum number of instructions executed in parallel in reassociated tree. If 0, use the target dependent heuristic. +diff --git a/gcc/testsuite/gcc.dg/tracer-static-1.c b/gcc/testsuite/gcc.dg/tracer-static-1.c +new file mode 100644 +index 000000000..76c863b48 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tracer-static-1.c +@@ -0,0 +1,28 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -ftracer-static -fdump-tree-tracer" } */ ++ ++static __attribute__ ((noinline)) int fib (int n) ++{ ++ if (n < 3) ++ return 0; ++ ++ long long fib1 = 0, fib2 = 1; ++ long long currentFib = 0; ++ ++ for (int i = 3; i <= n; ++i) ++ { ++ currentFib = fib1 + fib2; ++ fib1 = fib2; ++ fib2 = currentFib; ++ } ++ ++ return currentFib; ++} ++ ++int main (int argc, char** argv) ++{ ++ int n = argc; ++ return fib (n); ++} ++ ++/* { dg-final { scan-tree-dump-times "BB\\d+ with n = \\d+ will not be covered by tracer formation" 4 "tracer" } } */ +\ No newline at end of file +diff --git a/gcc/tracer.cc b/gcc/tracer.cc +index 4d054fe8f..9b1578cd4 100644 +--- a/gcc/tracer.cc ++++ b/gcc/tracer.cc +@@ -304,6 +304,17 @@ tail_duplicate (void) + { + int n; + analyze_bb (bb, &n); ++ ++ if (flag_tracer_static && n >= param_tracer_min_not_covered_insns_num ++ && n <= param_tracer_max_not_covered_insns_num) ++ { ++ if (dump_file) ++ fprintf (dump_file, ++ "BB%d with n = %d will not be covered by tracer formation\n", ++ bb->index, n); ++ continue; ++ } ++ + if (!ignore_bb_p (bb)) + blocks[bb->index] = heap.insert (-bb->count.to_frequency (cfun), bb); + +-- +2.33.0 + diff --git a/0314-bugfix-Modify-the-hip09-tune-flags.patch b/0314-bugfix-Modify-the-hip09-tune-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..180973129a9f1da8803c4145bceadd27377f199f --- /dev/null +++ b/0314-bugfix-Modify-the-hip09-tune-flags.patch @@ -0,0 +1,56 @@ +From e94bf3e1ad12211ec037c9e04a1698e1ed16c87a Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 3 Dec 2024 21:02:39 +0800 +Subject: [PATCH 8/8] [bugfix] Modify the hip09 tune flags. + +--- + gcc/config/aarch64/aarch64-tuning-flags.def | 3 +++ + gcc/config/aarch64/aarch64.cc | 11 +++++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64-tuning-flags.def b/gcc/config/aarch64/aarch64-tuning-flags.def +index b4a8f99a6..293f6fb7e 100644 +--- a/gcc/config/aarch64/aarch64-tuning-flags.def ++++ b/gcc/config/aarch64/aarch64-tuning-flags.def +@@ -49,6 +49,9 @@ AARCH64_EXTRA_TUNING_OPTION ("no_ldp_combine", NO_LDP_COMBINE) + + AARCH64_EXTRA_TUNING_OPTION ("rename_load_regs", RENAME_LOAD_REGS) + ++/* Prefer Advanced SIMD over SVE for auto-vectorization. */ ++AARCH64_EXTRA_TUNING_OPTION ("prefer_advsimd_autovec", PREFER_ADVSIMD_AUTOVEC) ++ + AARCH64_EXTRA_TUNING_OPTION ("cse_sve_vl_constants", CSE_SVE_VL_CONSTANTS) + + AARCH64_EXTRA_TUNING_OPTION ("use_new_vector_costs", USE_NEW_VECTOR_COSTS) +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 1d479f270..829e0da8f 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -1934,8 +1934,7 @@ static const struct tune_params hip09_tunings = + 2, /* min_div_recip_mul_df. */ + 0, /* max_case_values. */ + tune_params::AUTOPREFETCHER_WEAK, /* autoprefetcher_model. */ +- (AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS +- | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT), /* tune_flags. */ ++ (AARCH64_EXTRA_TUNE_PREFER_ADVSIMD_AUTOVEC), /* tune_flags. */ + &hip09_prefetch_tune + }; + +@@ -20250,6 +20249,14 @@ aarch64_override_options_internal (struct gcc_options *opts) + SET_OPTION_IF_UNSET (opts, &global_options_set, + param_sched_autopref_queue_depth, queue_depth); + ++ /* If the core wants only AdvancedSIMD autovectorization, do this through ++ aarch64_autovec_preference. If the user set it explicitly, they should ++ know what they want. */ ++ if (aarch64_tune_params.extra_tuning_flags ++ & AARCH64_EXTRA_TUNE_PREFER_ADVSIMD_AUTOVEC) ++ SET_OPTION_IF_UNSET (opts, &global_options_set, ++ aarch64_autovec_preference, 1); ++ + /* If using Advanced SIMD only for autovectorization disable SVE vector costs + comparison. */ + if (aarch64_autovec_preference == 1) +-- +2.33.0 + diff --git a/0315-Bugfix-Add-no-var-recored-check-for-ssa_name-in-stru.patch b/0315-Bugfix-Add-no-var-recored-check-for-ssa_name-in-stru.patch new file mode 100644 index 0000000000000000000000000000000000000000..befe1f6746a194fcd94e9a2779a3f46017f21991 --- /dev/null +++ b/0315-Bugfix-Add-no-var-recored-check-for-ssa_name-in-stru.patch @@ -0,0 +1,234 @@ +From 05bece3d79daa886a469b066061f0606ca6ebed8 Mon Sep 17 00:00:00 2001 +From: huang-xioaquan +Date: Mon, 2 Dec 2024 17:39:11 +0800 +Subject: [PATCH 2/5] [Bugfix] Add no var recored check for ssa_name in struct + reorg + +--- + gcc/ipa-struct-reorg/escapes.def | 1 + + gcc/ipa-struct-reorg/ipa-struct-reorg.cc | 44 ++++++ + .../gcc.dg/struct/rf_void_ptr_ssa_name.c | 125 ++++++++++++++++++ + 3 files changed, 170 insertions(+) + create mode 100644 gcc/testsuite/gcc.dg/struct/rf_void_ptr_ssa_name.c + +diff --git a/gcc/ipa-struct-reorg/escapes.def b/gcc/ipa-struct-reorg/escapes.def +index 996a09bac..4ba9cc2d0 100644 +--- a/gcc/ipa-struct-reorg/escapes.def ++++ b/gcc/ipa-struct-reorg/escapes.def +@@ -61,5 +61,6 @@ DEF_ESCAPE (escape_unhandled_rewrite, "Type escapes via a unhandled rewrite stmt + DEF_ESCAPE (escape_via_orig_escape, "Type escapes via a original escape type") + DEF_ESCAPE (escape_instance_field, "Type escapes via a field of instance") + DEF_ESCAPE (escape_via_empty_no_orig, "Type escapes via empty and no original") ++DEF_ESCAPE (escape_no_record_var, "Type escapes via no record var") + + #undef DEF_ESCAPE +diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.cc b/gcc/ipa-struct-reorg/ipa-struct-reorg.cc +index 1a169c635..b93b8a5b5 100644 +--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.cc ++++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.cc +@@ -1433,6 +1433,7 @@ public: + void propagate_escape_via_original (void); + void propagate_escape_via_empty_with_no_original (void); + void propagate_escape_via_ext_func_types (void); ++ void propagate_escape_via_no_record_var (void); + void analyze_types (void); + void clear_visited (void); + bool create_new_types (void); +@@ -4467,6 +4468,13 @@ ipa_struct_reorg::check_type_and_push (tree newdecl, srdecl *decl, + } + /* At this point there should only be unkown void* ssa names. */ + gcc_assert (TREE_CODE (newdecl) == SSA_NAME); ++ tree inner = SSA_NAME_VAR (newdecl); ++ if (current_layout_opt_level >= STRUCT_REORDER_FIELDS && ++ inner && find_decl (inner) == NULL) ++ { ++ type->mark_escape (escape_no_record_var, stmt); ++ return; ++ } + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\nrecording unkown decl: "); +@@ -5512,6 +5520,41 @@ ipa_struct_reorg::propagate_escape_via_ext_func_types (void) + } + } + ++/* Escape propagation is performed on ssa_name decl that no record var in ++ decls. */ ++ ++void ++ipa_struct_reorg::propagate_escape_via_no_record_var (void) ++{ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n propagate_escape_via_no_record_var: \n\n"); ++ ++ for (unsigned i = 0; i < functions.length (); i++) ++ { ++ if (functions[i]->node) ++ set_cfun (DECL_STRUCT_FUNCTION (functions[i]->node->decl)); ++ ++ for (unsigned j = 0; j < functions[i]->decls.length (); j++) ++ { ++ srdecl *decl = functions[i]->decls[j]; ++ srtype *type = decl->type; ++ ++ if (TREE_CODE (decl->decl) == SSA_NAME) ++ { ++ tree inner = SSA_NAME_VAR (decl->decl); ++ ++ if (inner && functions[i]->find_decl (inner) == NULL) ++ type->mark_escape (escape_no_record_var, NULL); ++ } ++ } ++ ++ set_cfun (NULL); ++ } ++ ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "\n end propagate_escape_via_no_record_var \n\n"); ++} ++ + /* Prune the escaped types and their decls from what was recorded. */ + + void +@@ -5530,6 +5573,7 @@ ipa_struct_reorg::prune_escaped_types (void) + propagate_escape_via_original (); + propagate_escape_via_empty_with_no_original (); + propagate_escape_via_ext_func_types (); ++ propagate_escape_via_no_record_var (); + } + + if (dump_file && (dump_flags & TDF_DETAILS)) +diff --git a/gcc/testsuite/gcc.dg/struct/rf_void_ptr_ssa_name.c b/gcc/testsuite/gcc.dg/struct/rf_void_ptr_ssa_name.c +new file mode 100644 +index 000000000..0f624b6b9 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/struct/rf_void_ptr_ssa_name.c +@@ -0,0 +1,125 @@ ++// Add a void* ssa_name check and escape. ++/* { dg-do compile } */ ++ ++// includes ++#include "stdio.h" ++#include "stdlib.h" ++#include "time.h" ++#include "string.h" ++#include "limits.h" ++#include "float.h" ++ ++#define JOTAI_NUM_RANDS_ 25 ++ ++const unsigned rand_primes[JOTAI_NUM_RANDS_] = {179, 103, 479, 647, 229, 37, ++271, 557, 263, 607, 18743, 50359, 21929, 48757, 98179, 12907, 52937, 64579, ++49957, 52567, 507163, 149939, 412157, 680861, 757751}; ++ ++int next_i () ++{ ++ int counter = 0; ++ return rand_primes[(++counter)%JOTAI_NUM_RANDS_]; ++} ++ ++float next_f () ++{ ++ int counter = 0; ++ return rand_primes[(++counter)%JOTAI_NUM_RANDS_] / 757751.0F; ++} ++ ++// Usage menu ++void usage() ++{ ++ printf("%s", "Usage:\n\ ++ prog [ARGS]\n\ ++\nARGS:\n\ ++ 0 big-arr\n\ ++ 1 big-arr-10x\n\ ++ 2 empty\n\ ++\n\ ++"); ++} ++ ++// ------------------------------------------------------------------------- // ++ ++typedef unsigned long size_t; // Customize by platform. ++typedef long intptr_t; ++typedef unsigned long uintptr_t; ++typedef long scalar_t__; // Either arithmetic or pointer type. ++/* By default, we understand bool (as a convenience). */ ++typedef int bool; ++#define false 0 ++#define true 1 ++ ++/* Forward declarations */ ++ ++/* Type definitions */ ++typedef size_t u32 ; ++struct octeon_device {int octeon_id; } ; ++ ++/* Variables and functions */ ++ size_t MAX_OCTEON_DEVICES ; ++ struct octeon_device** octeon_device ; ++ ++int lio_get_device_id(void *dev) ++{ ++ struct octeon_device *octeon_dev = (struct octeon_device *)dev; ++ u32 i; ++ ++ for (i = 0; i < MAX_OCTEON_DEVICES; i++) ++ { ++ if (octeon_device[i] == octeon_dev) ++ return octeon_dev->octeon_id; ++ } ++ return -1; ++} ++ ++// ------------------------------------------------------------------------- // ++ ++int main(int argc, char *argv[]) ++{ ++ if (argc != 2) ++ { ++ usage(); ++ return 1; ++ } ++ ++ int opt = atoi(argv[1]); ++ switch(opt) ++ { ++ // big-arr ++ case 0: ++ { ++ void * dev; ++ int benchRet = lio_get_device_id(dev); ++ printf("%d\n", benchRet); ++ break; ++ } ++ ++ // big-arr-10x ++ case 1: ++ { ++ void * dev; ++ int benchRet = lio_get_device_id(dev); ++ printf("%d\n", benchRet); ++ break; ++ } ++ ++ // empty ++ case 2: ++ { ++ void * dev; ++ int benchRet = lio_get_device_id(dev); ++ printf("%d\n", benchRet); ++ break; ++ } ++ ++ default: ++ usage(); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* { dg-final { scan-ipa-dump "No structures to transform" "struct_reorg" } } */ +-- +2.33.0 + diff --git a/0316-Use-ai-ability-to-guide-optimization.patch b/0316-Use-ai-ability-to-guide-optimization.patch new file mode 100644 index 0000000000000000000000000000000000000000..40b97861fa9f30cf18b3ba656e0603001a4dc4ad --- /dev/null +++ b/0316-Use-ai-ability-to-guide-optimization.patch @@ -0,0 +1,741 @@ +From 0b85ab4639e2d25314175962a6e41a841649b028 Mon Sep 17 00:00:00 2001 +From: zhenyu zhao +Date: Sun, 24 Nov 2024 17:29:13 +0800 +Subject: [PATCH 3/5] Use ai ability to guide optimization. + +--- + gcc/Makefile.in | 8 +- + gcc/ai4c-infer.cc | 457 ++++++++++++++++++++++++++++++++++ + gcc/ai4c-infer.h | 29 +++ + gcc/config/aarch64/aarch64.cc | 14 +- + gcc/gcc.cc | 32 +++ + gcc/gcc.h | 1 + + gcc/ipa-hardware-detection.cc | 6 +- + gcc/onnx.fdata | 1 + + gcc/opts-global.cc | 10 + + 9 files changed, 550 insertions(+), 8 deletions(-) + create mode 100644 gcc/ai4c-infer.cc + create mode 100644 gcc/ai4c-infer.h + create mode 100644 gcc/onnx.fdata + +diff --git a/gcc/Makefile.in b/gcc/Makefile.in +index bb6197a8e..6315462aa 100644 +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -1734,13 +1734,13 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \ + pretty-print.o intl.o \ + sbitmap.o \ + vec.o input.o hash-table.o ggc-none.o memory-block.o \ +- selftest.o selftest-diagnostic.o sort.o ++ ai4c-infer.o selftest.o selftest-diagnostic.o sort.o + + # Objects in libcommon-target.a, used by drivers and by the core + # compiler and containing target-dependent code. + OBJS-libcommon-target = $(common_out_object_file) prefix.o \ + opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \ +- hash-table.o file-find.o spellcheck.o selftest.o opt-suggestions.o ++ hash-table.o file-find.o spellcheck.o ai4c-infer.o selftest.o opt-suggestions.o + + # This lists all host objects for the front ends. + ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS)) +@@ -2256,7 +2256,7 @@ gcc-nm.cc: gcc-ar.cc + cp $^ $@ + + COLLECT2_OBJS = collect2.o collect2-aix.o vec.o ggc-none.o \ +- collect-utils.o file-find.o hash-table.o selftest.o ++ collect-utils.o file-find.o hash-table.o ai4c-infer.o selftest.o + COLLECT2_LIBS = @COLLECT2_LIBS@ + collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) + # Don't try modifying collect2 (aka ld) in place--it might be linking this. +@@ -3720,6 +3720,8 @@ install-plugin: installdirs lang.install-plugin s-header-vars install-gengtype + + # Install the compiler executables built during cross compilation. + install-common: native lang.install-common installdirs ++ rm -f $(DESTDIR)$(libexecdir)/onnx.fdata ++ cp $(srcdir)/onnx.fdata $(DESTDIR)$(libexecsubdir)/onnx.fdata + for file in $(COMPILERS); do \ + if [ -f $$file ] ; then \ + rm -f $(DESTDIR)$(libexecsubdir)/$$file; \ +diff --git a/gcc/ai4c-infer.cc b/gcc/ai4c-infer.cc +new file mode 100644 +index 000000000..99f7a6b45 +--- /dev/null ++++ b/gcc/ai4c-infer.cc +@@ -0,0 +1,457 @@ ++/* Lightweight AI Inference Framework. ++ Copyright (C) 2024-2024 Free Software Foundation, Inc. ++This file is part of GCC. ++GCC is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 3, or (at your option) any later ++version. ++GCC is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "ai4c-infer.h" ++#include "config.h" ++#include "system.h" ++ ++#define M_MODE_SIZE 6 ++#define NATIVE_TUNE_SIZE 128 ++#define CATS_STRINGS_ROW 12 ++#define CATS_STRINGS_COL 65 ++#define OFFSET_ROW 6 ++#define SCALE_ROW 6 ++#define UNITY_ROW 1 ++#define COEFFICIENT_ROW 18 ++#define COEFFICIENT_COL 100 ++#define COEFFICIENT1_ROW 100 ++#define COEFFICIENT1_COL 1 ++#define INTERCEPTS_ROW 100 ++#define INTERCEPTS1_ROW 1 ++ ++/* Model info. */ ++static int64_t argv_hw1[M_MODE_SIZE]; ++static char native_tune[NATIVE_TUNE_SIZE]; ++ ++/* Intermediate computation results from the ONNX model. */ ++static char cats_strings[CATS_STRINGS_ROW][CATS_STRINGS_COL]; ++static float offset[OFFSET_ROW]; ++static float scale[SCALE_ROW]; ++static float unity[UNITY_ROW]; ++static float coefficient[COEFFICIENT_ROW][COEFFICIENT_COL]; ++static float coefficient1[COEFFICIENT1_ROW][COEFFICIENT1_COL]; ++static float intercepts[INTERCEPTS_ROW]; ++static float intercepts1[INTERCEPTS1_ROW]; ++ ++/* Model result. */ ++static int64_t initialized; ++static int64_t optimize_result; ++ ++void ++prepare_native_tune_str (const char *info) ++{ ++ gcc_assert (strlen (info) < NATIVE_TUNE_SIZE); ++ if (info) ++ strcpy (native_tune, info); ++ return; ++} ++ ++void ++set_cache_info (int prefetches, int l1_cache_size, ++ int l1_cache_line_size, int l2_cache_size, ++ int prefetch_latency, int prefetch_distance_factor) ++{ ++ gcc_assert (5 < M_MODE_SIZE); ++ argv_hw1[0] = prefetches; ++ argv_hw1[1] = l1_cache_size; ++ argv_hw1[2] = l1_cache_line_size; ++ argv_hw1[3] = l2_cache_size; ++ argv_hw1[4] = prefetch_latency; ++ argv_hw1[5] = prefetch_distance_factor; ++} ++ ++/* Read float from onnx.fdata. */ ++ ++float static ++read_float_from_file (FILE* file) ++{ ++ char hex_float[8]; ++ float result; ++ ++ if (!file) ++ { ++ perror ("Can not open file."); ++ return result; ++ } ++ ++ if (fscanf (file, "%8s", hex_float) != 1) ++ { ++ perror ("Can not read hex from onnx.fdata."); ++ return result; ++ } ++ ++ unsigned char bytes[4]; ++ for (int i = 0; i < 4; i++) ++ { ++ sscanf(hex_float + 2 * i, "%2hhx", &bytes[i]); ++ } ++ ++ memcpy(&result, bytes, sizeof(float)); ++ return result; ++} ++ ++/* To read model parameter information from onnx.fdata and store it into the ++ appropriate arrays. */ ++ ++static void ++fill_node (const char *file_name) ++{ ++ FILE *file = fopen (file_name, "rb"); ++ ++ if (!file) ++ { ++ perror ("Can not open file."); ++ return; ++ } ++ ++ /* Read cats_strings from onnx.fdata. */ ++ char hex_string[2]; ++ for (int i = 0; i < CATS_STRINGS_ROW; i++) ++ { ++ for (int j = 0; j < CATS_STRINGS_COL - 1; j++) ++ { ++ if (fscanf(file, "%2s", hex_string) != 1) ++ { ++ perror ("Can not read cats_strings from onnx.fdata."); ++ return; ++ } ++ cats_strings[i][j] = (unsigned char)strtol(hex_string, NULL, 16); ++ } ++ cats_strings[i][CATS_STRINGS_COL - 1] = '\0'; ++ } ++ ++ /* Read offset from onnx.fdata. */ ++ for (int i = 0; i < OFFSET_ROW; i++) ++ { ++ float result = read_float_from_file (file); ++ offset[i] = result; ++ } ++ ++ /* Read scale from onnx.fdata. */ ++ for (int i = 0; i < SCALE_ROW; i++) ++ { ++ float result = read_float_from_file (file); ++ scale[i] = result; ++ } ++ ++ /* Read coefficient from onnx.fdata. */ ++ for (int i = 0; i < COEFFICIENT_ROW; i++) ++ for (int j = 0; j < COEFFICIENT_COL; j++) ++ { ++ float result = read_float_from_file (file); ++ coefficient[i][j] = result; ++ } ++ ++ /* Read coefficient1 from onnx.fdata. */ ++ for (int i = 0; i < COEFFICIENT1_ROW; i++) ++ for (int j = 0; j < COEFFICIENT1_COL; j++) ++ { ++ float result = read_float_from_file (file); ++ coefficient1[i][j] = result; ++ } ++ ++ /* Read intercepts from onnx.fdata. */ ++ for (int i = 0; i < INTERCEPTS_ROW; i++) ++ { ++ float result = read_float_from_file (file); ++ intercepts[i] = result; ++ } ++ ++ /* Read intercepts1 from onnx.fdata. */ ++ for (int i = 0; i < INTERCEPTS1_ROW; i++) ++ { ++ float result = read_float_from_file (file); ++ intercepts1[i] = result; ++ } ++ ++ /* Read unity from onnx.fdata. */ ++ for (int i = 0; i < UNITY_ROW; i++) ++ { ++ float result = read_float_from_file (file); ++ unity[i] = result; ++ } ++ ++ fclose (file); ++ return; ++} ++ ++static void ++matmul (const float *lhs, const float *rhs, int m, int k, int n, float *out) ++{ ++ for (int i = 0; i < m; i++) ++ { ++ for (int j = 0; j < n; j++) ++ { ++ out[i * n + j] = 0.0f; ++ for (int p = 0; p < k; p++) ++ { ++ out[i * n + j] += lhs[i * k + p] * rhs[p * n + j]; ++ } ++ } ++ } ++} ++ ++static void ++add (const float *lhs, const float *rhs, int length, float *out) ++{ ++ for (int i = 0; i < length; i++) ++ { ++ out[i] = lhs[i] + rhs[i]; ++ } ++} ++ ++static void ++sub (const float *lhs, const float *rhs, int length, float *out) ++{ ++ for (int i = 0; i < length; i++) ++ { ++ out[i] = lhs[i] - rhs[i]; ++ } ++} ++ ++static void ++sigmoid (const float *in, int length, float *out) ++{ ++ for (int i = 0; i < length; i++) ++ { ++ out[i] = 1.0f / (1.0f + expf (-in[i])); ++ } ++} ++ ++static void ++relu (const float *data, int length, float *out) ++{ ++ for (int i = 0; i < length; i++) ++ { ++ if (data[i] < 0) ++ { ++ out[i] = 0; ++ } ++ else ++ { ++ out[i] = data[i]; ++ } ++ } ++} ++ ++static void ++line_concat (const float *in, int in_size, float *out, int out_size) ++{ ++ for (int i = 0; i < in_size; i++) ++ out[out_size + i] = in[i]; ++} ++ ++static void ++one_hot_encoder (const char *in, const char (*cats)[65], float *out, ++ int out_size) ++{ ++ for (int i = 0; i < out_size; i++) ++ { ++ if (i < out_size && strcmp (cats[i], in) == 0) ++ { ++ out[i] = 1.0f; ++ } ++ else ++ { ++ out[i] = 0.0f; ++ } ++ } ++} ++ ++static void ++imputer (const int64_t *in, int size, float *out) ++{ ++ for (int i = 0; i < size; i++) ++ out[i] = in[i] * 1.0f; ++} ++ ++static void ++scaler (const float *in, const float *offset, const float *scale, int size, ++ float *out) ++{ ++ for (int i = 0; i < size; i++) ++ out[i] = (in[i] - offset[i]) * scale[i]; ++} ++ ++static int ++argmax (const float *in, int in_size) ++{ ++ int out_idx = 0; ++ for (int i = 0; i < in_size; i++) ++ { ++ if (in[i] > in[out_idx]) ++ out_idx = i; ++ } ++ return out_idx; ++} ++ ++static void ++preprocess (int argc, int64_t *argv, int64_t *in_modes) ++{ ++ int default_int_val= 0; ++ for (int i = 0; i < argc && i < M_MODE_SIZE; i++) ++ { ++ if (i < argc) ++ { ++ in_modes[i] = argv[i]; ++ } ++ else ++ { ++ in_modes[i] = default_int_val; ++ } ++ } ++} ++ ++/* The process of model inference. */ ++static int ++graph_infer (int argc, const char *argv, int argc2, int64_t *argv2) ++{ ++ const char *file_name = getenv ("GCC_AI4C_ONNX_FDATA"); ++ ++ if (access (file_name, F_OK) == 0) ++ { ++ fill_node (file_name); ++ } ++ else ++ { ++ return 0; ++ } ++ ++ int64_t in_modes[M_MODE_SIZE]; ++ ++ preprocess (argc2, argv2, in_modes); ++ ++ /* concat_result and encoder_out are intermediate computation results from ++ the ONNX model. concat_result is a 1 × 18 matrix, and encoder_out is a ++ 1 × 12 matrix. */ ++ ++ const int concat_out_size = 18; ++ float concat_result[concat_out_size]; ++ const int encoder_out_size = 12; ++ float encoder_out[encoder_out_size]; ++ ++ one_hot_encoder (argv, cats_strings, encoder_out, encoder_out_size); ++ ++ line_concat (encoder_out, encoder_out_size, concat_result, 0); ++ ++ float variable[M_MODE_SIZE]; ++ imputer (in_modes, M_MODE_SIZE, variable); ++ ++ float variable1[M_MODE_SIZE]; ++ scaler (variable, offset, scale, M_MODE_SIZE, variable1); ++ float transformed_column[concat_out_size + M_MODE_SIZE]; ++ line_concat (variable1, M_MODE_SIZE, transformed_column, 0); ++ line_concat (concat_result, concat_out_size, transformed_column, 6); ++ ++ /* This requires performing matrix multiplication between a 1 × 18 matrix ++ and an 18 × 100 matrix */ ++ ++ const int m = 1, k = 18, n = 100; ++ float mul_result[n]; ++ matmul (transformed_column, coefficient[0], m, k, n, mul_result); ++ ++ float add_result[n]; ++ add (mul_result, intercepts, n, add_result); ++ ++ float next_activations[n]; ++ relu (add_result, n, next_activations); ++ ++ /* This requires performing matrix multiplication between a 1 × 100 matrix ++ and an 100 × 1 matrix */ ++ ++ const int m2 = 1, k2 = 100, n2 = 1; ++ float mul_result1[n2]; ++ matmul (next_activations, coefficient1[0], m2, k2, n2, mul_result1); ++ ++ float add_result1[n2]; ++ add (mul_result1, intercepts1, n2, add_result1); ++ ++ float out_activations_result[n2]; ++ sigmoid (add_result1, n2, out_activations_result); ++ ++ float negative_class_proba[n2]; ++ sub (unity, out_activations_result, n2, negative_class_proba); ++ const int prob_size = n2 + n2; ++ float probabilities[prob_size]; ++ line_concat (negative_class_proba, n2, probabilities, 0); ++ line_concat (out_activations_result, n2, probabilities, n2); ++ ++ int argmax_output = argmax (probabilities, prob_size); ++ return argmax_output; ++} ++ ++void execute_sha256 (const char *input, char *output, size_t output_size) ++{ ++ char command[256]; ++ snprintf (command, sizeof (command), "echo -n \"%s\" | sha256sum", input); ++ ++ FILE *pipe = popen (command, "r"); ++ if (pipe == NULL) ++ { ++ perror ("Failed to run command."); ++ return; ++ } ++ ++ fgets (output, output_size, pipe); ++ pclose (pipe); ++} ++ ++int ++get_optimize_decision_from_ai4c () ++{ ++ if (initialized== 1) ++ { ++ return optimize_result; ++ } ++ if (native_tune && (strchr (native_tune, '+') != NULL)) ++ { ++ char hash[65]; ++ char input[64]; ++ const char prefix = '='; ++ const char *start = strchr (native_tune, prefix); ++ if (start) ++ { ++ start += 1; ++ const char *end = strchr (start, '+'); ++ if (!end) ++ { ++ end = native_tune + strlen (native_tune); ++ } ++ size_t len = end - start; ++ if (len >= sizeof (input)) ++ len = sizeof (input) - 1; ++ strncpy (input, start, len); ++ input[len] = '\0'; ++ } ++ else ++ input[0] = '\0'; ++ ++ execute_sha256 (input, hash, sizeof (hash)); ++ optimize_result = graph_infer (1, hash, M_MODE_SIZE, argv_hw1); ++ initialized = 1; ++ if (optimize_result == 1) ++ setenv ("AI_GUIDED", "1", 1); ++ } ++ return optimize_result; ++} +diff --git a/gcc/ai4c-infer.h b/gcc/ai4c-infer.h +new file mode 100644 +index 000000000..7fb75900b +--- /dev/null ++++ b/gcc/ai4c-infer.h +@@ -0,0 +1,29 @@ ++/* Lightweight AI Inference Framework. ++ ++ Copyright (C) 2024-2024 Free Software Foundation, Inc. ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify it under ++ the terms of the GNU General Public License as published by the Free ++ Software Foundation; either version 3, or (at your option) any later ++ version. ++ ++ GCC is distributed in the hope that it will be useful, but WITHOUT ANY ++ WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GCC; see the file COPYING3. If not see ++ . */ ++ ++#ifndef AI4C_INFER_H ++#define AI4C_INFER_H ++ ++extern int get_optimize_decision_from_ai4c (); ++extern void set_cache_info (int prefetches, int l1_cache_size, ++ int l1_cache_line_size, int l2_cache_size, ++ int prefetch_latency, int prefetch_distance_factor); ++extern void prepare_native_tune_str (const char *info); ++#endif /* AI4C_INFER_H */ +\ No newline at end of file +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 08a43541e..1d479f270 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -18764,12 +18764,14 @@ override_C_optimize_options (struct gcc_options *opts) + opts->x_flag_ipa_struct_reorg = 6; + opts->x_struct_layout_optimize_level = 6; + opts->x_flag_gnu89_inline = 1; +- opts->x_flag_ccmp2 = 1; +- opts->x_flag_array_widen_compare = 1; + opts->x_flag_convert_minmax = 1; + opts->x_flag_tree_slp_transpose_vectorize = 1; + opts->x_param_max_inline_insns_auto = 64; + opts->x_param_inline_unit_growth = 96; ++ opts->x_param_pointer_compression_size = 16; ++ opts->x_semi_relayout_level = 14; ++ opts->x_flag_ipa_prefetch = 1; ++ opts->x_flag_ipa_ic = 1; + } + + /* Check whether in CPP language or LTO with only CPP language. */ +@@ -18826,6 +18828,8 @@ override_optimize_options_1 (struct gcc_options *opts) + opts->x_param_ifcvt_allow_register_renaming = 2; + opts->x_param_max_rtl_if_conversion_unpredictable_cost = 48; + opts->x_param_max_rtl_if_conversion_predictable_cost = 48; ++ opts->x_flag_ccmp2 = 1; ++ opts->x_flag_array_widen_compare = 1; + } + + static void +@@ -18848,6 +18852,8 @@ override_Fortran_optimize_options (struct gcc_options *opts) + opts->x_flag_reorder_blocks = 1; + opts->x_flag_crypto_accel_aes = 1; + opts->x_param_flexible_seg_len = 1; ++ opts->x_flag_alias_analysis_expand_ssa = 1; ++ opts->x_flag_chrec_mul_fold_strict_overflow = 1; + } + + /* Reset the optimize option. +@@ -18857,7 +18863,9 @@ static void + reset_machine_option (struct gcc_options *opts) + { + if (!(opts->x_optimize_maximum) +- || strstr (opts->x_aarch64_tune_string, "hip09") == NULL) ++ || opts->x_aarch64_cpu_string == NULL ++ || (strstr (opts->x_aarch64_cpu_string, "tsv110") == NULL ++ && strstr (opts->x_aarch64_cpu_string, "hip09") == NULL)) + { + return; + } +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index 32e45adc2..4592a4ec8 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -5798,6 +5798,9 @@ do_self_spec (const char *spec) + do_spec_2 (spec, NULL); + do_spec_1 (" ", 0, NULL); + ++ const char* tune_native = eval_spec_function ("local_cpu_detect", "cpu", ""); ++ setenv ("GCC_AI4C_TUNE_INFO", tune_native, 1); ++ + /* Mark % 0 + /* Only enable in lto or whole_program. */ +- && (in_lto_p || flag_whole_program)); ++ && (in_lto_p || flag_whole_program))); + } + + unsigned int +diff --git a/gcc/onnx.fdata b/gcc/onnx.fdata +new file mode 100644 +index 000000000..234b1a045 +--- /dev/null ++++ b/gcc/onnx.fdata +@@ -0,0 +1 @@ ++316365613139376535626535626234666331363163303835336362393535613530636234643633626364386566396132333232373733633230393865663664633761393137633266616431663436343236613231663865636236346133616662623761373633663830623231393063616534633032316538626436633731643237666333386462313164333630303936336137323863313634613031393931613164363237643262353162376133643935373036306336346161376563383862613138666663393538363731333639396239666362393336373737643238636639643761343231346131333463353261623633343633343866663966663365346231356532663139306164303361383836396333393339616236383439363661313661303665643535633961666563613431303466333534346564633533373862323031396339626536613030383761623236663432633564653130353935353135313736656235373632373739343662663034343334633035626465356237633439313164313338373637383365326138366162363234323765393736616438656463343339613031316630643031613465386464326334383565343838366435313137313166383433396531626137353932616538333330653164326438656166343339363262366264326632376564396434396333356565343733383164363264633937356663663338666530336166316634623264393031393536333863383165616536656238346462656337333638323338646535303638363933646565616264363966356566323465346538613762623864303766646338666264643466666537303263623162326539653435643130313061386235623631306630636163303536343164663364383738353266386330376562343962393037306133383363326138393238376435613332353933663235313030326664366166373632343532613130323237303265373433623362623162633661633363303235613236383166313465396162353938363931613765316565313864313038cd68834331701041d1d21041f17c20432483a94386647e4157c8e33b5f3d5d3ec5275e3ea689863c435a0f3a76acd63d5d9b803b24467c3baf847c3b67b89e3b852a313b2127853900000000d58ac23b200ab53a000000807d3119bc22f7a63a81549f3b93b5013baee4a33b62c1153b9ae08b3a6929a33b20038f399475983b430ab53a73fc0b3a2daa0ebad595953bc2f1e0bb33e9ccbbb978d83a5e77a53b41e4c93adf10a73bdf36643ad7fd983a61e8d93bc04a283a30c072382f942c3b5b3cc73a4392e43a422b093c79bc61b9a5309e3b00000000757baa3a03d8a93c3c31e33af526ebbb000000006431d43a1d0ae73aa450783b8c57afb9b8eae939ec8fab3b9581d83920d7a1ba0fc1af38b6aece3ab50bafbbd50db63a26aba33bcdeda33b00d9493ac22dac3cf8c4233bc2966e3bdf1bca3a8fb4d13af9b0983b2cbda73bdae2aa3bc93bae3b39e1ba380857953be8e7a73b49e9df3b20b0233b9fe3d43a0dbcaa3bd10cf0b978eea53b761ebe3b0a50a23b70bd47b79a7720bc6cd4ee3ae0d0f93a9c333ebb5098dfbbbf8fa53b445efebac7b9993b6182b93aef267c3a4aa09e3b46d9a83b9f95983a379e913c6516123a1b2ebd3aaf943c3a0b90803becba92bce68f673be723253c5d7f813ad779613800000080af3c65ba6999743900000080957a003d82f2fe39baab4d3b7f348c39b8d3323b3c1e253ace952dbbc9d364bc3aafaf373d0a633be8fdee3968b0fa39eb70a83a7cba4e3bdf2407bc40f50f3d94f4c3b9a828573b3f2bc3b99a5763bcccb838bb24f011bae3400dbdc3074fba30a829bb3dde6e3ad7c2caba2b2aa7b8d479a7bbebe2603a7025583b00000000017414ba680386bc9b365e3aaacb03bc000000006afd90b9a64e263980eb223c80a48ebcca9703392310573b1fd419bbf7368abc17a2083a3ceafab95eb11cbcf29995b9a64264bc8bae403bc1dc6139631c88bc12e3373c07cf0c3cdc93a6b97edbc0b917754d3b5cdc143c61ef393b40a809baf3861dbbafce623be550513b828382bc359d513afa4a25ba31394c3bb013da3a9835553bf3d9553bec2b65bcee09bab9f6343e3c03a59f39fb11053a078e7cbc5bd006bcfe23363b08d12cbb3cfb533bb98a8fbadcb99139cbd1573b24725e3b01014fb6dcbc45ba6ee024bb318db1baf39ce9b952d625bc41afddb91d7dffbbc0ba163b0387b93b2594623b00000000f60cf9ba483c983b0000008015e6c6bcbd45983b77d62ebcfbb69f3b7b5752bcc334ab3b4f9806bc9d89063cc0675a3b807426bca81a9f3b7ef56f3b6a96a13a045937bcd4a2f33cb92173bc40af783b26ac40bc5fef6b3beba6fe3b8c7207bc5e25443bfd99a33be7e7403b4c2508bc0c87bb3bb95dcd3abe228b3bac03deb91a2ab03add753bbc000000002e04703be98f1fbccef2af3b17ebe93c0000000020e37a3b46ba913b1fd7003b1f3f133df85d423bacc843bc5fada7bbc8680d3d8423503b2afc6c3b4e43033dcfcc7c3bcece053cdbb44ebc4151823ba14426bc6e942c3b3bdc4d3a34967f3b7687783bd0cd3ebcfc75053ade324ebcd10c32bc9ff9fbbb0b7430bcf60e4abcd6b6e03b295db43b25c75d3b88334fbc8d95883ac9c73ebcddf941bc2b18083c43044c3b405414bd7617963b9910a03bd5e70c3d9356f23c3a2750bc472107bce47d47bc0125243b3c41953b0f6134bc8c403bbc8fb3873ba5e218bcae5d06bc2dfe103b758a493b43cef63cd7438d3c2bf1eb3b2d4a833cf13a43bc5d14c4bd000000002932a7bc3191e4bb00000080224e753dea87dfbb41e28a3cbeb44b3d731d8f3c1312d2bb54e44dbc232b84bc74f9d9bd033bcb3cdda410bbeeeb47bdd7e44e3b3c3e21bb435712bdb3e6413c82e770393f20a53cc6642dbc325484bc410c4e3dcb49823dc262bd3c204a563d032393bb0887753c0cad943d3946abbbcb77b3bc9151c6ba860dc0bd00000080e5880d3a2f960ebd1bba99bcce3910bd0000008037acde3be98a983bd60b7c3c66ee27bd2431aab98b2b95bded06813bc17429bdf5a9e9bc4ff297bafad924bdc14d53bc901784bcad96073cd34989bc84580fbd1e276b3ca48e513c189796bbe15f8cbb39fa473cce9c693cbdd0843a4f07443dbf40c03c38a1893c3790ab3cb48c58bcc5e9863b684448bcb5c32abc0726a6ba1def9ebb57ce273d772b84bc1925c63d2e26d8bc24460cbcb0f807bc8dd0a5bc9ba312bd6ed5393c32e1f43cf3c58bbc8a5334bc8e0c53bbf78cb13c7805793c8d5800bbc4a5c2bcfc2c85bba79d3c3df00f493db55cb73cce71c43dc030f03cc953823c79c1f13d614db73d0000000074e98f3ca415183c000000801104803d9afea83ddf9ff93d835f9bbce8d8623cd67e093c453d143d7d8c90bc1434e23d24580b3e00711d3c729b903d81a0253c82e9b53cba65123ca564a23d7a53003c2c82ec3de139f93c58f58ebce101813ba5782d3d4e198e3dbaa40fbb58e2bc3bbf92943c98421e3df32c0c3cbc235ebcc2fe443c2789033e00000080b94ca73be81815bd1758e53c5df7053b00000080f9f63f3cc7a9893cb846823c65d2143c9bb50e3cced60c3e92fb983b583593bbbbfe263e390bdf3b696887bbd13e823c207890bc1cf0c23cd688163dd14e16bdd3cb813c95a6593c70d7083cd6c6e43b6d4d9b3c9455683c876e1f3e599ff83c4b377f3c2afd953cbeedd43ccbdb163d2d78fd3bcc84363c5c7fa63c22fedf3c3318e83d0ecdba3d0ea690bc462e9a3d0b11013cf19f503da4f8813db249c0bba7300f3c2d6c223dd1d7663b56b4c43d56e5f93c4799e43b0702a73d4e15ae3de8040e3cdfad72bc0ab6593d1fb7c9bb6f90b43dbfcab83b4cd802bbbd3c993be1a91c3c8f677cbaa83420bb0000008084bf263b6336adba00000000373bd13b521cffba733ac83bee8c9bba1306f73bbf5471ba8651773bc863ac3a6ed119bb926fc43b9368e5ba34f319bba9c8ebbaa74acb3b39169ebc812d573b4764beba5815ea3b5211caba956ec23a9e107d3b64dbc4ba674ac73be88107bb5354493b688c5cbaaf4571bab3d6b3bae566603b11b0b0ba6bd1d03b000000005b6cc1ba0720833c5210c7ba85cd97bc000000003c1fc4bab35dbbba30b6fe3b389ea2bc97eb8eba37bae43b697a293b87969abc5c9e04bb83acc2ba5f8fadbcf872c5bab03daf3ad509fe3b2f81f9ba4317863cd808bb3b0177f03b02dabdbab2efbdba3b03d83bc09f223c6030ec3b0137c13b29f5663bf195ce3bc10eff3b18cda93b35486cba7dd7c8ba0d51003c34dc93ba891be33bb785ea3bbb75a73ae04f2abba21d8f3b9065c3ba8892bbbac37d96bc6a0c9dbc596cef3bce5a063bd64cec3be62fb0baaa5cbbba1acbd03b5cdfe13b0f37e9ba48bb653cc513733bc352a0bacba0ffba469ababdf17dae3c939271bd7af718be283c113ed15fbb3d00000080920e90badfa4d63d00000080df70d63c18f5c03dbbb677bde981e83d5a78d2bd0985093e663cffbd9a12803d3fc0b33d65b388bd50a0dd3d011acc3d2df0203ed04095bd5c9a8abd7294323dd404b33dabc5bdbd8042a33d93cb6f3d3b81f7bd4e2e823dfdba273d83ea863d7d0f3cbeaff2133e565a3d3d0d66ca3d035bea398af8073ec3b79abd00000000d078ad3dbe475c3c9267013e1db874bd000000809e1db03d23f9cb3d902b14be16ea52bdc41ac33db52abbbdf07981bed9442ebd4d94a83de0f7a93d745d41bd4cebb33d01f57c3da16adbbd8ae0b63d2d6c763cc1f40ebe098cbebddc59b83d256bb13d359fa9bdf886e5bd0dfcbbbdd68d0dbd726807be83579fbd05c9dcbdd8e8983ccd620d3edcf69f3dc980e8bdcb6c923e1cdcb3bdcc6ec1bde600823d030d993d9b3a1d3d420bcd3d754dde3df8132cbdfabb85bdce89c3bdefd054beafc6c8bd931e7c3d30fed83dbef795bd7fb1b3bd6d9eb73de344993cceb603bebd216b3de45c803d70a1953e1dfb62bea91d2a3ed284113f544008bfc50498be00000000d460e13b0d05b2be0000000066f28ebe9adb9ebe4ee6323efd01c7be63c7ac3e888dfabe44e5e23ec6f631bed07890beb0fe4a3e6217babee93daabecf501abfd1b9573e7bd53a3f805fe2be10a48cbecac09a3e52c67bbef48823be9a9dd83eb74340be75deeabd3fbf42be9d1c3c3f74e10abf923b05beaec4a4be66229fbbb35ff6be8a146c3e00000080638d84be04cb14be4dcfe7be53ec253f00000000208c89be7039a8bef1170c3f70ac0d3fdcd59bbe68f4973e6b1f903f16a3eb3e6d0a86be361a81be4cba023f82c88cbe01132ebea3feb73e79f391beeb6826be5130063fc4d9953e4a6690becd328abe13b7803efa6fc23e9823993efea5b83d60e0f43eff276c3ed453ba3e374b63bdd41502bf17e36dbe5034c53ea2ac9dbfff04903e64879e3e4c9d35bede8b6cbe435ed2be4e73abbe3020bfbef8c6e83e8630343ff9de9e3e78d65c3f3659a63eee6f35bed729b4be3954623ef8778f3ef4758fbe75fd4ebed9e3ed3e770a23be6b403ebed7e596bd656a093d6e463cbddfa103be2213f73d8a4c973d0000000050dc0bbb9d64b03d00000080d5e9283d3e429c3d1d0b3ebd35e5c03d101cacbd51b0e83dd890d5bd1378483dcc6a903d431d54bda0cab63d6376a63df1ab0a3e1a586bbd6bcfdbbd5cfb8d3db01a903dced598bdc300823d43fc3a3db75ccebdfea14a3d8f27fe3cf98c533de7d924bef762fc3df248103dde32a53d8d067e3a17bee53d5b6573bd00000080285b8b3d5cd0283d3447d93dd249c3bd00000000317f8d3db47da63df06ffebd933ca7bd3da29e3d0f9496bd7f1c6dbe2feb8abdd761863d8d3f883dc33d9abdecee903dd3ed453dc93cb4bd785f933d08c8393d5eb3f4bdef249bbd4ffb943d98be8e3d7b5487bd365bbebd103397bd19bdd2bcbc53e4bd9eb77cbd7d6fb5bdcc15713c4f00f03d54fc7e3d1c98c0bd05dd853e0dea8fbd5a2d9cbd35aa4b3d879a713df19b783d214da73d821bb73dc52889bdb707d4bdfd3d9ebdb6e53cbe1ee9a2bdc740443d3594b23de3046bbd4acb8fbdbf54943d23de5e3dbd36ddbddae5363d5155473de961aa3ed3a432be5d8e583e1d9a173f318110bfbc47aabe00000000a572363c9755c8be00000000c5235abe14fbb1be3f59573e57f8dbbe0adcc13e40d705bf1517f43eb1d467be07b3a2be40216f3eb6d9cfbe84b1bbbeba571cbf5c30843e96700c3f700eb6beee52a3bedcd6ab3eb39b93be9fd159be7524eb3efdd668beee2a1abe9dd171be0acf3d3f227e12bfbb312dbe3966bbbee3f99bbcec2f01bf2790883e0000008047ae9dbe59a438be26a4f9bedaf7f93e000000004b62a0bea849bdbe00ac123fa905d63e3e96b2bed43da93eef558d3f0c73b23e65bf96be67359abe8cc9c53e372ba4be184265becf66cb3edd11a7bed6d249be506f0d3f7429af3e0ba1a8bed2aca1becacc973e154ad73e9df5a93e53dd003e4cbd023fedc88d3e01e5cc3eff3eb3bd194d0abfa27090beb4a9d93ed0bf9dbf7c95a13e7bb5af3eb12a6bbeace488beb5419fbe86c8bebedea8d1beb735b03e6889073fb9f1b13e34835e3f7d7bb73ef8e961be08c5cabe6ff4833e956fa13e33e0a7befd926ebe6009fe3e8bc653be843b65be6a18a0bdd534f93c01fc52bd6b6f09be77e3fd3dc1c59f3d00000000e97d92bbf664b83d00000000972f193da896a43d65e754bd5e81c83d269cb4bd1d84ef3d1f11ddbd55385e3d020b993d4fdf69bd12a5be3ddd95ae3d62cb0d3e7ff87fbd7418c7bdf8ca803d1ed5983d13dea1bd480c8b3df3be503d2202d6bd540d5e3dc93e133d530d673d1b012bbe8f7c013eb79d243d9072ad3d772a273acfa6ec3d0ce383bd00000000fd56943de9119e3c0f64e03dd0cdb0bd00000080274f963deba6ae3d1c0a05be683297bd1f18a73d49b19fbdc64270be58657bbd263a8f3d374f913d63948bbda1b0993ddab55b3d7485bcbd00fc9b3df3edb03c892c00be9350a6bd25af9d3d968b973d79fe90bdeca4c9bdba46a0bddb1004bdbc84ebbde25788bd3ab0bdbda690963ccab6f63d60cc883d918ec8bd51ba873e9a3e99bdd01da5bde567613d50fd813d6981613d7163af3ddbdcbe3d473578bd8c07c0bd6924a7bd21c53fbe8ca6abbdaaf9573d158dba3d86c37fbd572399bd2a109d3d6994dc3c1e95e4bd4e1d4b3d7eca5a3d032771bdc8f5403d4b1a09bde53ceabdbfd4db3de573753d000000004909b9ba32b88f3d00000000c1c16c3d8b42803d994910bd8ba8a03dac6f8bbd482cca3db803b7bd3e900f3dbd44693d09b223bd2e39963db96c893d58fbf83dd2092ebd01b411be3149c43d891f633dd5b879bd93444b3d60e4033dfcc3aebd6c231b3de078bd3c57241d3dc16d17bed815e03d92dad63cc208853d82c1823a3acdc63d6d833ebd00000000ad06563de91bf63ca912bb3d854001be00000000941b5e3d5cd1873d744ce1bd91fce3bd57a17b3d804275bd64d465be11f8bdbdae6a583d0b73503dfc7bd1bd7155633d3e6a0c3db57194bd8eae6b3d6798093d58a9d7bdc3db71bdbd2b693d602c5f3d20c14fbd73e59cbdd53e77bdf28694bc1c71c5bd7f773ebd704a96bdd115383cf8ebd13df406403d27019fbde07f823eef7668bd4fcf7fbd6184123d9a113f3ddd37ad3dfe6a8a3dda459a3d3a30bbbdafb00cbe663c80bd0e3832be203886bdf262123d1972913df4a036bd978267bd99a5673d02f7283d6ae8bfbdd981033d3e82193df70172bdf1b33b3d2c8309bdf837ebbd4944dc3d875a763d000000001630b3baef2e903d000000008d6c663da8b4803d58ca10bd9221a13d74e08bbd7fa6ca3d338bb7bd700e103d71236a3dc13924bd00b2963d3de8893d2c6cf93d4ab12ebd894d11be9e58c13d81f0633dae8e7abd69054c3d5b51043d5d42afbdc1b21b3db199bd3cdab61d3d61aa17be7e84e03d2c57d73c907b853d18e27a3ac747c73d073e3fbd0000000013d0563d4ba4ec3cf98ebb3db3d400be0000000068ea5e3df445883d2b22e2bded78e2bd97817c3d232376bdb02f66becefebbbd053d593d6b38513d5d50cfbdab27643d1ce40c3d1ce994bdc0866c3dc167043d7161d8bd9abb72bd8c016a3ddcfa5f3d6e8650bdf66e9dbda51c78bd8b6494bc14dcc5bd07203fbd87b396bd8478363cab61d23dd8be403d137e9fbda19d833edb4969bdf35780bd9506133d4ac83f3d4157a93d2be18a3d44c19a3db553b9bd422c0cbe29ae80bd8b1f32be2ab086bd7fe6123d5ce9913d1b4c37bd253c68bdf37a683dda1d253d1866c0bd1fef033d630f1a3d55a78ebd9363e43c877813bdf06300be01e5f03d82788b3d00000000c3734fba035aa53d00000000e511873d7b68913d4e6e1cbd7718b73d813fa9bdcc68e13d5460cdbdbca5213daa5f843dade935bd383bac3d31919b3d2bf8073e69c848bd95ef2cbe5d65d83dba17833d49ee93bddd1f693de61c123dab7ac5bdd1dd2d3d5cf9643c6e50333d290923bebe38f63d2111e33cba73993d0a4b1c3aff26de3de00c5abd0000008092d2793d9b92fc3c1457d13de3451bbe00000080993e803dcd659b3d9082f7bd691808bef0f6913d51b390bdbab66cbe5acce9bda06e743dd62e733d250efbbd92ab833d46cc1d3d0c53b4bdea20873d8341113dbc72edbda26d8cbd369a873d164c813d395d75bdbe4ab3bd341392bd2d3f81bc05cadcbd939c5ebdc34eb6bd0175de3b5116e93d1b04603d00c2c2bda59a863e93b488bd09f997bda483253d75f4573dfd1ad83d23ed9c3d4bbfad3dc5f9e5bdf05c27be036399bd72e93bbe8204a0bd71d8243d7988a73d352350bdb95188bdcbd0863df73d3e3d0cbed5bd59aa133d40402b3d52f370bd85b63b3d0fd708bd723aeabdcdb1db3d87df743d000000806cedb3bad56b8f3d00000000d46d663d35e87f3d67e50fbd8859a03da22e8bbd43f6c93d37deb6bd811c0f3daeb1683d765223bdb9ef953d1c24893da7e7f83d15a22dbdd3ac11bee609c13d9f83623d703979bd21b74a3d7b7b033def92aebd70b81a3d730bbd3c5cbd1c3d0ecd17bef7f0df3d8140d63cd8b9843d1d757e3ac997c63d11023ebd00000000937d553d0e57ef3c0edaba3dc82f01be000000807c885d3ded82873d247ae1bd3436e3bd170e7b3d5ab774bd32eb68bef817bdbd6edc573ddbec4f3d4721d1bde3c1623d5ffa0b3df23994bd8a176b3d63e0053deec1d7bd7a5971bd5899683d57945e3d72434fbd92a59cbd4c9e76bde50b94bcc364c5bdab1a3ebd841a96bd88b5363cb8bbd13d548a3f3dd1e69ebd72ce833edbe867bd6f517fbda50d123dc88a3e3d8f2ba93dd51b8a3d83fc993d10a3babddc870cbe05e47fbdc04732be17f885bdfdfe113d7b27913dd82436bd100667bddb16673d808c263dbfbcbfbdfa2c033d6118193dc7b077bde7d4433ddcae0dbdc3a7efbd20dfe03dbb5f7c3d00000000603dbdbab68b933d00000080e852703d98cf833d651615bd4fbfa43dce3a8fbdd0edce3d2297bbbdfe4c143dbdf46f3de7d728bd892b9a3d092a8d3d635efe3dce9033bdcff113be186ac83d49a3693d124780bd8e56513d255a083d402eb3bde733203df262c43c6343223d04aa1abe2d29e53d0392de3cb1a9883d8ea7833ab384cb3d0e5744bd00000000d2555c3d8ed7f63caaa1bf3d462903be000000801f8e643d88808b3d81a9e6bd24a3e8bd4854813dee347cbdeafb6bbe1474c1bd62c75e3d92a6563d5559d5bda6e2693dbb14113dd06d98bd8065723d3e040a3d071cddbdc1d478bd83d76f3d8d9e653d47f855bde307a1bdaf257ebdce119abce91fcabd9f3a44bdee319abd37ff3e3ccecad63d6be6453d101fa3bd177f853e88256fbdab7483bd6e52173d12e6443da4ecaf3d32268e3d324b9e3d0603bfbd44ea0ebe44cb83bdad6235be57ee89bd933e173da14e953dd84a3cbd7c026ebd384d6e3d9d5f2b3de293c4bd3104083dbe891e3d97b16fbd8d903a3dc1e207bd7219eabdc854db3df7f4733d00000000e850b1ba61f98e3d000000005023653d9b007f3dc20d0fbd7beb9f3dfab88abdd293c93d1e74b6bdb4490e3d3bc7673d755122bd3e7e953d89af883dc493f83d8dbc2cbdcd0711be5457c03d389b613d165078bd9bcf493d41ae023d0226aebd2ddc193d9366bb3c94df1b3d008d17be2995df3d3dbcd43c3446843d9367763ad233c63da91b3dbd000000805b93543d7659ea3c8b72ba3d3a4100be00000080009f5c3dc40f873d922ce1bd32cce0bdcc237a3df4cb73bd988d68bef1ddbabdc7f2563d12034f3d497ccebd01d8613dde280b3d17c693bdf72d6a3dd434033d60b6d7bdb06b70bddbae673d96ab5d3d24584ebdc2339cbdb0b675bd189c92bc81e0c4bd3e2b3dbdbd8e95bd1ac1343c405bd13dbca23e3d396f9ebda2b7833e68ff66bd3d687ebd9a39113d03a53d3df37fa83d74a9893df58c993d4e6db8bdf6030cbedcfa7ebd142532be818285bd7426113d02b5903d4d4035bd28f265bdd02b663da385233d2056bfbd115b023db03c183db67f6bbd2238373dd9f904bd22b7e6bd6a08d83dee556f3d00000000ade0acba75698c3d00000000f81e613d4b3c7a3de7e50bbd952b9d3da23788bdd76dc63d2d7cb3bd59220b3d7e4f633d7cf91ebde1db923d2333863dd90ef53dfb1b29bd309d0fbe4f9dbd3d9c365d3d57a273bd67be453d2576ff3c0b43abbde685163d9d25b73c9e81183dc2bb15be5940dc3dd0c4cf3cd1d5813da770743ad315c33df03939bd00000080845d503d6a53e83ccd6fb73da62cfebd00000080394c583db596843d6201debd1f8fdfbd2971753d652e6fbd538966be80adb9bdc0b3523dd9e04a3ddf6dcdbdbf735d3d780f083d5d2a91bd6ead653d6e14023d8e3fd4bd8fda6bbd9f37633dc054593d64394abd3a8099bd5d0f71bd21308fbccde4c1bdbb5139bd100693bdb242303c8a24ce3d22bc3a3dc7bb9bbdb39e823e728962bd89a779bd5f050e3d61c0393db4f7a53d2828873d21de963dd6f4b6bd38820abe1b387abd071b30be521083bd6bf50d3d5f208e3d217c31bd92a961bd07ba613dbd25223d3f48bcbd38d9fe3c41ed143dd523d63e2f30a6be5ce7723ed5b3503f886143bf5a97d9be00000000c1361f3cccf6febe00000000c6a7ccbe1e6ae3be53717f3e548d0ebf056cf73e199933bf669a223feb077ebe93bfcebea700913e864805bf36c6f3be43625dbfe4309a3e1cd6843f05862bbfa03fc9be5676dd3e6810b4be955869be71381b3f575a89be84a727be4f278bbe140b873fb12947bf300e3ebed7eaebbe6f18e1bb9c9930bf87c0a83e00000080a1a9bdbe755354be942526bf6d1c6c3f0000008047d1c4be18e0f0be20e6483f35e1493fbe1adfbe1a73d93e563bcf3fc2fb273f6dc3bfbe63b5b8bec4753a3f2078c9be5a7578bef4c2033f06e3d0beea966dbe5368403f7778d63e0baccebe57bfc5be121fb83eee420b3f4424db3e763c033e51892f3ffbd8a83e686e053fdedaa1bd5d843abfda1faabe45450d3f5488eabf600cce3e4ce3e23ed6a181be523aa9be643b16bf1a7ff5be76e208bf7cdd253f4b25803f6a67e33e789a9e3fe61fee3e8b9781bea90601bfbac0a13ead42cd3e5d54cdbe8fe093be127f2a3fccd368be1ee887be106a0c3eeee1893e82029f3d5725303e5642663f3d48ee3e04d172bdd485bc3d3547ff3ebf8421bebc6bdd3e023dcb3e23feb53e08b1363fd7ad833e92133b3f3091903e0fafc13f51adf03e4b2e0c3e6612e43e92e1dd3e0d091e3fb063833e89ea713e2698003ff850313fb951543ede510b3feed7bd3ff97d843ee29fd73e0161653eeff1ad3e7755773e09023e3ffd34bd3ebdd90e3f0fa2503eee46033feb2b833eef03febd8727d83e8ae5a83f665d0a3f17b35d3ed825d5bba70bf43e5126033f1900253e8a569a3e88b7ba3e7c70703eb6557e3ec9ba7d3e7c13ae3e5830d03ecc7b683e5adeee3ec9c7b83f2190693e9937bc3e9a92b03f24c51b3e101df53d7e77e33eff50233fd3666b3edf57163eee32983e5416253eee1e513e11fe1f3ecdef4e3ef340053e45e4273f99bccd3eb76e623e886d9e3f8fbd5a3eb44f543e27dbc33fd1e4d63eea1a123f46521a3f75a2083fdbf8533e77cf6c3e0bdb8a3eec4fc83e2d98653ec5310c3f5ec9ea3e3bf2513e3fb13f3e7277c13edbe3bf3ea6c69e3ea869d03eee4ba73eb83d76be0000803f +\ No newline at end of file +diff --git a/gcc/opts-global.cc b/gcc/opts-global.cc +index a18c76940..e684bc5e3 100644 +--- a/gcc/opts-global.cc ++++ b/gcc/opts-global.cc +@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see + #include "attribs.h" + #include "asan.h" + #include "file-prefix-map.h" /* add_*_prefix_map() */ ++#include "ai4c-infer.h" + + typedef const char *const_char_p; /* For DEF_VEC_P. */ + +@@ -304,6 +305,15 @@ decode_options (struct gcc_options *opts, struct gcc_options *opts_set, + location_t loc, diagnostic_context *dc, + void (*target_option_override_hook) (void)) + { ++ set_cache_info (global_options.x_param_simultaneous_prefetches, ++ global_options.x_param_l1_cache_size, ++ global_options.x_param_l1_cache_line_size, ++ global_options.x_param_l2_cache_size, ++ global_options.x_param_prefetch_latency, ++ global_options.x_param_ipa_prefetch_distance_factor); ++ const char *tune_native = getenv ("GCC_AI4C_TUNE_INFO"); ++ prepare_native_tune_str (tune_native); ++ + struct cl_option_handlers handlers; + + unsigned int lang_mask; +-- +2.33.0 + diff --git a/0317-Bugfix-set-default-value-when-tune_native-is-NULL.patch b/0317-Bugfix-set-default-value-when-tune_native-is-NULL.patch new file mode 100644 index 0000000000000000000000000000000000000000..92f10c2bcd9ec686820fd45abe2bac6dda64bddc --- /dev/null +++ b/0317-Bugfix-set-default-value-when-tune_native-is-NULL.patch @@ -0,0 +1,27 @@ +From bc468838ffa1991e50cb4b82b45154d44302417b Mon Sep 17 00:00:00 2001 +From: zhenyu--zhao_admin +Date: Tue, 3 Dec 2024 22:39:36 +0800 +Subject: [PATCH 5/5] Bugfix: set default value when tune_native is NULL. + +--- + gcc/gcc.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index 0032735db..90f6dfe85 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -5800,6 +5800,10 @@ do_self_spec (const char *spec) + do_spec_1 (" ", 0, NULL); + + const char* tune_native = eval_spec_function ("local_cpu_detect", "cpu", ""); ++ if (tune_native == NULL) ++ { ++ tune_native = "native"; ++ } + setenv ("GCC_AI4C_TUNE_INFO", tune_native, 1); + + /* Mark % +Date: Wed, 11 Sep 2024 17:27:19 +0800 +Subject: [PATCH 4/5] add flag -flto-try enable LTO and automatically skip in + inapplicable situation. + +--- + gcc/collect2.cc | 51 ++++++++++++++++++++++++++++++++++++++++++- + gcc/common.opt | 8 +++++++ + gcc/opts-common.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++- + gcc/opts.cc | 20 +++++++++++++++++ + 4 files changed, 131 insertions(+), 2 deletions(-) + +diff --git a/gcc/collect2.cc b/gcc/collect2.cc +index 9715e8eee..690363880 100644 +--- a/gcc/collect2.cc ++++ b/gcc/collect2.cc +@@ -200,6 +200,7 @@ static enum lto_mode_d lto_mode = LTO_MODE_WHOPR; + #else + static enum lto_mode_d lto_mode = LTO_MODE_NONE; + #endif ++static bool maybe_relink_without_lto = false; + + bool helpflag; /* true if --help */ + +@@ -751,7 +752,53 @@ do_link (char **ld_argv, const char *atsuffix) + PEX_LAST | PEX_SEARCH, + HAVE_GNU_LD && at_file_supplied, atsuffix); + int ret = collect_wait (prog, pex); +- if (ret) ++ if (ret && maybe_relink_without_lto) ++ { ++ bool link_with_lto_plugin_before = false; ++ for (int i = 0, j = -1; ld_argv[i]; ++i) ++ { ++ if (endswith (ld_argv[i], "liblto_plugin.so")) ++ { ++ link_with_lto_plugin_before = true; ++ for (j = i + 1; ld_argv[j]; ++j) ++ { ++ if (!startswith (ld_argv[j], "-plugin-opt=")) ++ break; ++ } ++ for (i = i - 1; ; ++i, ++j) ++ { ++ ld_argv[i] = ld_argv[j]; ++ if (ld_argv[j] == NULL) ++ break; ++ } ++ break; ++ } ++ } ++ int ret2 = 0; ++ if (link_with_lto_plugin_before) ++ { ++ fprintf (stderr, "lto link fail, relinking without lto"); ++ lto_mode = LTO_MODE_NONE; ++ pex = collect_execute (prog, ld_argv, NULL, NULL, ++ PEX_LAST | PEX_SEARCH, ++ HAVE_GNU_LD && at_file_supplied, atsuffix); ++ ret2 = collect_wait (prog, pex); ++ } ++ else ++ ret2 = ret; ++ if (ret2) ++ { ++ error ("ld returned %d exit status", ret); ++ exit (ret); ++ } ++ else ++ { ++ /* We have just successfully produced an output file, so assume that ++ we may unlink it if need be for now on. */ ++ may_unlink_output_file = true; ++ } ++ } ++ else if (ret) + { + error ("ld returned %d exit status", ret); + exit (ret); +@@ -1009,6 +1056,8 @@ main (int argc, char **argv) + num_c_args++; + if (startswith (q, "-flto-partition=none")) + no_partition = true; ++ else if (startswith (q, "-flto-try")) ++ maybe_relink_without_lto = true; + else if (startswith (q, "-fno-lto")) + lto_mode = LTO_MODE_NONE; + else if (startswith (q, "-save-temps")) +diff --git a/gcc/common.opt b/gcc/common.opt +index 96888cf1b..0895c6114 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -70,6 +70,10 @@ bool flag_warn_unused_result = false + Variable + int flag_generate_lto + ++; Nonzero if we should write GIMPLE bytecode for link-time optimization. ++Variable ++int flag_relink_whthout_lto = 0 ++ + ; Nonzero if we should write GIMPLE bytecode for offload compilation. + Variable + int flag_generate_offload = 0 +@@ -2161,6 +2165,10 @@ flto + Common + Enable link-time optimization. + ++flto-try ++Common Var(flag_lto_try) Init(0) ++Do link-time optimization as much as possible. ++ + flto= + Common RejectNegative Joined Var(flag_lto) + Link-time optimization with number of parallel jobs or jobserver. +diff --git a/gcc/opts-common.cc b/gcc/opts-common.cc +index 33c696f3d..176041bfe 100644 +--- a/gcc/opts-common.cc ++++ b/gcc/opts-common.cc +@@ -1162,7 +1162,50 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv, + struct cl_decoded_option *opt_array; + unsigned int num_decoded_options; + +- int opt_array_len = argc; ++ enum LTO_SKIP_STAT ++ { ++ NO_NEED_TO_SKIP, ++ NEED_TO_SKIP, ++ ALREADY_SKIP, ++ }; ++ LTO_SKIP_STAT lto_skip_stat = NO_NEED_TO_SKIP; ++ bool try_use_lto = false; ++ const char* lto_option_conflict = NULL; ++ const char* wrap_option = "-Wl,--wrap="; ++ const char* start_lib_option = "-Wl,--start-lib"; ++ for (i = 1; i < argc; i += 1) ++ { ++ if (startswith (argv[i], "-flto-try")) ++ { ++ try_use_lto = true; ++ } ++ ++ if (startswith (argv[i], wrap_option) ++ && (lto_skip_stat == NO_NEED_TO_SKIP)) ++ { ++ lto_option_conflict = wrap_option; ++ lto_skip_stat = NEED_TO_SKIP; ++ } ++ else if (startswith (argv[i], start_lib_option) ++ && (lto_skip_stat == NO_NEED_TO_SKIP)) ++ { ++ lto_option_conflict = start_lib_option; ++ lto_skip_stat = NEED_TO_SKIP; ++ } ++ else if (startswith (argv[i], "-fno-lto")) ++ { ++ lto_option_conflict = NULL; ++ lto_skip_stat = ALREADY_SKIP; ++ break; ++ } ++ } ++ if (!try_use_lto) ++ { ++ lto_skip_stat = NO_NEED_TO_SKIP; ++ lto_option_conflict = NULL; ++ } ++ ++ int opt_array_len = lto_skip_stat == NEED_TO_SKIP ? argc + 1 : argc; + opt_array = XNEWVEC (struct cl_decoded_option, opt_array_len); + + opt_array[0].opt_index = OPT_SPECIAL_program_name; +@@ -1244,6 +1287,15 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv, + num_decoded_options += handle_machine_option (lang_mask, num_decoded_options, + argc, argv, opt_array); + ++ if (lto_skip_stat == NEED_TO_SKIP) ++ { ++ const char * nolto = "-fno-lto"; ++ fprintf (stderr, "skip lto for %s\n", lto_option_conflict); ++ decode_cmdline_option (&nolto, lang_mask, ++ &opt_array[num_decoded_options]); ++ num_decoded_options++; ++ } ++ + *decoded_options = opt_array; + *decoded_options_count = num_decoded_options; + prune_options (decoded_options, decoded_options_count, lang_mask); +diff --git a/gcc/opts.cc b/gcc/opts.cc +index 84dd8925a..9ccc22510 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -1143,6 +1143,26 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, + SET_OPTION_IF_UNSET (opts, opts_set, param_stack_frame_growth, 40); + } + ++ if (opts->x_flag_lto_try) ++ { ++#ifdef ENABLE_LTO ++ if (opts_set->x_flag_lto && opts->x_flag_lto) ++ { ++ inform (loc, "%<-flto-try%> don't guarantee that lto " ++ "will be enabled."); ++ } ++ opts->x_flag_lto = ""; ++ if (opts_set->x_flag_fat_lto_objects && !opts->x_flag_fat_lto_objects) ++ { ++ error_at (loc, "%<-flto-try%> are not supported with " ++ "-fno-fat-lto-objects"); ++ } ++ opts->x_flag_fat_lto_objects = 1; ++#else ++ error_at (loc, "LTO support has not been enabled in this configuration"); ++#endif ++ } ++ + if (opts->x_flag_lto) + { + #ifdef ENABLE_LTO +-- +2.33.0 + diff --git a/0319-CSPGO-fix-bugs-when-using-cspgo.patch b/0319-CSPGO-fix-bugs-when-using-cspgo.patch new file mode 100644 index 0000000000000000000000000000000000000000..bd86bb8dfe9ab989bb776e6a0f9f6e813ffe2aaf --- /dev/null +++ b/0319-CSPGO-fix-bugs-when-using-cspgo.patch @@ -0,0 +1,140 @@ +From 610470b1892213afd4ddcf83862667c758724872 Mon Sep 17 00:00:00 2001 +From: liyancheng <412998149@qq.com> +Date: Wed, 4 Dec 2024 16:25:01 +0800 +Subject: [PATCH] [CSPGO] fix bugs when using cspgo + +--- + gcc/opts.cc | 36 ++++++++++++++++++++++++++---------- + gcc/tree-profile.cc | 20 ++++++++++++++++++++ + 2 files changed, 46 insertions(+), 10 deletions(-) + +diff --git a/gcc/opts.cc b/gcc/opts.cc +index 6ca9dde7e..2433ace06 100644 +--- a/gcc/opts.cc ++++ b/gcc/opts.cc +@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see + #include "diagnostic-color.h" + #include "version.h" + #include "selftest.h" ++#include "ai4c-infer.h" + + /* In this file all option sets are explicit. */ + #undef OPTION_SET_P +@@ -3086,17 +3087,28 @@ common_handle_option (struct gcc_options *opts, + break; + + case OPT_fcfgo_profile_use_: ++ opts->x_profile_data_prefix = xstrdup (arg); ++ opts->x_flag_profile_use = true; ++ value = true; + /* No break here - do -fcfgo-profile-use processing. */ + /* FALLTHRU */ + case OPT_fcfgo_profile_use: +- value = true; +- if (value) ++ if (get_optimize_decision_from_ai4c ()) + { ++ value = true; + enable_cfgo_optimizations (opts, opts_set, value); + SET_OPTION_IF_UNSET (opts, opts_set, flag_cfgo_profile_use, value); ++ /* Enable orig fdo optimizations. */ ++ enable_fdo_optimizations (opts, opts_set, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_reorder_functions, ++ value); ++ /* Indirect call profiling should do all useful transformations ++ speculative devirtualization does. */ ++ if (opts->x_flag_value_profile_transformations) ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_devirtualize_speculatively, ++ false); + } +- /* No break here - do -fprofile-use processing. */ +- /* FALLTHRU */ ++ break; + case OPT_fprofile_use_: + opts->x_profile_data_prefix = xstrdup (arg); + opts->x_flag_profile_use = true; +@@ -3116,10 +3128,10 @@ common_handle_option (struct gcc_options *opts, + + case OPT_fcfgo_csprofile_use_: + opts->x_csprofile_data_prefix = xstrdup (arg); +- value = true; + /* No break here - do -fcfgo-csprofile-use processing. */ + /* FALLTHRU */ + case OPT_fcfgo_csprofile_use: ++ value = get_optimize_decision_from_ai4c (); + SET_OPTION_IF_UNSET (opts, opts_set, flag_csprofile_use, value); + break; + +@@ -3155,18 +3167,22 @@ common_handle_option (struct gcc_options *opts, + break; + + case OPT_fcfgo_profile_generate_: ++ opts->x_profile_data_prefix = xstrdup (arg); ++ value = true; + /* No break here - do -fcfgo-profile-generate processing. */ + /* FALLTHRU */ + case OPT_fcfgo_profile_generate: +- value = true; +- if (value) ++ if (get_optimize_decision_from_ai4c ()) + { + enable_cfgo_optimizations (opts, opts_set, value); + SET_OPTION_IF_UNSET (opts, opts_set, flag_cfgo_profile_generate, + value); + } +- /* No break here - do -fprofile-generate processing. */ +- /* FALLTHRU */ ++ SET_OPTION_IF_UNSET (opts, opts_set, profile_arc_flag, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value); ++ SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value); ++ break; + case OPT_fprofile_generate_: + opts->x_profile_data_prefix = xstrdup (arg); + value = true; +@@ -3181,10 +3197,10 @@ common_handle_option (struct gcc_options *opts, + + case OPT_fcfgo_csprofile_generate_: + opts->x_csprofile_data_prefix = xstrdup (arg); +- value = true; + /* No break here - do -fcfgo-csprofile-generate processing. */ + /* FALLTHRU */ + case OPT_fcfgo_csprofile_generate: ++ value = get_optimize_decision_from_ai4c (); + SET_OPTION_IF_UNSET (opts, opts_set, flag_csprofile_generate, value); + break; + +diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc +index aa3a2b3a9..ace1fe31c 100644 +--- a/gcc/tree-profile.cc ++++ b/gcc/tree-profile.cc +@@ -1114,6 +1114,26 @@ public: + to do anything. */ + virtual unsigned int execute (function *) + { ++ if (!profile_data_prefix) ++ error ("profile_data_prefix must set when using cspgo."); ++ ++ if (!csprofile_data_prefix) ++ error ("csprofile_data_prefix must set when using cspgo."); ++ ++ if (!flag_cfgo_profile_use) ++ error ("cspgo must used with cfgo-pgo."); ++ ++ /* Just compare canonical pathnames. */ ++ char* cfgo_pgo_path = lrealpath (profile_data_prefix); ++ char* cfgo_cspgo_path = lrealpath (csprofile_data_prefix); ++ bool files_differ = filename_cmp (cfgo_pgo_path, cfgo_cspgo_path); ++ if (!files_differ) ++ { ++ error ("pgo and cspgo path must different between %s and %s", ++ cfgo_pgo_path, cfgo_cspgo_path); ++ } ++ free (cfgo_pgo_path); ++ free (cfgo_cspgo_path); + return 0; + } + +-- +2.25.1 + diff --git a/0320-if-split-fix-bugs.patch b/0320-if-split-fix-bugs.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8b97ebe5ceb0eded7073abb31d029dcfc1cffc4 --- /dev/null +++ b/0320-if-split-fix-bugs.patch @@ -0,0 +1,105 @@ +From 7636e8782aa0dac322c22631c4cd0b60c0eb1842 Mon Sep 17 00:00:00 2001 +From: Zinin Ivan WX1305386 +Date: Tue, 3 Dec 2024 16:02:15 +0300 +Subject: [PATCH] Fix bugs + +Added check if then_bb got single succ in process_complex_cond() + +Made processing of cases when then_bb is pred of EXIT and got +return statement inside. Splitting of edge from EXIT pred to +EXIT deletes return statement, and duplication of then_bb will +got no return statement too. So in such cases we need to build +return statement in merge_bb by ourselves. +--- + gcc/gimple-if-split.cc | 35 +++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) + +diff --git a/gcc/gimple-if-split.cc b/gcc/gimple-if-split.cc +index 3446204ea..351515435 100644 +--- a/gcc/gimple-if-split.cc ++++ b/gcc/gimple-if-split.cc +@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see + #include "tree-cfg.h" + #include "bitmap.h" + #include "cfganal.h" ++#include "cfgloop.h" + + /* Perform splitting if-then-else patterns, whose complex OR condition in + cond-bb contains comparison of some variable with constant and then-bb got +@@ -255,6 +256,7 @@ process_complex_cond (basic_block cond_bb, basic_block then_bb, + cond_parts_defs defs; + + if (!can_duplicate_block_p (then_bb) ++ || !single_succ_p (then_bb) + || !necessary_complex_cond_p (cond, then_bb, &defs)) + return; + +@@ -345,14 +347,39 @@ static basic_block + make_two_separate_calls (basic_block outer_cond_bb, basic_block inner_cond_bb, + basic_block then_bb) + { +- if (!can_duplicate_block_p (then_bb) || EDGE_COUNT (then_bb->succs) != 1) ++ if (!can_duplicate_block_p (then_bb) || !single_succ_p (then_bb)) + return NULL; + + edge outer_then_e = find_edge (outer_cond_bb, then_bb); + + /* Making duplication of then_bb. */ + basic_block then_bb_dom = get_immediate_dominator (CDI_DOMINATORS, then_bb); ++ ++ /* Saving ret_value and then_bb succ edge flags, if then_bb is pred of ++ * EXIT_BLOCK and has return statement inside. */ ++ tree ret_val; ++ int then_bb_succ_edge_flags; ++ if (single_succ (then_bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) ++ { ++ gcc_assert (gimple_code (last_stmt (then_bb)) == GIMPLE_RETURN); ++ ret_val = gimple_return_retval (as_a(last_stmt (then_bb))); ++ ++ then_bb_succ_edge_flags = single_succ_edge (then_bb)->flags; ++ } ++ + basic_block merge_bb = split_edge (single_succ_edge (then_bb)); ++ ++ /* Building return statement in merge_bb and setting merge_bb succ edge flags, ++ * if now merge_bb is pred of EXIT_BLOCK. */ ++ if (single_succ (merge_bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) ++ { ++ gimple* ret = gimple_build_return (ret_val); ++ gimple_stmt_iterator gsi = gsi_last_bb (merge_bb); ++ gsi_insert_after (&gsi, ret, GSI_NEW_STMT); ++ ++ single_succ_edge (merge_bb)->flags = then_bb_succ_edge_flags; ++ } ++ + basic_block then_bb1 = duplicate_block (then_bb, outer_then_e, outer_cond_bb); + edge outer_then1_e = find_edge (outer_cond_bb, then_bb1); + +@@ -372,6 +399,9 @@ make_two_separate_calls (basic_block outer_cond_bb, basic_block inner_cond_bb, + set_immediate_dominator (CDI_POST_DOMINATORS, merge_bb, + single_succ (merge_bb)); + ++ if (get_immediate_dominator (CDI_POST_DOMINATORS, outer_cond_bb) == then_bb) ++ set_immediate_dominator (CDI_POST_DOMINATORS, outer_cond_bb, merge_bb); ++ + return then_bb1; + } + +@@ -548,6 +578,7 @@ pass_if_split::execute (function *fun) + + checking_verify_ssa (true, true); + checking_verify_flow_info (); ++ checking_verify_loop_structure (); + checking_verify_dominators (CDI_DOMINATORS); + checking_verify_dominators (CDI_POST_DOMINATORS); + +@@ -564,4 +595,4 @@ gimple_opt_pass * + make_pass_if_split (gcc::context *ctxt) + { + return new pass_if_split (ctxt); +-} +\ No newline at end of file ++} +-- +2.33.0 + diff --git a/Fix-indentation-and-numbering-errors.diff b/Fix-indentation-and-numbering-errors.diff new file mode 100644 index 0000000000000000000000000000000000000000..261d622858a9384c795b890efd09e03ae06df8ce --- /dev/null +++ b/Fix-indentation-and-numbering-errors.diff @@ -0,0 +1,205 @@ +diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in +index 91cd653623b..b686f5eb492 100644 +--- a/libphobos/libdruntime/Makefile.in ++++ b/libphobos/libdruntime/Makefile.in +@@ -124,13 +124,13 @@ target_triplet = @target@ + # CPU specific sources + @DRUNTIME_CPU_AARCH64_TRUE@am__append_11 = config/aarch64/switchcontext.S + @DRUNTIME_CPU_ARM_TRUE@am__append_12 = config/arm/switchcontext.S +-@DRUNTIME_CPU_LOONGARCH_TRUE@am__append_13 = config/loongarch/switchcontext.S +-@DRUNTIME_CPU_MIPS_TRUE@am__append_14 = config/mips/switchcontext.S +-@DRUNTIME_CPU_POWERPC_TRUE@am__append_15 = config/powerpc/switchcontext.S +-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__append_16 = config/mingw/switchcontext.S +-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__append_17 = config/x86/switchcontext.S +-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__append_18 = config/systemz/get_tls_offset.S +-@DRUNTIME_CPU_S390_TRUE@am__append_19 = config/s390/get_tls_offset.S ++@DRUNTIME_CPU_MIPS_TRUE@am__append_13 = config/mips/switchcontext.S ++@DRUNTIME_CPU_POWERPC_TRUE@am__append_14 = config/powerpc/switchcontext.S ++@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__append_15 = config/mingw/switchcontext.S ++@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__append_16 = config/x86/switchcontext.S ++@DRUNTIME_CPU_SYSTEMZ_TRUE@am__append_17 = config/systemz/get_tls_offset.S ++@DRUNTIME_CPU_S390_TRUE@am__append_18 = config/s390/get_tls_offset.S ++@DRUNTIME_CPU_LOONGARCH_TRUE@am__append_19 = config/loongarch/switchcontext.S + subdir = libdruntime + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +@@ -475,14 +475,14 @@ am__objects_22 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \ + @DRUNTIME_OS_SOLARIS_TRUE@am__objects_23 = $(am__objects_22) + @DRUNTIME_CPU_AARCH64_TRUE@am__objects_24 = config/aarch64/libgdruntime_la-switchcontext.lo + @DRUNTIME_CPU_ARM_TRUE@am__objects_25 = config/arm/libgdruntime_la-switchcontext.lo +-@DRUNTIME_CPU_LOONGARCH_TRUE@am__objects_26 = config/loongarch/libgdruntime_la-switchcontext.lo +-@DRUNTIME_CPU_MIPS_TRUE@am__objects_27 = config/mips/libgdruntime_la-switchcontext.lo +-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_28 = config/powerpc/libgdruntime_la-switchcontext.lo +-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_29 = config/mingw/libgdruntime_la-switchcontext.lo +-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_30 = config/x86/libgdruntime_la-switchcontext.lo +-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_31 = config/systemz/libgdruntime_la-get_tls_offset.lo +-@DRUNTIME_CPU_S390_TRUE@am__objects_32 = config/s390/libgdruntime_la-get_tls_offset.lo +-am__objects_33 = $(am__objects_6) $(am__objects_8) $(am__objects_10) \ ++@DRUNTIME_CPU_MIPS_TRUE@am__objects_26 = config/mips/libgdruntime_la-switchcontext.lo ++@DRUNTIME_CPU_POWERPC_TRUE@am__objects_27 = config/powerpc/libgdruntime_la-switchcontext.lo ++@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_28 = config/mingw/libgdruntime_la-switchcontext.lo ++@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_29 = config/x86/libgdruntime_la-switchcontext.lo ++@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_30 = config/systemz/libgdruntime_la-get_tls_offset.lo ++@DRUNTIME_CPU_S390_TRUE@am__objects_31 = config/s390/libgdruntime_la-get_tls_offset.lo ++@DRUNTIME_CPU_LOONGARCH_TRUE@am__objects_32 = config/loongarch/libgdruntime_la-switchcontext.lo ++am__objects_33 = $(am__objects_5) $(am__objects_7) $(am__objects_9) \ + $(am__objects_11) $(am__objects_13) $(am__objects_15) \ + $(am__objects_17) $(am__objects_19) $(am__objects_21) \ + $(am__objects_23) $(am__objects_24) $(am__objects_25) \ +@@ -500,22 +500,22 @@ am__objects_36 = core/stdc/libgdruntime_convenience_la-errno_.lo + @DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo + @DRUNTIME_CPU_AARCH64_TRUE@am__objects_38 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo + @DRUNTIME_CPU_ARM_TRUE@am__objects_39 = config/arm/libgdruntime_convenience_la-switchcontext.lo +-@DRUNTIME_CPU_LOONGARCH_TRUE@am__objects_40 = config/loongarch/libgdruntime_convenience_la-switchcontext.lo +-@DRUNTIME_CPU_MIPS_TRUE@am__objects_41 = config/mips/libgdruntime_convenience_la-switchcontext.lo +-@DRUNTIME_CPU_POWERPC_TRUE@am__objects_42 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo +-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_43 = config/mingw/libgdruntime_convenience_la-switchcontext.lo +-@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_44 = config/x86/libgdruntime_convenience_la-switchcontext.lo +-@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_45 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo +-@DRUNTIME_CPU_S390_TRUE@am__objects_46 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo ++@DRUNTIME_CPU_MIPS_TRUE@am__objects_40 = config/mips/libgdruntime_convenience_la-switchcontext.lo ++@DRUNTIME_CPU_POWERPC_TRUE@am__objects_41 = config/powerpc/libgdruntime_convenience_la-switchcontext.lo ++@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_TRUE@am__objects_42 = config/mingw/libgdruntime_convenience_la-switchcontext.lo ++@DRUNTIME_CPU_X86_TRUE@@DRUNTIME_OS_MINGW_FALSE@am__objects_43 = config/x86/libgdruntime_convenience_la-switchcontext.lo ++@DRUNTIME_CPU_SYSTEMZ_TRUE@am__objects_44 = config/systemz/libgdruntime_convenience_la-get_tls_offset.lo ++@DRUNTIME_CPU_S390_TRUE@am__objects_45 = config/s390/libgdruntime_convenience_la-get_tls_offset.lo ++@DRUNTIME_CPU_LOONGARCH_TRUE@am__objects_46 = config/loongarch/libgdruntime_convenience_la-switchcontext.lo + am__objects_47 = $(am__objects_5) $(am__objects_7) $(am__objects_9) \ + $(am__objects_11) $(am__objects_13) $(am__objects_15) \ +- $(am__objects_17) $(am__objects_19) $(am__objects_36) \ +- $(am__objects_23) $(am__objects_37) $(am__objects_38) \ +- $(am__objects_39) $(am__objects_40) $(am__objects_41) \ +- $(am__objects_42) $(am__objects_43) $(am__objects_44) \ +- $(am__objects_45) $(am__objects_46) +-am__objects_48 = $(am__objects_1) $(am__objects_35) $(am__objects_3) \ +- $(am__objects_47) $(am__objects_33) ++ $(am__objects_17) $(am__objects_19) $(am__objects_37) \ ++ $(am__objects_23) $(am__objects_38) $(am__objects_39) \ ++ $(am__objects_40) $(am__objects_41) $(am__objects_42) \ ++ $(am__objects_43) $(am__objects_44) $(am__objects_45) \ ++ $(am__objects_46) ++am__objects_48 = $(am__objects_1) $(am__objects_36) $(am__objects_3) \ ++ $(am__objects_47) $(am__objects_34) + am__objects_49 = $(am__objects_48) + am_libgdruntime_convenience_la_OBJECTS = $(am__objects_49) + libgdruntime_convenience_la_OBJECTS = \ +@@ -1905,11 +1905,6 @@ config/arm/$(am__dirstamp): + @: > config/arm/$(am__dirstamp) + config/arm/libgdruntime_la-switchcontext.lo: \ + config/arm/$(am__dirstamp) +-config/loongarch/$(am__dirstamp): +- @$(MKDIR_P) config/loongarch +- @: > config/loongarch/$(am__dirstamp) +-config/loongarch/libgdruntime_la-switchcontext.lo: \ +- config/loongarch/$(am__dirstamp) + config/mips/$(am__dirstamp): + @$(MKDIR_P) config/mips + @: > config/mips/$(am__dirstamp) +@@ -1937,6 +1932,11 @@ config/s390/$(am__dirstamp): + @: > config/s390/$(am__dirstamp) + config/s390/libgdruntime_la-get_tls_offset.lo: \ + config/s390/$(am__dirstamp) ++config/loongarch/$(am__dirstamp): ++ @$(MKDIR_P) config/loongarch ++ @: > config/loongarch/$(am__dirstamp) ++config/loongarch/libgdruntime_la-switchcontext.lo: \ ++ config/loongarch/$(am__dirstamp) + gcc/config.lo: gcc/$(am__dirstamp) + gcc/libbacktrace.lo: gcc/$(am__dirstamp) + +@@ -1950,8 +1950,6 @@ config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \ + config/aarch64/$(am__dirstamp) + config/arm/libgdruntime_convenience_la-switchcontext.lo: \ + config/arm/$(am__dirstamp) +-config/loongarch/libgdruntime_convenience_la-switchcontext.lo: \ +- config/loongarch/$(am__dirstamp) + config/mips/libgdruntime_convenience_la-switchcontext.lo: \ + config/mips/$(am__dirstamp) + config/powerpc/libgdruntime_convenience_la-switchcontext.lo: \ +@@ -1964,6 +1962,8 @@ config/systemz/libgdruntime_convenience_la-get_tls_offset.lo: \ + config/systemz/$(am__dirstamp) + config/s390/libgdruntime_convenience_la-get_tls_offset.lo: \ + config/s390/$(am__dirstamp) ++config/loongarch/libgdruntime_convenience_la-switchcontext.lo: \ ++ config/loongarch/$(am__dirstamp) + + libgdruntime_convenience.la: $(libgdruntime_convenience_la_OBJECTS) $(libgdruntime_convenience_la_DEPENDENCIES) $(EXTRA_libgdruntime_convenience_la_DEPENDENCIES) + $(AM_V_GEN)$(libgdruntime_convenience_la_LINK) $(libgdruntime_convenience_la_OBJECTS) $(libgdruntime_convenience_la_LIBADD) $(LIBS) +@@ -1976,14 +1976,14 @@ mostlyclean-compile: + -rm -f config/arm/*.lo + -rm -f config/mingw/*.$(OBJEXT) + -rm -f config/mingw/*.lo +- -rm -f config/loongarch/*.$(OBJEXT) +- -rm -f config/loongarch/*.lo + -rm -f config/mips/*.$(OBJEXT) + -rm -f config/mips/*.lo + -rm -f config/powerpc/*.$(OBJEXT) + -rm -f config/powerpc/*.lo + -rm -f config/s390/*.$(OBJEXT) + -rm -f config/s390/*.lo ++ -rm -f config/loongarch/*.$(OBJEXT) ++ -rm -f config/loongarch/*.lo + -rm -f config/systemz/*.$(OBJEXT) + -rm -f config/systemz/*.lo + -rm -f config/x86/*.$(OBJEXT) +@@ -2101,10 +2101,7 @@ config/aarch64/libgdruntime_la-switchcontext.lo: config/aarch64/switchcontext.S + config/arm/libgdruntime_la-switchcontext.lo: config/arm/switchcontext.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/arm/libgdruntime_la-switchcontext.lo `test -f 'config/arm/switchcontext.S' || echo '$(srcdir)/'`config/arm/switchcontext.S + +-config/loongarch/libgdruntime_la-switchcontext.lo: config/loongarch/switchcontext.S +- $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) +- +-onfig/mips/libgdruntime_la-switchcontext.lo: config/mips/switchcontext.S ++config/mips/libgdruntime_la-switchcontext.lo: config/mips/switchcontext.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/mips/libgdruntime_la-switchcontext.lo `test -f 'config/mips/switchcontext.S' || echo '$(srcdir)/'`config/mips/switchcontext.S + + config/powerpc/libgdruntime_la-switchcontext.lo: config/powerpc/switchcontext.S +@@ -2122,18 +2119,21 @@ config/systemz/libgdruntime_la-get_tls_offset.lo: config/systemz/get_tls_offset. + config/s390/libgdruntime_la-get_tls_offset.lo: config/s390/get_tls_offset.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/s390/libgdruntime_la-get_tls_offset.lo `test -f 'config/s390/get_tls_offset.S' || echo '$(srcdir)/'`config/s390/get_tls_offset.S + ++config/loongarch/libgdruntime_la-switchcontext.lo: config/loongarch/switchcontext.S ++ $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/loongarch/libgdruntime_la-switchcontext.lo `test -f 'config/loongarch/switchcontext.S' || echo '$(srcdir)/'`config/loongarch/switchcontext.S ++ + config/aarch64/libgdruntime_convenience_la-switchcontext.lo: config/aarch64/switchcontext.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/aarch64/libgdruntime_convenience_la-switchcontext.lo `test -f 'config/aarch64/switchcontext.S' || echo '$(srcdir)/'`config/aarch64/switchcontext.S + + config/arm/libgdruntime_convenience_la-switchcontext.lo: config/arm/switchcontext.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/arm/libgdruntime_convenience_la-switchcontext.lo `test -f 'config/arm/switchcontext.S' || echo '$(srcdir)/'`config/arm/switchcontext.S + +-config/loongarch/libgdruntime_convenience_la-switchcontext.lo: config/loongarch/switchcontext.S +- $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM +- + config/mips/libgdruntime_convenience_la-switchcontext.lo: config/mips/switchcontext.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/mips/libgdruntime_convenience_la-switchcontext.lo `test -f 'config/mips/switchcontext.S' || echo '$(srcdir)/'`config/mips/switchcontext.S + ++config/loongarch/libgdruntime_convenience_la-switchcontext.lo: config/loongarch/switchcontext.S ++ $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/loongarch/libgdruntime_convenience_la-switchcontext.lo `test -f 'config/loongarch/switchcontext.S' || echo '$(srcdir)/'`config/loongarch/switchcontext.S ++ + config/powerpc/libgdruntime_convenience_la-switchcontext.lo: config/powerpc/switchcontext.S + $(AM_V_CPPAS)$(LIBTOOL) $(AM_V_lt) $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o config/powerpc/libgdruntime_convenience_la-switchcontext.lo `test -f 'config/powerpc/switchcontext.S' || echo '$(srcdir)/'`config/powerpc/switchcontext.S + +@@ -2178,10 +2178,10 @@ clean-libtool: + -rm -rf config/aarch64/.libs config/aarch64/_libs + -rm -rf config/arm/.libs config/arm/_libs + -rm -rf config/mingw/.libs config/mingw/_libs +- -rm -rf config/loongarch/.libs config/loongarch/_libs + -rm -rf config/mips/.libs config/mips/_libs + -rm -rf config/powerpc/.libs config/powerpc/_libs + -rm -rf config/s390/.libs config/s390/_libs ++ -rm -rf config/loongarch/.libs config/loongarch/_libs + -rm -rf config/systemz/.libs config/systemz/_libs + -rm -rf config/x86/.libs config/x86/_libs + -rm -rf core/.libs core/_libs +@@ -2340,10 +2340,10 @@ distclean-generic: + -rm -f config/aarch64/$(am__dirstamp) + -rm -f config/arm/$(am__dirstamp) + -rm -f config/mingw/$(am__dirstamp) +- -rm -f config/loongarch/$(am__dirstamp) + -rm -f config/mips/$(am__dirstamp) + -rm -f config/powerpc/$(am__dirstamp) + -rm -f config/s390/$(am__dirstamp) ++ -rm -f config/loongarch/$(am__dirstamp) + -rm -f config/systemz/$(am__dirstamp) + -rm -f config/x86/$(am__dirstamp) + -rm -f core/$(am__dirstamp) diff --git a/LoongArch-Allow-attributes-in-non-gnu-namespaces.diff b/LoongArch-Allow-attributes-in-non-gnu-namespaces.diff new file mode 100644 index 0000000000000000000000000000000000000000..ae7ac9be1055138d4c4d70b97e0283df2f5f715d --- /dev/null +++ b/LoongArch-Allow-attributes-in-non-gnu-namespaces.diff @@ -0,0 +1,23 @@ +diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc +index 6be0d80b3..12af95f70 100644 +--- a/gcc/config/loongarch/loongarch.cc ++++ b/gcc/config/loongarch/loongarch.cc +@@ -7917,15 +7917,13 @@ loongarch_handle_model_attribute (tree *node, tree name, tree arg, int, + return NULL_TREE; + } + +-static const struct attribute_spec loongarch_attribute_table[] = ++TARGET_GNU_ATTRIBUTES (loongarch_attribute_table, + { + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, + affects_type_identity, handler, exclude } */ + { "model", 1, 1, true, false, false, false, +- loongarch_handle_model_attribute, NULL }, +- /* The last attribute spec is set to be NULL. */ +- {} +-}; ++ loongarch_handle_model_attribute, NULL } ++}); + + bool + loongarch_use_anchors_for_symbol_p (const_rtx symbol) diff --git a/gcc.spec b/gcc.spec index cf6473da37ae35a245ef39f4f91a5a85c3bbd450..35104d29a382f8951451b87c519dc23865d51242 100644 --- a/gcc.spec +++ b/gcc.spec @@ -2,7 +2,7 @@ %global gcc_major 12 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 36 +%global gcc_release 56 %global _unpackaged_files_terminate_build 0 %global _performance_build 1 @@ -23,32 +23,32 @@ %else %global build_libquadmath 0 %endif -%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 loongarch64 riscv64 +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 loongarch64 riscv64 sw_64 %global build_libasan 1 %else %global build_libasan 0 %endif -%ifarch x86_64 ppc64 ppc64le aarch64 s390x loongarch64 +%ifarch x86_64 ppc64 ppc64le aarch64 s390x loongarch64 sw_64 %global build_libtsan 1 %else %global build_libtsan 0 %endif -%ifarch x86_64 ppc64 ppc64le aarch64 s390x loongarch64 +%ifarch x86_64 ppc64 ppc64le aarch64 s390x loongarch64 sw_64 %global build_liblsan 1 %else %global build_liblsan 0 %endif -%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 loongarch64 riscv64 +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 loongarch64 riscv64 sw_64 %global build_libubsan 1 %else %global build_libubsan 0 %endif -%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %{mips} riscv64 loongarch64 +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %{mips} riscv64 loongarch64 sw_64 %global build_libatomic 1 %else %global build_libatomic 0 %endif -%ifarch %{ix86} x86_64 %{arm} alpha ppc ppc64 ppc64le ppc64p7 s390 s390x aarch64 loongarch64 +%ifarch %{ix86} x86_64 %{arm} alpha ppc ppc64 ppc64le ppc64p7 s390 s390x aarch64 loongarch64 sw_64 %global build_libitm 1 %else %global build_libitm 0 @@ -69,7 +69,6 @@ %global multilib_32_arch i686 %endif %ifarch riscv64 -%global _lib lib %global _smp_mflags -j8 %endif @@ -203,157 +202,251 @@ Patch93: 0093-fix-bugs-within-pointer-compression-and-DFE.patch Patch94: 0094-BUGFIX-AutoBOLT-function-miss-bind-type.patch Patch95: 0095-STABS-remove-gstabs-and-gxcoff-functionality.patch Patch96: 0096-Bugfix-Autofdo-use-PMU-sampling-set-num-eauals-den.patch -Patch97: 0097-Backport-SME-AArch64-Cleanup-CPU-option-processing-c.patch -Patch98: 0098-Backport-SME-AArch64-Cleanup-option-processing-code.patch -Patch99: 0099-Backport-SME-aarch64-Add-march-support-for-Armv9.1-A.patch -Patch100: 0100-Backport-SME-Revert-aarch64-Define-__ARM_FEATURE_RCP.patch -Patch101: 0101-Backport-SME-Revert-Ampere-1-and-Ampere-1A-core-defi.patch -Patch102: 0102-Backport-SME-aarch64-Rename-AARCH64_ISA-architecture.patch -Patch103: 0103-Backport-SME-aarch64-Rename-AARCH64_FL-architecture-.patch -Patch104: 0104-Backport-SME-aarch64-Rename-AARCH64_FL_FOR_ARCH-macr.patch -Patch105: 0105-Backport-SME-aarch64-Add-V-to-aarch64-arches.def-nam.patch -Patch106: 0106-Backport-SME-aarch64-Small-config.gcc-cleanups.patch -Patch107: 0107-Backport-SME-aarch64-Avoid-redundancy-in-aarch64-cor.patch -Patch108: 0108-Backport-SME-aarch64-Remove-AARCH64_FL_RCPC8_4-PR107.patch -Patch109: 0109-Backport-SME-aarch64-Fix-transitive-closure-of-featu.patch -Patch110: 0110-Backport-SME-aarch64-Reorder-an-entry-in-aarch64-opt.patch -Patch111: 0111-Backport-SME-aarch64-Simplify-feature-definitions.patch -Patch112: 0112-Backport-SME-aarch64-Simplify-generation-of-.arch-st.patch -Patch113: 0113-Backport-SME-aarch64-Avoid-std-string-in-static-data.patch -Patch114: 0114-Backport-SME-aarch64-Tweak-constness-of-option-relat.patch -Patch115: 0115-Backport-SME-aarch64-Make-more-use-of-aarch64_featur.patch -Patch116: 0116-Backport-SME-aarch64-Tweak-contents-of-flags_on-off-.patch -Patch117: 0117-Backport-SME-aarch64-Tweak-handling-of-mgeneral-regs.patch -Patch118: 0118-Backport-SME-aarch64-Remove-redundant-TARGET_-checks.patch -Patch119: 0119-Backport-SME-aarch64-Define-__ARM_FEATURE_RCPC.patch -Patch120: 0120-Backport-SME-Add-Ampere-1-and-Ampere-1A-core-definit.patch -Patch121: 0121-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch -Patch122: 0122-Backport-SME-aarch64-Commonise-some-folding-code.patch -Patch123: 0123-Backport-SME-aarch64-Add-a-Z-operand-modifier-for-SV.patch -Patch124: 0124-Backport-SME-mode-switching-Remove-unused-bbnum-fiel.patch -Patch125: 0125-Backport-SME-mode-switching-Tweak-the-macro-hook-doc.patch -Patch126: 0126-Backport-SME-mode-switching-Add-note-problem.patch -Patch127: 0127-Backport-SME-mode-switching-Avoid-quadractic-list-op.patch -Patch128: 0128-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch -Patch129: 0129-Backport-SME-mode-switching-Simplify-recording-of-tr.patch -Patch130: 0130-Backport-SME-mode-switching-Tweak-entry-exit-handlin.patch -Patch131: 0131-Backport-SME-mode-switching-Allow-targets-to-set-the.patch -Patch132: 0132-Backport-SME-mode-switching-Pass-set-of-live-registe.patch -Patch133: 0133-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch -Patch134: 0134-Backport-SME-mode-switching-Use-1-based-edge-aux-fie.patch -Patch135: 0135-Backport-SME-mode-switching-Add-a-target-configurabl.patch -Patch136: 0136-Backport-SME-mode-switching-Add-a-backprop-hook.patch -Patch137: 0137-Backport-SME-aarch64-Add-a-result_mode-helper-functi.patch -Patch138: 0138-Backport-SME-rtl-Try-to-remove-EH-edges-after-pro-ep.patch -Patch139: 0139-Backport-SME-Fix-PR-middle-end-107705-ICE-after-recl.patch -Patch140: 0140-Backport-SME-function-Change-return-type-of-predicat.patch -Patch141: 0141-Backport-SME-Allow-prologues-and-epilogues-to-be-ins.patch -Patch142: 0142-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch -Patch143: 0143-Backport-SME-Add-a-new-target-hook-TARGET_START_CALL.patch -Patch144: 0144-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch -Patch145: 0145-Backport-SME-New-compact-syntax-for-insn-and-insn_sp.patch -Patch146: 0146-Backport-SME-recog-Improve-parser-for-pattern-new-co.patch -Patch147: 0147-Backport-SME-recog-Support-space-in-cons.patch -Patch148: 0148-Backport-SME-aarch64-Generalise-require_immediate_la.patch -Patch149: 0149-Backport-SME-aarch64-Add-backend-support-for-DFP.patch -Patch150: 0150-Backport-SME-aarch64-Vector-move-fixes-for-nosimd.patch -Patch151: 0151-Backport-SME-aarch64-Simplify-output-template-emissi.patch -Patch152: 0152-Backport-SME-Improve-immediate-expansion-PR106583.patch -Patch153: 0153-Backport-SME-AArch64-Cleanup-move-immediate-code.patch -Patch154: 0154-Backport-SME-AArch64-convert-some-patterns-to-compac.patch -Patch155: 0155-Backport-SME-aarch64-Use-SVE-s-RDVL-instruction.patch -Patch156: 0156-Backport-SME-aarch64-Make-AARCH64_FL_SVE-requirement.patch -Patch157: 0157-Backport-SME-aarch64-Add-group-suffixes-to-SVE-intri.patch -Patch158: 0158-Backport-SME-aarch64-Add-sve_type-to-SVE-builtins-co.patch -Patch159: 0159-Backport-SME-aarch64-Generalise-some-SVE-ACLE-error-.patch -Patch160: 0160-Backport-SME-aarch64-Replace-vague-previous-argument.patch -Patch161: 0161-Backport-SME-aarch64-Make-more-use-of-sve_type-in-AC.patch -Patch162: 0162-Backport-SME-aarch64-Tweak-error-message-for-tuple-v.patch -Patch163: 0163-Backport-SME-aarch64-Add-tuple-forms-of-svreinterpre.patch -Patch164: 0164-Backport-SME-attribs-Use-existing-traits-for-excl_ha.patch -Patch165: 0165-Backport-SME-Allow-target-attributes-in-non-gnu-name.patch -Patch166: 0166-Backport-SME-aarch64-Fix-plugin-header-install.patch -Patch167: 0167-Backport-SME-aarch64-Add-arm_streaming-_compatible-a.patch -Patch168: 0168-Backport-SME-aarch64-Add-sme.patch -Patch169: 0169-Backport-SME-aarch64-Add-r-m-and-m-r-alternatives-to.patch -Patch170: 0170-Backport-SME-AArch64-Rewrite-simd-move-immediate-pat.patch -Patch171: 0171-Backport-SME-AArch64-remove-test-comment-from-mov-mo.patch -Patch172: 0172-Backport-SME-aarch64-Distinguish-streaming-compatibl.patch -Patch173: 0173-Backport-SME-aarch64-Mark-relevant-SVE-instructions-.patch -Patch174: 0174-Backport-SME-AArch64-Support-new-tbranch-optab.patch -Patch175: 0175-Backport-SME-aarch64-Use-local-frame-vars-in-shrink-.patch -Patch176: 0176-Backport-SME-aarch64-Avoid-a-use-of-callee_offset.patch -Patch177: 0177-Backport-SME-aarch64-Explicitly-handle-frames-with-n.patch -Patch178: 0178-Backport-SME-aarch64-Add-bytes_below_saved_regs-to-f.patch -Patch179: 0179-Backport-SME-aarch64-Add-bytes_below_hard_fp-to-fram.patch -Patch180: 0180-Backport-SME-aarch64-Robustify-stack-tie-handling.patch -Patch181: 0181-Backport-SME-aarch64-Tweak-aarch64_save-restore_call.patch -Patch182: 0182-Backport-SME-aarch64-Only-calculate-chain_offset-if-.patch -Patch183: 0183-Backport-SME-aarch64-Rename-locals_offset-to-bytes_a.patch -Patch184: 0184-Backport-SME-aarch64-Rename-hard_fp_offset-to-bytes_.patch -Patch185: 0185-Backport-SME-aarch64-Tweak-frame_size-comment.patch -Patch186: 0186-Backport-SME-aarch64-Measure-reg_offset-from-the-bot.patch -Patch187: 0187-Backport-SME-aarch64-Simplify-top-of-frame-allocatio.patch -Patch188: 0188-Backport-SME-aarch64-Minor-initial-adjustment-tweak.patch -Patch189: 0189-Backport-SME-aarch64-Tweak-stack-clash-boundary-cond.patch -Patch190: 0190-Backport-SME-aarch64-Put-LR-save-probe-in-first-16-b.patch -Patch191: 0191-Backport-SME-aarch64-Simplify-probe-of-final-frame-a.patch -Patch192: 0192-Backport-SME-aarch64-Explicitly-record-probe-registe.patch -Patch193: 0193-Backport-SME-aarch64-Remove-below_hard_fp_saved_regs.patch -Patch194: 0194-Backport-SME-aarch64-Make-stack-smash-canary-protect.patch -Patch195: 0195-Backport-SME-Handle-epilogues-that-contain-jumps.patch -Patch196: 0196-Backport-SME-aarch64-Use-vecs-to-store-register-save.patch -Patch197: 0197-Backport-SME-aarch64-Put-LR-save-slot-first-in-more-.patch -Patch198: 0198-Backport-SME-aarch64-Switch-PSTATE.SM-around-calls.patch -Patch199: 0199-Backport-SME-aarch64-Add-support-for-SME-ZA-attribut.patch -Patch200: 0200-Backport-SME-aarch64-Add-a-register-class-for-w12-w1.patch -Patch201: 0201-Backport-SME-aarch64-Add-a-VNx1TI-mode.patch -Patch202: 0202-Backport-SME-aarch64-Generalise-unspec_based_functio.patch -Patch203: 0203-Backport-SME-aarch64-Generalise-_m-rules-for-SVE-int.patch -Patch204: 0204-Backport-SME-aarch64-Add-support-for-arm_sme.h.patch -Patch205: 0205-Backport-SME-aarch64-Add-support-for-__arm_locally_s.patch -Patch206: 0206-Backport-SME-aarch64-Handle-PSTATE.SM-across-abnorma.patch -Patch207: 0207-Backport-SME-aarch64-Enforce-inlining-restrictions-f.patch -Patch208: 0208-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch -Patch209: 0209-Backport-SME-libgcc-aarch64-Configure-check-for-.var.patch -Patch210: 0210-Backport-SME-libgcc-aarch64-Configure-check-for-__ge.patch -Patch211: 0211-Backport-SME-libgcc-aarch64-Add-SME-runtime-support.patch -Patch212: 0212-Backport-SME-libgcc-aarch64-Add-SME-unwinder-support.patch -Patch213: 0213-Backport-SME-libgcc-Fix-config.in.patch -Patch214: 0214-Backport-SME-aarch64-Add-funwind-tables-to-some-test.patch -Patch215: 0215-Backport-SME-aarch64-Skip-some-SME-register-save-tes.patch -Patch216: 0216-Backport-SME-Add-OPTIONS_H_EXTRA-to-GTFILES.patch -Patch217: 0217-Backport-SME-aarch64-Add-V1DI-mode.patch -Patch218: 0218-Backport-SME-Allow-md-iterators-to-include-other-ite.patch -Patch219: 0219-Backport-SME-riscv-Add-support-for-strlen-inline-exp.patch -Patch220: 0220-Backport-SME-attribs-Add-overloads-with-namespace-na.patch -Patch221: 0221-Backport-SME-vec-Add-array_slice-constructors-from-n.patch -Patch222: 0222-Backport-SME-A-couple-of-va_gc_atomic-tweaks.patch -Patch223: 0223-Backport-SME-middle-end-Fix-issue-of-poly_uint16-1-1.patch -Patch224: 0224-SME-Add-missing-header-file-in-aarch64.cc.patch -Patch225: 0225-Backport-SME-c-Add-support-for-__extension__.patch -Patch226: 0226-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch -Patch227: 0227-Backport-SME-c-Support-C2x-empty-initializer-braces.patch -Patch228: 0228-Backport-SME-aarch64-Update-sizeless-tests-for-recen.patch -Patch229: 0229-Backport-SME-attribs-Namespace-aware-lookup_attribut.patch -Patch230: 0230-Backport-SME-c-family-ICE-with-gnu-nocf_check-PR1069.patch -Patch231: 0231-Backport-SME-AArch64-Fix-assert-in-aarch64_move_imm-.patch -Patch232: 0232-Backport-SME-testsuite-Only-run-fcf-protection-test-.patch -Patch233: 0233-Backport-SME-Fix-PRs-106764-106765-and-107307-all-IC.patch -Patch234: 0234-Backport-SME-aarch64-Remove-expected-error-for-compo.patch -Patch235: 0235-Backport-SME-aarch64-Remove-redundant-builtins-code.patch -Patch236: 0236-Backport-SME-AArch64-Fix-Armv9-a-warnings-that-get-e.patch -Patch237: 0237-Backport-SME-Canonicalize-X-Y-as-X-Y-in-match.pd-whe.patch -Patch238: 0238-Backport-SME-middle-end-Add-new-tbranch-optab-to-add.patch -Patch239: 0239-Backport-SME-explow-Allow-dynamic-allocations-after-.patch -Patch240: 0240-Backport-SME-PR105169-Fix-references-to-discarded-se.patch -Patch241: 0241-Backport-SME-RISC-V-autovec-Verify-that-GET_MODE_NUN.patch -Patch242: 0242-Backport-SME-Add-operator-to-gimple_stmt_iterator-an.patch -Patch243: 0243-Backport-SME-tree-optimization-110221-SLP-and-loop-m.patch -Patch244: 0244-SME-Adapt-some-testsuites.patch -Patch245: 0245-SME-Fix-error-by-backported-patches-and-IPA-prefetch.patch -Patch246: 0246-aarch64-Fix-return-register-handling-in-untyped_call.patch -Patch247: 0247-aarch64-Fix-loose-ldpstp-check.patch +Patch97: 0097-Improve-non-loop-disambiguation.patch +Patch98: 0098-CHREC-multiplication-and-undefined-overflow.patch +Patch99: 0099-Enable-Transposed-SLP.patch +Patch100: 0100-Add-hip09-machine-discribtion.patch +Patch101: 0101-Add-hip11-CPU-pipeline-scheduling.patch +Patch102: 0102-Add-Crc32-Optimization-in-Gzip-For-crc32-algorithm-i.patch +Patch103: 0103-SME-Remove-hip09-and-hip11-in-aarch64-cores.def-to-b.patch +Patch104: 0104-Backport-SME-AArch64-Cleanup-CPU-option-processing-c.patch +Patch105: 0105-Backport-SME-AArch64-Cleanup-option-processing-code.patch +Patch106: 0106-Backport-SME-aarch64-Add-march-support-for-Armv9.1-A.patch +Patch107: 0107-Backport-SME-Revert-aarch64-Define-__ARM_FEATURE_RCP.patch +Patch108: 0108-Backport-SME-Revert-Ampere-1-and-Ampere-1A-core-defi.patch +Patch109: 0109-Backport-SME-aarch64-Rename-AARCH64_ISA-architecture.patch +Patch110: 0110-Backport-SME-aarch64-Rename-AARCH64_FL-architecture-.patch +Patch111: 0111-Backport-SME-aarch64-Rename-AARCH64_FL_FOR_ARCH-macr.patch +Patch112: 0112-Backport-SME-aarch64-Add-V-to-aarch64-arches.def-nam.patch +Patch113: 0113-Backport-SME-aarch64-Small-config.gcc-cleanups.patch +Patch114: 0114-Backport-SME-aarch64-Avoid-redundancy-in-aarch64-cor.patch +Patch115: 0115-Backport-SME-aarch64-Remove-AARCH64_FL_RCPC8_4-PR107.patch +Patch116: 0116-Backport-SME-aarch64-Fix-transitive-closure-of-featu.patch +Patch117: 0117-Backport-SME-aarch64-Reorder-an-entry-in-aarch64-opt.patch +Patch118: 0118-Backport-SME-aarch64-Simplify-feature-definitions.patch +Patch119: 0119-Backport-SME-aarch64-Simplify-generation-of-.arch-st.patch +Patch120: 0120-Backport-SME-aarch64-Avoid-std-string-in-static-data.patch +Patch121: 0121-Backport-SME-aarch64-Tweak-constness-of-option-relat.patch +Patch122: 0122-Backport-SME-aarch64-Make-more-use-of-aarch64_featur.patch +Patch123: 0123-Backport-SME-aarch64-Tweak-contents-of-flags_on-off-.patch +Patch124: 0124-Backport-SME-aarch64-Tweak-handling-of-mgeneral-regs.patch +Patch125: 0125-Backport-SME-aarch64-Remove-redundant-TARGET_-checks.patch +Patch126: 0126-Backport-SME-aarch64-Define-__ARM_FEATURE_RCPC.patch +Patch127: 0127-Backport-SME-Add-Ampere-1-and-Ampere-1A-core-definit.patch +Patch128: 0128-Backport-SME-aarch64-Fix-nosimd-handling-of-FPR-move.patch +Patch129: 0129-Backport-SME-aarch64-Commonise-some-folding-code.patch +Patch130: 0130-Backport-SME-aarch64-Add-a-Z-operand-modifier-for-SV.patch +Patch131: 0131-Backport-SME-mode-switching-Remove-unused-bbnum-fiel.patch +Patch132: 0132-Backport-SME-mode-switching-Tweak-the-macro-hook-doc.patch +Patch133: 0133-Backport-SME-mode-switching-Add-note-problem.patch +Patch134: 0134-Backport-SME-mode-switching-Avoid-quadractic-list-op.patch +Patch135: 0135-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch +Patch136: 0136-Backport-SME-mode-switching-Simplify-recording-of-tr.patch +Patch137: 0137-Backport-SME-mode-switching-Tweak-entry-exit-handlin.patch +Patch138: 0138-Backport-SME-mode-switching-Allow-targets-to-set-the.patch +Patch139: 0139-Backport-SME-mode-switching-Pass-set-of-live-registe.patch +Patch140: 0140-Backport-SME-mode-switching-Pass-the-set-of-live-reg.patch +Patch141: 0141-Backport-SME-mode-switching-Use-1-based-edge-aux-fie.patch +Patch142: 0142-Backport-SME-mode-switching-Add-a-target-configurabl.patch +Patch143: 0143-Backport-SME-mode-switching-Add-a-backprop-hook.patch +Patch144: 0144-Backport-SME-aarch64-Add-a-result_mode-helper-functi.patch +Patch145: 0145-Backport-SME-rtl-Try-to-remove-EH-edges-after-pro-ep.patch +Patch146: 0146-Backport-SME-Fix-PR-middle-end-107705-ICE-after-recl.patch +Patch147: 0147-Backport-SME-function-Change-return-type-of-predicat.patch +Patch148: 0148-Backport-SME-Allow-prologues-and-epilogues-to-be-ins.patch +Patch149: 0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch +Patch150: 0150-Backport-SME-Add-a-new-target-hook-TARGET_START_CALL.patch +Patch151: 0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch +Patch152: 0152-Backport-SME-New-compact-syntax-for-insn-and-insn_sp.patch +Patch153: 0153-Backport-SME-recog-Improve-parser-for-pattern-new-co.patch +Patch154: 0154-Backport-SME-recog-Support-space-in-cons.patch +Patch155: 0155-Backport-SME-aarch64-Generalise-require_immediate_la.patch +Patch156: 0156-Backport-SME-aarch64-Add-backend-support-for-DFP.patch +Patch157: 0157-Backport-SME-aarch64-Vector-move-fixes-for-nosimd.patch +Patch158: 0158-Backport-SME-aarch64-Simplify-output-template-emissi.patch +Patch159: 0159-Backport-SME-Improve-immediate-expansion-PR106583.patch +Patch160: 0160-Backport-SME-AArch64-Cleanup-move-immediate-code.patch +Patch161: 0161-Backport-SME-AArch64-convert-some-patterns-to-compac.patch +Patch162: 0162-Backport-SME-aarch64-Use-SVE-s-RDVL-instruction.patch +Patch163: 0163-Backport-SME-aarch64-Make-AARCH64_FL_SVE-requirement.patch +Patch164: 0164-Backport-SME-aarch64-Add-group-suffixes-to-SVE-intri.patch +Patch165: 0165-Backport-SME-aarch64-Add-sve_type-to-SVE-builtins-co.patch +Patch166: 0166-Backport-SME-aarch64-Generalise-some-SVE-ACLE-error-.patch +Patch167: 0167-Backport-SME-aarch64-Replace-vague-previous-argument.patch +Patch168: 0168-Backport-SME-aarch64-Make-more-use-of-sve_type-in-AC.patch +Patch169: 0169-Backport-SME-aarch64-Tweak-error-message-for-tuple-v.patch +Patch170: 0170-Backport-SME-aarch64-Add-tuple-forms-of-svreinterpre.patch +Patch171: 0171-Backport-SME-attribs-Use-existing-traits-for-excl_ha.patch +Patch172: 0172-Backport-SME-Allow-target-attributes-in-non-gnu-name.patch +Patch173: 0173-Backport-SME-aarch64-Fix-plugin-header-install.patch +Patch174: 0174-Backport-SME-aarch64-Add-arm_streaming-_compatible-a.patch +Patch175: 0175-Backport-SME-aarch64-Add-sme.patch +Patch176: 0176-Backport-SME-aarch64-Add-r-m-and-m-r-alternatives-to.patch +Patch177: 0177-Backport-SME-AArch64-Rewrite-simd-move-immediate-pat.patch +Patch178: 0178-Backport-SME-AArch64-remove-test-comment-from-mov-mo.patch +Patch179: 0179-Backport-SME-aarch64-Distinguish-streaming-compatibl.patch +Patch180: 0180-Backport-SME-aarch64-Mark-relevant-SVE-instructions-.patch +Patch181: 0181-Backport-SME-AArch64-Support-new-tbranch-optab.patch +Patch182: 0182-Backport-SME-aarch64-Use-local-frame-vars-in-shrink-.patch +Patch183: 0183-Backport-SME-aarch64-Avoid-a-use-of-callee_offset.patch +Patch184: 0184-Backport-SME-aarch64-Explicitly-handle-frames-with-n.patch +Patch185: 0185-Backport-SME-aarch64-Add-bytes_below_saved_regs-to-f.patch +Patch186: 0186-Backport-SME-aarch64-Add-bytes_below_hard_fp-to-fram.patch +Patch187: 0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch +Patch188: 0188-Backport-SME-aarch64-Tweak-aarch64_save-restore_call.patch +Patch189: 0189-Backport-SME-aarch64-Only-calculate-chain_offset-if-.patch +Patch190: 0190-Backport-SME-aarch64-Rename-locals_offset-to-bytes_a.patch +Patch191: 0191-Backport-SME-aarch64-Rename-hard_fp_offset-to-bytes_.patch +Patch192: 0192-Backport-SME-aarch64-Tweak-frame_size-comment.patch +Patch193: 0193-Backport-SME-aarch64-Measure-reg_offset-from-the-bot.patch +Patch194: 0194-Backport-SME-aarch64-Simplify-top-of-frame-allocatio.patch +Patch195: 0195-Backport-SME-aarch64-Minor-initial-adjustment-tweak.patch +Patch196: 0196-Backport-SME-aarch64-Tweak-stack-clash-boundary-cond.patch +Patch197: 0197-Backport-SME-aarch64-Put-LR-save-probe-in-first-16-b.patch +Patch198: 0198-Backport-SME-aarch64-Simplify-probe-of-final-frame-a.patch +Patch199: 0199-Backport-SME-aarch64-Explicitly-record-probe-registe.patch +Patch200: 0200-Backport-SME-aarch64-Remove-below_hard_fp_saved_regs.patch +Patch201: 0201-Backport-SME-aarch64-Make-stack-smash-canary-protect.patch +Patch202: 0202-Backport-SME-Handle-epilogues-that-contain-jumps.patch +Patch203: 0203-Backport-SME-aarch64-Use-vecs-to-store-register-save.patch +Patch204: 0204-Backport-SME-aarch64-Put-LR-save-slot-first-in-more-.patch +Patch205: 0205-Backport-SME-aarch64-Switch-PSTATE.SM-around-calls.patch +Patch206: 0206-Backport-SME-aarch64-Add-support-for-SME-ZA-attribut.patch +Patch207: 0207-Backport-SME-aarch64-Add-a-register-class-for-w12-w1.patch +Patch208: 0208-Backport-SME-aarch64-Add-a-VNx1TI-mode.patch +Patch209: 0209-Backport-SME-aarch64-Generalise-unspec_based_functio.patch +Patch210: 0210-Backport-SME-aarch64-Generalise-_m-rules-for-SVE-int.patch +Patch211: 0211-Backport-SME-aarch64-Add-support-for-arm_sme.h.patch +Patch212: 0212-Backport-SME-aarch64-Add-support-for-__arm_locally_s.patch +Patch213: 0213-Backport-SME-aarch64-Handle-PSTATE.SM-across-abnorma.patch +Patch214: 0214-Backport-SME-aarch64-Enforce-inlining-restrictions-f.patch +Patch215: 0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch +Patch216: 0216-Backport-SME-libgcc-aarch64-Configure-check-for-.var.patch +Patch217: 0217-Backport-SME-libgcc-aarch64-Configure-check-for-__ge.patch +Patch218: 0218-Backport-SME-libgcc-aarch64-Add-SME-runtime-support.patch +Patch219: 0219-Backport-SME-libgcc-aarch64-Add-SME-unwinder-support.patch +Patch220: 0220-Backport-SME-libgcc-Fix-config.in.patch +Patch221: 0221-Backport-SME-aarch64-Add-funwind-tables-to-some-test.patch +Patch222: 0222-Backport-SME-aarch64-Skip-some-SME-register-save-tes.patch +Patch223: 0223-Backport-SME-Add-OPTIONS_H_EXTRA-to-GTFILES.patch +Patch224: 0224-Backport-SME-aarch64-Add-V1DI-mode.patch +Patch225: 0225-Backport-SME-Allow-md-iterators-to-include-other-ite.patch +Patch226: 0226-Backport-SME-riscv-Add-support-for-strlen-inline-exp.patch +Patch227: 0227-Backport-SME-attribs-Add-overloads-with-namespace-na.patch +Patch228: 0228-Backport-SME-vec-Add-array_slice-constructors-from-n.patch +Patch229: 0229-Backport-SME-A-couple-of-va_gc_atomic-tweaks.patch +Patch230: 0230-Backport-SME-middle-end-Fix-issue-of-poly_uint16-1-1.patch +Patch231: 0231-SME-Add-missing-header-file-in-aarch64.cc.patch +Patch232: 0232-Backport-SME-c-Add-support-for-__extension__.patch +Patch233: 0233-Backport-SME-lra-Updates-of-biggest-mode-for-hard-re.patch +Patch234: 0234-Backport-SME-c-Support-C2x-empty-initializer-braces.patch +Patch235: 0235-Backport-SME-aarch64-Update-sizeless-tests-for-recen.patch +Patch236: 0236-Backport-SME-attribs-Namespace-aware-lookup_attribut.patch +Patch237: 0237-Backport-SME-c-family-ICE-with-gnu-nocf_check-PR1069.patch +Patch238: 0238-Backport-SME-AArch64-Fix-assert-in-aarch64_move_imm-.patch +Patch239: 0239-Backport-SME-testsuite-Only-run-fcf-protection-test-.patch +Patch240: 0240-Backport-SME-Fix-PRs-106764-106765-and-107307-all-IC.patch +Patch241: 0241-Backport-SME-aarch64-Remove-expected-error-for-compo.patch +Patch242: 0242-Backport-SME-aarch64-Remove-redundant-builtins-code.patch +Patch243: 0243-Backport-SME-AArch64-Fix-Armv9-a-warnings-that-get-e.patch +Patch244: 0244-Backport-SME-Canonicalize-X-Y-as-X-Y-in-match.pd-whe.patch +Patch245: 0245-Backport-SME-middle-end-Add-new-tbranch-optab-to-add.patch +Patch246: 0246-Backport-SME-explow-Allow-dynamic-allocations-after-.patch +Patch247: 0247-Backport-SME-PR105169-Fix-references-to-discarded-se.patch +Patch248: 0248-Backport-SME-RISC-V-autovec-Verify-that-GET_MODE_NUN.patch +Patch249: 0249-Backport-SME-Add-operator-to-gimple_stmt_iterator-an.patch +Patch250: 0250-Backport-SME-tree-optimization-110221-SLP-and-loop-m.patch +Patch251: 0251-SME-Adapt-some-testsuites.patch +Patch252: 0252-SME-Fix-error-by-backported-patches-and-IPA-prefetch.patch +Patch253: 0253-aarch64-Fix-return-register-handling-in-untyped_call.patch +Patch254: 0254-aarch64-Fix-loose-ldpstp-check.patch +Patch255: 0255-x86-Add-a-new-option-mdaz-ftz-to-enable-FTZ-and-DAZ-.patch +Patch256: 0256-Explicitly-view_convert_expr-mask-to-signed-type-whe.patch +Patch257: 0257-Make-option-mvzeroupper-independent-of-optimization-.patch +Patch258: 0258-i386-Sync-tune_string-with-arch_string-for-target-at.patch +Patch259: 0259-Refine-maskloadmn-pattern-with-UNSPEC_MASKLOAD.patch +Patch260: 0260-Refine-maskstore-patterns-with-UNSPEC_MASKMOV.patch +Patch261: 0261-x86-Update-model-values-for-Alderlake-and-Rocketlake.patch +Patch262: 0262-Workaround-possible-CPUID-bug-in-Sandy-Bridge.patch +Patch263: 0263-Software-mitigation-Disable-gather-generation-in-vec.patch +Patch264: 0264-Support-m-no-gather-m-no-scatter-to-enable-disable-v.patch +Patch265: 0265-Remove-constraint-modifier-for-fcmaddcph-fmaddcph-fc.patch +Patch266: 0266-Disparage-slightly-for-the-alternative-which-move-DF.patch +Patch267: 0267-Fix-wrong-code-due-to-vec_merge-pcmp-to-blendvb-spli.patch +Patch268: 0268-Don-t-assume-it-s-AVX_U128_CLEAN-after-call_insn-who.patch +Patch269: 0269-Disable-FMADD-in-chains-for-Zen4-and-generic.patch +Patch270: 0270-Initial-Raptorlake-Support.patch +Patch271: 0271-Initial-Meteorlake-Support.patch +Patch272: 0272-Support-Intel-AMX-FP16-ISA.patch +Patch273: 0273-Support-Intel-prefetchit0-t1.patch +Patch274: 0274-Initial-Granite-Rapids-Support.patch +Patch275: 0275-Support-Intel-AMX-COMPLEX.patch +Patch276: 0276-i386-Add-AMX-COMPLEX-to-Granite-Rapids.patch +Patch277: 0277-Initial-Granite-Rapids-D-Support.patch +Patch278: 0278-Correct-Granite-Rapids-D-documentation.patch +Patch279: 0279-i386-Remove-Meteorlake-s-family_model.patch +Patch280: 0280-x86-Update-model-values-for-Alderlake-Rocketlake-and.patch +Patch281: 0281-x86-Update-model-values-for-Raptorlake.patch +Patch282: 0282-Fix-target_clone-arch-graniterapids-d.patch +Patch283: 0283-i386-Change-prefetchi-output-template.patch +Patch284: 0284-i386-Add-non-optimize-prefetchi-intrins.patch +Patch285: 0285-SME-Recover-hip09-and-hip11-in-aarch64-cores.def.patch +Patch286: 0286-Try-to-use-AI-model-to-guide-optimization.patch +Patch287: 0287-Add-dynamic-memory-access-checks.patch +Patch288: 0288-Enable-macro-use-commandline.patch +Patch289: 0289-tree-ssa-loop-crc.cc-TARGET_CRC32-may-be-not-defined.patch +Patch290: 0290-Add-ipa-prefetch-test-for-gcc-s-case.patch +Patch291: 0291-Fix-settings-for-wide-operations-tests.patch +Patch292: 0292-Fix-errors-in-ipa-prefetch-IAORPF-and-IAOSJ0.patch +Patch293: 0293-Fix-error-with-stmts-insertion-in-ipa-prefetch-for-I.patch +Patch294: 0294-Fix-errors-in-ipa-prefetch-IAO50J-and-IAO5H7.patch +Patch295: 0295-Fix-error-with-grouped_load-merge-in-slp-transpose-v.patch +Patch296: 0296-Fix-error-in-slp-transpose-vectorize-for-IAQFM3.patch +Patch297: 0297-Fix-grouped-load-merging-error-in-SLP-transpose-vectorization.patch +Patch298: 0298-Mark-prefetch-builtin-as-willreturn.patch +Patch299: 0299-Backport-Disallow-pointer-operands-for-and-partly-PR.patch +Patch300: 0300-Remove-erroneous-pattern-from-gimple-ifcvt.patch +Patch301: 0301-Add-required-check-for-iteration-through-uses.patch +Patch302: 0302-Added-param-for-optimization-for-merging-bb-s-with-c.patch +Patch303: 0303-Add-generation-of-stream-in-functions-for-pre-versio.patch +Patch304: 0304-Add-multi-version-lto-symbol-parse-cross-lto-units-i.patch +Patch305: 0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch +Patch306: 0306-RISC-V-Install-libstdc-libcc1-etc-to-lib64-instead-o.patch +Patch307: 0307-Set-fallback-value-for-print-multi-os-directory.patch +Patch308: 0308-Fix-enum-INPUT-MIDDLE-FINAL-aes_stage.patch +Patch309: 0309-CSPGO-Add-context-sensitive-PGO.patch +Patch310: 0310-CFGO-Add-cfgo-pgo-optimization.patch +Patch311: 0311-PATCH-Add-if-split-optimization-pass.patch +Patch312: 0312-Add-late-slp-vectorization-pass-with-additional-chec.patch +Patch313: 0313-Add-tracer-transformation-for-static-probabilities.patch +Patch314: 0314-bugfix-Modify-the-hip09-tune-flags.patch +Patch315: 0315-Bugfix-Add-no-var-recored-check-for-ssa_name-in-stru.patch +Patch316: 0316-Use-ai-ability-to-guide-optimization.patch +Patch317: 0317-Bugfix-set-default-value-when-tune_native-is-NULL.patch +Patch318: 0318-add-flag-flto-try.patch +Patch319: 0319-CSPGO-fix-bugs-when-using-cspgo.patch +Patch320: 0320-if-split-fix-bugs.patch + +# Part 1001-1999 +%ifarch sw_64 +Patch1001: 0001-Sw64-Port-add-configure-support-for-sw64.patch +Patch1002: 0002-Sw64-Port-add-gcc-compiler.patch +Patch1003: 0003-Sw64-Port-add-multi-prefetch-support-for-sw64.patch +Patch1004: 0004-Sw64-Port-update-gcc-testsuite-for-sw64.patch +Patch1005: 0005-Sw64-Port-libatomic.patch +Patch1006: 0006-Sw64-Port-libgcc.patch +Patch1007: 0007-Sw64-Port-libffi.patch +Patch1008: 0008-Sw64-Port-libgfortran.patch +Patch1009: 0009-Sw64-Port-libgo.patch +Patch1010: 0010-Sw64-Port-libgomp.patch +Patch1011: 0011-Sw64-Port-libitm.patch +Patch1012: 0012-Sw64-Port-libstdc.patch +Patch1013: 0013-Sw64-Port-set-raise-FPE-when-DivbyZero-on-Sw_64.patch +Patch1014: 0014-Sw64-Port-add-lex-builtin-support-in-libcpp.patch +Patch1015: 0015-Sw64-Port-libsanitizer.patch +Patch1016: 0016-libsanitizer-fix-isoc23-function-interception.patch +Patch1017: 0017-Sw64-Port-Fix-target-explicit_mask.patch +%endif # Part 3000 ~ 4999 %ifarch loongarch64 @@ -678,6 +771,8 @@ Patch3318: 0188-libphobos-Update-build-scripts-for-LoongArch64.patch Patch3319: 0189-LoongArch-fix-building-errors.patch Patch3320: 0190-tree-optimization-110702-avoid-zero-based-memory-ref.patch Patch3321: 0191-LoongArch-Change-OSDIR-for-distribution.patch +Patch3322: Fix-indentation-and-numbering-errors.diff +Patch3323: LoongArch-Allow-attributes-in-non-gnu-namespaces.diff %endif # On ARM EABI systems, we do want -gnueabi to be part of the @@ -1146,548 +1241,642 @@ not stable, so plugins must be rebuilt any time GCC is updated. %prep %setup -q -n gcc-12.3.0 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 -%patch35 -p1 -%patch36 -p1 -%patch37 -p1 -%patch38 -p1 -%patch39 -p1 -%patch40 -p1 -%patch41 -p1 -%patch42 -p1 -%patch43 -p1 -%patch44 -p1 -%patch45 -p1 -%patch46 -p1 -%patch47 -p1 -%patch48 -p1 -%patch49 -p1 -%patch50 -p1 -%patch51 -p1 -%patch52 -p1 -%patch53 -p1 -%patch54 -p1 -%patch55 -p1 -%patch56 -p1 -%patch57 -p1 -%patch86 -p1 -%patch87 -p1 -%patch88 -p1 -%patch89 -p1 -%patch90 -p1 -%patch91 -p1 -%patch92 -p1 -%patch93 -p1 -%patch94 -p1 -%patch95 -p1 -%patch96 -p1 -%patch97 -p1 -%patch98 -p1 -%patch99 -p1 -%patch100 -p1 -%patch101 -p1 -%patch102 -p1 -%patch103 -p1 -%patch104 -p1 -%patch105 -p1 -%patch106 -p1 -%patch107 -p1 -%patch108 -p1 -%patch109 -p1 -%patch110 -p1 -%patch111 -p1 -%patch112 -p1 -%patch113 -p1 -%patch114 -p1 -%patch115 -p1 -%patch116 -p1 -%patch117 -p1 -%patch118 -p1 -%patch119 -p1 -%patch120 -p1 -%patch121 -p1 -%patch122 -p1 -%patch123 -p1 -%patch124 -p1 -%patch125 -p1 -%patch126 -p1 -%patch127 -p1 -%patch128 -p1 -%patch129 -p1 -%patch130 -p1 -%patch131 -p1 -%patch132 -p1 -%patch133 -p1 -%patch134 -p1 -%patch135 -p1 -%patch136 -p1 -%patch137 -p1 -%patch138 -p1 -%patch139 -p1 -%patch140 -p1 -%patch141 -p1 -%patch142 -p1 -%patch143 -p1 -%patch144 -p1 -%patch145 -p1 -%patch146 -p1 -%patch147 -p1 -%patch148 -p1 -%patch149 -p1 -%patch150 -p1 -%patch151 -p1 -%patch152 -p1 -%patch153 -p1 -%patch154 -p1 -%patch155 -p1 -%patch156 -p1 -%patch157 -p1 -%patch158 -p1 -%patch159 -p1 -%patch160 -p1 -%patch161 -p1 -%patch162 -p1 -%patch163 -p1 -%patch164 -p1 -%patch165 -p1 -%patch166 -p1 -%patch167 -p1 -%patch168 -p1 -%patch169 -p1 -%patch170 -p1 -%patch171 -p1 -%patch172 -p1 -%patch173 -p1 -%patch174 -p1 -%patch175 -p1 -%patch176 -p1 -%patch177 -p1 -%patch178 -p1 -%patch179 -p1 -%patch180 -p1 -%patch181 -p1 -%patch182 -p1 -%patch183 -p1 -%patch184 -p1 -%patch185 -p1 -%patch186 -p1 -%patch187 -p1 -%patch188 -p1 -%patch189 -p1 -%patch190 -p1 -%patch191 -p1 -%patch192 -p1 -%patch193 -p1 -%patch194 -p1 -%patch195 -p1 -%patch196 -p1 -%patch197 -p1 -%patch198 -p1 -%patch199 -p1 -%patch200 -p1 -%patch201 -p1 -%patch202 -p1 -%patch203 -p1 -%patch204 -p1 -%patch205 -p1 -%patch206 -p1 -%patch207 -p1 -%patch208 -p1 -%patch209 -p1 -%patch210 -p1 -%patch211 -p1 -%patch212 -p1 -%patch213 -p1 -%patch214 -p1 -%patch215 -p1 -%patch216 -p1 -%patch217 -p1 -%patch218 -p1 -%patch219 -p1 -%patch220 -p1 -%patch221 -p1 -%patch222 -p1 -%patch223 -p1 -%patch224 -p1 -%patch225 -p1 -%patch226 -p1 -%patch227 -p1 -%patch228 -p1 -%patch229 -p1 -%patch230 -p1 -%patch231 -p1 -%patch232 -p1 -%patch233 -p1 -%patch234 -p1 -%patch235 -p1 -%patch236 -p1 -%patch237 -p1 -%patch238 -p1 -%patch239 -p1 -%patch240 -p1 -%patch241 -p1 -%patch242 -p1 -%patch243 -p1 -%patch244 -p1 -%patch245 -p1 -%patch246 -p1 -%patch247 -p1 - +%patch -P1 -p1 +%patch -P2 -p1 +%patch -P3 -p1 +%patch -P4 -p1 +%patch -P6 -p1 +%patch -P7 -p1 +%patch -P8 -p1 +%patch -P9 -p1 +%patch -P10 -p1 +%patch -P11 -p1 +%patch -P12 -p1 +%patch -P13 -p1 +%patch -P14 -p1 +%patch -P15 -p1 +%patch -P16 -p1 +%patch -P17 -p1 +%patch -P18 -p1 +%patch -P19 -p1 +%patch -P20 -p1 +%patch -P21 -p1 +%patch -P22 -p1 +%patch -P23 -p1 +%patch -P24 -p1 +%patch -P25 -p1 +%patch -P26 -p1 +%patch -P27 -p1 +%patch -P28 -p1 +%patch -P29 -p1 +%patch -P30 -p1 +%patch -P31 -p1 +%patch -P32 -p1 +%patch -P33 -p1 +%patch -P34 -p1 +%patch -P35 -p1 +%patch -P36 -p1 +%patch -P37 -p1 +%patch -P38 -p1 +%patch -P39 -p1 +%patch -P40 -p1 +%patch -P41 -p1 +%patch -P42 -p1 +%patch -P43 -p1 +%patch -P44 -p1 +%patch -P45 -p1 +%patch -P46 -p1 +%patch -P47 -p1 +%patch -P48 -p1 +%patch -P49 -p1 +%patch -P50 -p1 +%patch -P51 -p1 +%patch -P52 -p1 +%patch -P53 -p1 +%patch -P54 -p1 +%patch -P55 -p1 +%patch -P56 -p1 +%patch -P57 -p1 +%patch -P86 -p1 +%patch -P87 -p1 +%patch -P88 -p1 +%patch -P89 -p1 +%patch -P90 -p1 +%patch -P91 -p1 +%patch -P92 -p1 +%patch -P93 -p1 +%patch -P94 -p1 +%patch -P95 -p1 +%patch -P96 -p1 +%patch -P97 -p1 +%patch -P98 -p1 +%patch -P99 -p1 +%patch -P100 -p1 +%patch -P101 -p1 +%patch -P102 -p1 +%patch -P103 -p1 +%patch -P104 -p1 +%patch -P105 -p1 +%patch -P106 -p1 +%patch -P107 -p1 +%patch -P108 -p1 +%patch -P109 -p1 +%patch -P110 -p1 +%patch -P111 -p1 +%patch -P112 -p1 +%patch -P113 -p1 +%patch -P114 -p1 +%patch -P115 -p1 +%patch -P116 -p1 +%patch -P117 -p1 +%patch -P118 -p1 +%patch -P119 -p1 +%patch -P120 -p1 +%patch -P121 -p1 +%patch -P122 -p1 +%patch -P123 -p1 +%patch -P124 -p1 +%patch -P125 -p1 +%patch -P126 -p1 +%patch -P127 -p1 +%patch -P128 -p1 +%patch -P129 -p1 +%patch -P130 -p1 +%patch -P131 -p1 +%patch -P132 -p1 +%patch -P133 -p1 +%patch -P134 -p1 +%patch -P135 -p1 +%patch -P136 -p1 +%patch -P137 -p1 +%patch -P138 -p1 +%patch -P139 -p1 +%patch -P140 -p1 +%patch -P141 -p1 +%patch -P142 -p1 +%patch -P143 -p1 +%patch -P144 -p1 +%patch -P145 -p1 +%patch -P146 -p1 +%patch -P147 -p1 +%patch -P148 -p1 +%patch -P149 -p1 +%patch -P150 -p1 +%patch -P151 -p1 +%patch -P152 -p1 +%patch -P153 -p1 +%patch -P154 -p1 +%patch -P155 -p1 +%patch -P156 -p1 +%patch -P157 -p1 +%patch -P158 -p1 +%patch -P159 -p1 +%patch -P160 -p1 +%patch -P161 -p1 +%patch -P162 -p1 +%patch -P163 -p1 +%patch -P164 -p1 +%patch -P165 -p1 +%patch -P166 -p1 +%patch -P167 -p1 +%patch -P168 -p1 +%patch -P169 -p1 +%patch -P170 -p1 +%patch -P171 -p1 +%patch -P172 -p1 +%patch -P173 -p1 +%patch -P174 -p1 +%patch -P175 -p1 +%patch -P176 -p1 +%patch -P177 -p1 +%patch -P178 -p1 +%patch -P179 -p1 +%patch -P180 -p1 +%patch -P181 -p1 +%patch -P182 -p1 +%patch -P183 -p1 +%patch -P184 -p1 +%patch -P185 -p1 +%patch -P186 -p1 +%patch -P187 -p1 +%patch -P188 -p1 +%patch -P189 -p1 +%patch -P190 -p1 +%patch -P191 -p1 +%patch -P192 -p1 +%patch -P193 -p1 +%patch -P194 -p1 +%patch -P195 -p1 +%patch -P196 -p1 +%patch -P197 -p1 +%patch -P198 -p1 +%patch -P199 -p1 +%patch -P200 -p1 +%patch -P201 -p1 +%patch -P202 -p1 +%patch -P203 -p1 +%patch -P204 -p1 +%patch -P205 -p1 +%patch -P206 -p1 +%patch -P207 -p1 +%patch -P208 -p1 +%patch -P209 -p1 +%patch -P210 -p1 +%patch -P211 -p1 +%patch -P212 -p1 +%patch -P213 -p1 +%patch -P214 -p1 +%patch -P215 -p1 +%patch -P216 -p1 +%patch -P217 -p1 +%patch -P218 -p1 +%patch -P219 -p1 +%patch -P220 -p1 +%patch -P221 -p1 +%patch -P222 -p1 +%patch -P223 -p1 +%patch -P224 -p1 +%patch -P225 -p1 +%patch -P226 -p1 +%patch -P227 -p1 +%patch -P228 -p1 +%patch -P229 -p1 +%patch -P230 -p1 +%patch -P231 -p1 +%patch -P232 -p1 +%patch -P233 -p1 +%patch -P234 -p1 +%patch -P235 -p1 +%patch -P236 -p1 +%patch -P237 -p1 +%patch -P238 -p1 +%patch -P239 -p1 +%patch -P240 -p1 +%patch -P241 -p1 +%patch -P242 -p1 +%patch -P243 -p1 +%patch -P244 -p1 +%patch -P245 -p1 +%patch -P246 -p1 +%patch -P247 -p1 +%patch -P248 -p1 +%patch -P249 -p1 +%patch -P250 -p1 +%patch -P251 -p1 +%patch -P252 -p1 +%patch -P253 -p1 +%patch -P254 -p1 +%patch -P255 -p1 +%patch -P256 -p1 +%patch -P257 -p1 +%patch -P258 -p1 +%patch -P259 -p1 +%patch -P260 -p1 +%patch -P261 -p1 +%patch -P262 -p1 +%patch -P263 -p1 +%patch -P264 -p1 +%patch -P265 -p1 +%patch -P266 -p1 +%patch -P267 -p1 +%patch -P268 -p1 +%patch -P269 -p1 +%patch -P270 -p1 +%patch -P271 -p1 +%patch -P272 -p1 +%patch -P273 -p1 +%patch -P274 -p1 +%patch -P275 -p1 +%patch -P276 -p1 +%patch -P277 -p1 +%patch -P278 -p1 +%patch -P279 -p1 +%patch -P280 -p1 +%patch -P281 -p1 +%patch -P282 -p1 +%patch -P283 -p1 +%patch -P284 -p1 +%patch -P285 -p1 +%patch -P286 -p1 +%patch -P287 -p1 +%patch -P288 -p1 +%patch -P289 -p1 +%patch -P290 -p1 +%patch -P291 -p1 +%patch -P292 -p1 +%patch -P293 -p1 +%patch -P294 -p1 +%patch -P295 -p1 +%patch -P296 -p1 +%patch -P297 -p1 +%patch -P298 -p1 +%patch -P299 -p1 +%patch -P300 -p1 +%patch -P301 -p1 +%patch -P302 -p1 +%patch -P303 -p1 +%patch -P304 -p1 +%patch -P305 -p1 +%patch -P306 -p1 +%patch -P307 -p1 +%patch -P308 -p1 +%patch -P309 -p1 +%patch -P310 -p1 +%patch -P311 -p1 +%patch -P312 -p1 +%patch -P313 -p1 +%patch -P314 -p1 +%patch -P315 -p1 +%patch -P316 -p1 +%patch -P317 -p1 +%patch -P318 -p1 +%patch -P319 -p1 +%patch -P320 -p1 + +%ifarch sw_64 +%patch -P1001 -p1 +%patch -P1002 -p1 +%patch -P1003 -p1 +%patch -P1004 -p1 +%patch -P1005 -p1 +%patch -P1006 -p1 +%patch -P1007 -p1 +%patch -P1008 -p1 +%patch -P1009 -p1 +%patch -P1010 -p1 +%patch -P1011 -p1 +%patch -P1012 -p1 +%patch -P1013 -p1 +%patch -P1014 -p1 +%patch -P1015 -p1 +%patch -P1016 -p1 +%patch -P1017 -p1 +%endif %ifarch loongarch64 -%patch3001 -p1 -%patch3002 -p1 -%patch3003 -p1 -%patch3004 -p1 -%patch3005 -p1 -%patch3006 -p1 -%patch3007 -p1 -%patch3008 -p1 -%patch3009 -p1 -%patch3010 -p1 -%patch3011 -p1 -%patch3012 -p1 -%patch3013 -p1 -%patch3014 -p1 -%patch3015 -p1 -%patch3016 -p1 -%patch3017 -p1 -%patch3018 -p1 -%patch3019 -p1 -%patch3020 -p1 -%patch3021 -p1 -%patch3022 -p1 -%patch3023 -p1 -%patch3024 -p1 -%patch3025 -p1 -%patch3026 -p1 -%patch3027 -p1 -%patch3028 -p1 -%patch3029 -p1 -%patch3030 -p1 -%patch3031 -p1 -%patch3032 -p1 -%patch3033 -p1 -%patch3034 -p1 -%patch3035 -p1 -%patch3036 -p1 -%patch3037 -p1 -%patch3038 -p1 -%patch3039 -p1 -%patch3040 -p1 -%patch3041 -p1 -%patch3042 -p1 -%patch3043 -p1 -%patch3044 -p1 -%patch3045 -p1 -%patch3046 -p1 -%patch3047 -p1 -%patch3048 -p1 -%patch3049 -p1 -%patch3050 -p1 -%patch3051 -p1 -%patch3052 -p1 -%patch3053 -p1 -%patch3054 -p1 -%patch3056 -p1 -%patch3057 -p1 -%patch3058 -p1 -%patch3059 -p1 -%patch3060 -p1 -%patch3061 -p1 -%patch3062 -p1 -%patch3063 -p1 -%patch3064 -p1 -%patch3065 -p1 -%patch3066 -p1 -%patch3067 -p1 -%patch3068 -p1 -%patch3069 -p1 -%patch3070 -p1 -%patch3071 -p1 -%patch3072 -p1 -%patch3073 -p1 -%patch3074 -p1 -%patch3075 -p1 -%patch3076 -p1 -%patch3077 -p1 -%patch3078 -p1 -%patch3079 -p1 -%patch3080 -p1 -%patch3081 -p1 -%patch3082 -p1 -%patch3083 -p1 -%patch3084 -p1 -%patch3085 -p1 -%patch3086 -p1 -%patch3087 -p1 -%patch3088 -p1 -%patch3089 -p1 -%patch3090 -p1 -%patch3091 -p1 -%patch3092 -p1 -%patch3093 -p1 -%patch3094 -p1 -%patch3095 -p1 -%patch3096 -p1 -%patch3097 -p1 -%patch3098 -p1 -%patch3099 -p1 -%patch3100 -p1 -%patch3101 -p1 -%patch3102 -p1 -%patch3103 -p1 -%patch3104 -p1 -%patch3105 -p1 -%patch3106 -p1 -%patch3107 -p1 -%patch3108 -p1 -%patch3109 -p1 -%patch3110 -p1 -%patch3111 -p1 -%patch3112 -p1 -%patch3113 -p1 -%patch3114 -p1 -%patch3115 -p1 -%patch3116 -p1 -%patch3117 -p1 -%patch3118 -p1 -%patch3119 -p1 -%patch3120 -p1 -%patch3121 -p1 -%patch3122 -p1 -%patch3123 -p1 -%patch3124 -p1 -%patch3125 -p1 -%patch3126 -p1 -%patch3127 -p1 -%patch3128 -p1 -%patch3129 -p1 -%patch3130 -p1 +%patch -P3001 -p1 +%patch -P3002 -p1 +%patch -P3003 -p1 +%patch -P3004 -p1 +%patch -P3005 -p1 +%patch -P3006 -p1 +%patch -P3007 -p1 +%patch -P3008 -p1 +%patch -P3009 -p1 +%patch -P3010 -p1 +%patch -P3011 -p1 +%patch -P3012 -p1 +%patch -P3013 -p1 +%patch -P3014 -p1 +%patch -P3015 -p1 +%patch -P3016 -p1 +%patch -P3017 -p1 +%patch -P3018 -p1 +%patch -P3019 -p1 +%patch -P3020 -p1 +%patch -P3021 -p1 +%patch -P3022 -p1 +%patch -P3023 -p1 +%patch -P3024 -p1 +%patch -P3025 -p1 +%patch -P3026 -p1 +%patch -P3027 -p1 +%patch -P3028 -p1 +%patch -P3029 -p1 +%patch -P3030 -p1 +%patch -P3031 -p1 +%patch -P3032 -p1 +%patch -P3033 -p1 +%patch -P3034 -p1 +%patch -P3035 -p1 +%patch -P3036 -p1 +%patch -P3037 -p1 +%patch -P3038 -p1 +%patch -P3039 -p1 +%patch -P3040 -p1 +%patch -P3041 -p1 +%patch -P3042 -p1 +%patch -P3043 -p1 +%patch -P3044 -p1 +%patch -P3045 -p1 +%patch -P3046 -p1 +%patch -P3047 -p1 +%patch -P3048 -p1 +%patch -P3049 -p1 +%patch -P3050 -p1 +%patch -P3051 -p1 +%patch -P3052 -p1 +%patch -P3053 -p1 +%patch -P3054 -p1 +%patch -P3056 -p1 +%patch -P3057 -p1 +%patch -P3058 -p1 +%patch -P3059 -p1 +%patch -P3060 -p1 +%patch -P3061 -p1 +%patch -P3062 -p1 +%patch -P3063 -p1 +%patch -P3064 -p1 +%patch -P3065 -p1 +%patch -P3066 -p1 +%patch -P3067 -p1 +%patch -P3068 -p1 +%patch -P3069 -p1 +%patch -P3070 -p1 +%patch -P3071 -p1 +%patch -P3072 -p1 +%patch -P3073 -p1 +%patch -P3074 -p1 +%patch -P3075 -p1 +%patch -P3076 -p1 +%patch -P3077 -p1 +%patch -P3078 -p1 +%patch -P3079 -p1 +%patch -P3080 -p1 +%patch -P3081 -p1 +%patch -P3082 -p1 +%patch -P3083 -p1 +%patch -P3084 -p1 +%patch -P3085 -p1 +%patch -P3086 -p1 +%patch -P3087 -p1 +%patch -P3088 -p1 +%patch -P3089 -p1 +%patch -P3090 -p1 +%patch -P3091 -p1 +%patch -P3092 -p1 +%patch -P3093 -p1 +%patch -P3094 -p1 +%patch -P3095 -p1 +%patch -P3096 -p1 +%patch -P3097 -p1 +%patch -P3098 -p1 +%patch -P3099 -p1 +%patch -P3100 -p1 +%patch -P3101 -p1 +%patch -P3102 -p1 +%patch -P3103 -p1 +%patch -P3104 -p1 +%patch -P3105 -p1 +%patch -P3106 -p1 +%patch -P3107 -p1 +%patch -P3108 -p1 +%patch -P3109 -p1 +%patch -P3110 -p1 +%patch -P3111 -p1 +%patch -P3112 -p1 +%patch -P3113 -p1 +%patch -P3114 -p1 +%patch -P3115 -p1 +%patch -P3116 -p1 +%patch -P3117 -p1 +%patch -P3118 -p1 +%patch -P3119 -p1 +%patch -P3120 -p1 +%patch -P3121 -p1 +%patch -P3122 -p1 +%patch -P3123 -p1 +%patch -P3124 -p1 +%patch -P3125 -p1 +%patch -P3126 -p1 +%patch -P3127 -p1 +%patch -P3128 -p1 +%patch -P3129 -p1 +%patch -P3130 -p1 #-- -%patch3131 -p1 -%patch3132 -p1 -%patch3133 -p1 -%patch3134 -p1 -%patch3135 -p1 -%patch3136 -p1 -%patch3137 -p1 -%patch3138 -p1 -%patch3139 -p1 -%patch3140 -p1 -%patch3141 -p1 -%patch3142 -p1 -%patch3143 -p1 -%patch3144 -p1 -%patch3145 -p1 -%patch3146 -p1 -%patch3147 -p1 -%patch3148 -p1 -%patch3149 -p1 -%patch3150 -p1 -%patch3151 -p1 -%patch3152 -p1 -%patch3153 -p1 -%patch3154 -p1 -%patch3155 -p1 -%patch3156 -p1 -%patch3157 -p1 -%patch3158 -p1 -%patch3159 -p1 -%patch3160 -p1 -%patch3161 -p1 -%patch3162 -p1 -%patch3163 -p1 -%patch3164 -p1 -%patch3165 -p1 -%patch3166 -p1 -%patch3167 -p1 -%patch3168 -p1 -%patch3169 -p1 -%patch3170 -p1 -%patch3171 -p1 -%patch3172 -p1 -%patch3173 -p1 -%patch3174 -p1 -%patch3175 -p1 -%patch3176 -p1 -%patch3177 -p1 -%patch3178 -p1 -%patch3179 -p1 -%patch3180 -p1 -%patch3181 -p1 -%patch3182 -p1 -%patch3183 -p1 -%patch3184 -p1 -%patch3185 -p1 -%patch3186 -p1 -%patch3187 -p1 -%patch3188 -p1 -%patch3189 -p1 -%patch3190 -p1 -%patch3191 -p1 -%patch3192 -p1 -%patch3193 -p1 -%patch3194 -p1 -%patch3195 -p1 -%patch3196 -p1 -%patch3197 -p1 -%patch3198 -p1 -%patch3199 -p1 -%patch3200 -p1 -%patch3201 -p1 -%patch3202 -p1 -%patch3203 -p1 -%patch3204 -p1 -%patch3205 -p1 -%patch3206 -p1 -%patch3207 -p1 -%patch3208 -p1 -%patch3209 -p1 -%patch3210 -p1 -%patch3211 -p1 -%patch3212 -p1 -%patch3213 -p1 -%patch3214 -p1 -%patch3215 -p1 -%patch3216 -p1 -%patch3217 -p1 -%patch3218 -p1 -%patch3219 -p1 -%patch3220 -p1 -%patch3221 -p1 -%patch3222 -p1 -%patch3223 -p1 -%patch3224 -p1 -%patch3225 -p1 -%patch3226 -p1 -%patch3227 -p1 -%patch3228 -p1 -%patch3229 -p1 -%patch3230 -p1 -%patch3231 -p1 -%patch3232 -p1 -%patch3233 -p1 -%patch3234 -p1 -%patch3235 -p1 -%patch3236 -p1 -%patch3237 -p1 -%patch3238 -p1 -%patch3239 -p1 -%patch3240 -p1 -%patch3241 -p1 -%patch3242 -p1 -%patch3243 -p1 -%patch3244 -p1 -%patch3245 -p1 -%patch3246 -p1 -%patch3247 -p1 -%patch3248 -p1 -%patch3249 -p1 -%patch3250 -p1 -%patch3251 -p1 -%patch3252 -p1 -%patch3253 -p1 -%patch3254 -p1 -%patch3255 -p1 -%patch3256 -p1 -%patch3257 -p1 -%patch3258 -p1 -%patch3259 -p1 -%patch3260 -p1 -%patch3261 -p1 -%patch3262 -p1 -%patch3263 -p1 -%patch3264 -p1 -%patch3265 -p1 -%patch3266 -p1 -%patch3267 -p1 -%patch3268 -p1 -%patch3269 -p1 -%patch3270 -p1 -%patch3271 -p1 -%patch3272 -p1 -%patch3273 -p1 -%patch3274 -p1 -%patch3275 -p1 -%patch3276 -p1 -%patch3277 -p1 -%patch3278 -p1 -%patch3279 -p1 -%patch3280 -p1 -%patch3281 -p1 -%patch3282 -p1 -%patch3283 -p1 -%patch3284 -p1 -%patch3285 -p1 -%patch3286 -p1 -%patch3287 -p1 -%patch3288 -p1 -%patch3289 -p1 -%patch3290 -p1 -%patch3291 -p1 -%patch3292 -p1 -%patch3293 -p1 -%patch3294 -p1 -%patch3295 -p1 -%patch3296 -p1 -%patch3297 -p1 -%patch3298 -p1 -%patch3299 -p1 -%patch3300 -p1 -%patch3301 -p1 -%patch3302 -p1 -%patch3303 -p1 -%patch3304 -p1 -%patch3305 -p1 -%patch3306 -p1 -%patch3307 -p1 -%patch3308 -p1 -%patch3309 -p1 -%patch3310 -p1 -%patch3311 -p1 -%patch3312 -p1 -%patch3313 -p1 -%patch3314 -p1 -%patch3315 -p1 -%patch3316 -p1 -%patch3317 -p1 -%patch3318 -p1 -%patch3319 -p1 -%patch3320 -p1 -%patch3321 -p1 +%patch -P3131 -p1 +%patch -P3132 -p1 +%patch -P3133 -p1 +%patch -P3134 -p1 +%patch -P3135 -p1 +%patch -P3136 -p1 +%patch -P3137 -p1 +%patch -P3138 -p1 +%patch -P3139 -p1 +%patch -P3140 -p1 +%patch -P3141 -p1 +%patch -P3142 -p1 +%patch -P3143 -p1 +%patch -P3144 -p1 +%patch -P3145 -p1 +%patch -P3146 -p1 +%patch -P3147 -p1 +%patch -P3148 -p1 +%patch -P3149 -p1 +%patch -P3150 -p1 +%patch -P3151 -p1 +%patch -P3152 -p1 +%patch -P3153 -p1 +%patch -P3154 -p1 +%patch -P3155 -p1 +%patch -P3156 -p1 +%patch -P3157 -p1 +%patch -P3158 -p1 +%patch -P3159 -p1 +%patch -P3160 -p1 +%patch -P3161 -p1 +%patch -P3162 -p1 +%patch -P3163 -p1 +%patch -P3164 -p1 +%patch -P3165 -p1 +%patch -P3166 -p1 +%patch -P3167 -p1 +%patch -P3168 -p1 +%patch -P3169 -p1 +%patch -P3170 -p1 +%patch -P3171 -p1 +%patch -P3172 -p1 +%patch -P3173 -p1 +%patch -P3174 -p1 +%patch -P3175 -p1 +%patch -P3176 -p1 +%patch -P3177 -p1 +%patch -P3178 -p1 +%patch -P3179 -p1 +%patch -P3180 -p1 +%patch -P3181 -p1 +%patch -P3182 -p1 +%patch -P3183 -p1 +%patch -P3184 -p1 +%patch -P3185 -p1 +%patch -P3186 -p1 +%patch -P3187 -p1 +%patch -P3188 -p1 +%patch -P3189 -p1 +%patch -P3190 -p1 +%patch -P3191 -p1 +%patch -P3192 -p1 +%patch -P3193 -p1 +%patch -P3194 -p1 +%patch -P3195 -p1 +%patch -P3196 -p1 +%patch -P3197 -p1 +%patch -P3198 -p1 +%patch -P3199 -p1 +%patch -P3200 -p1 +%patch -P3201 -p1 +%patch -P3202 -p1 +%patch -P3203 -p1 +%patch -P3204 -p1 +%patch -P3205 -p1 +%patch -P3206 -p1 +%patch -P3207 -p1 +%patch -P3208 -p1 +%patch -P3209 -p1 +%patch -P3210 -p1 +%patch -P3211 -p1 +%patch -P3212 -p1 +%patch -P3213 -p1 +%patch -P3214 -p1 +%patch -P3215 -p1 +%patch -P3216 -p1 +%patch -P3217 -p1 +%patch -P3218 -p1 +%patch -P3219 -p1 +%patch -P3220 -p1 +%patch -P3221 -p1 +%patch -P3222 -p1 +%patch -P3223 -p1 +%patch -P3224 -p1 +%patch -P3225 -p1 +%patch -P3226 -p1 +%patch -P3227 -p1 +%patch -P3228 -p1 +%patch -P3229 -p1 +%patch -P3230 -p1 +%patch -P3231 -p1 +%patch -P3232 -p1 +%patch -P3233 -p1 +%patch -P3234 -p1 +%patch -P3235 -p1 +%patch -P3236 -p1 +%patch -P3237 -p1 +%patch -P3238 -p1 +%patch -P3239 -p1 +%patch -P3240 -p1 +%patch -P3241 -p1 +%patch -P3242 -p1 +%patch -P3243 -p1 +%patch -P3244 -p1 +%patch -P3245 -p1 +%patch -P3246 -p1 +%patch -P3247 -p1 +%patch -P3248 -p1 +%patch -P3249 -p1 +%patch -P3250 -p1 +%patch -P3251 -p1 +%patch -P3252 -p1 +%patch -P3253 -p1 +%patch -P3254 -p1 +%patch -P3255 -p1 +%patch -P3256 -p1 +%patch -P3257 -p1 +%patch -P3258 -p1 +%patch -P3259 -p1 +%patch -P3260 -p1 +%patch -P3261 -p1 +%patch -P3262 -p1 +%patch -P3263 -p1 +%patch -P3264 -p1 +%patch -P3265 -p1 +%patch -P3266 -p1 +%patch -P3267 -p1 +%patch -P3268 -p1 +%patch -P3269 -p1 +%patch -P3270 -p1 +%patch -P3271 -p1 +%patch -P3272 -p1 +%patch -P3273 -p1 +%patch -P3274 -p1 +%patch -P3275 -p1 +%patch -P3276 -p1 +%patch -P3277 -p1 +%patch -P3278 -p1 +%patch -P3279 -p1 +%patch -P3280 -p1 +%patch -P3281 -p1 +%patch -P3282 -p1 +%patch -P3283 -p1 +%patch -P3284 -p1 +%patch -P3285 -p1 +%patch -P3286 -p1 +%patch -P3287 -p1 +%patch -P3288 -p1 +%patch -P3289 -p1 +%patch -P3290 -p1 +%patch -P3291 -p1 +%patch -P3292 -p1 +%patch -P3293 -p1 +%patch -P3294 -p1 +%patch -P3295 -p1 +%patch -P3296 -p1 +%patch -P3297 -p1 +%patch -P3298 -p1 +%patch -P3299 -p1 +%patch -P3300 -p1 +%patch -P3301 -p1 +%patch -P3302 -p1 +%patch -P3303 -p1 +%patch -P3304 -p1 +%patch -P3305 -p1 +%patch -P3306 -p1 +%patch -P3307 -p1 +%patch -P3308 -p1 +%patch -P3309 -p1 +%patch -P3310 -p1 +%patch -P3311 -p1 +%patch -P3312 -p1 +%patch -P3313 -p1 +%patch -P3314 -p1 +%patch -P3315 -p1 +%patch -P3316 -p1 +%patch -P3317 -p1 +%patch -P3318 -p1 +%patch -P3319 -p1 +%patch -P3320 -p1 +%patch -P3321 -p1 +%patch -P3322 -p1 +%patch -P3323 -p1 %endif echo '%{_vendor} %{version}-%{release}' > gcc/DEV-PHASE @@ -1798,6 +1987,10 @@ CONFIGURE_OPTS="\ --with-arch=loongarch64 --with-abi=lp64d \ --disable-libquadmath --disable-multilib --enable-tls \ --enable-default-pie +%endif +%ifarch sw_64 + --with-cpu=sw6b --disable-libquadmath --disable-multilib \ + --enable-tls %endif " @@ -2067,7 +2260,7 @@ mkdir -p %{buildroot}/%{_lib} mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}.so.1 chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}.so.1 ln -sf libgcc_s-%{gcc_major}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1 -%ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} aarch64 riscv64 loongarch64 +%ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} aarch64 riscv64 loongarch64 sw_64 rm -f $FULLPATH/libgcc_s.so echo '/* GNU ld script Use the shared library, but some functions are only in @@ -2170,7 +2363,7 @@ mv ../../../libasan_preinit.o libasan_preinit.o %if %{build_libubsan} ln -sf ../../../libubsan.so.1.* libubsan.so %endif -%ifarch loongarch64 +%ifarch loongarch64 sw_64 %if %{build_libtsan} rm -f libtsan.so echo 'INPUT ( %{_prefix}/%{_lib}/'`echo ../../../../%{_lib}/libtsan.so.2.* | sed 's,^.*libt,libt,'`' )' > libtsan.so @@ -2964,6 +3157,7 @@ end %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/lto-wrapper %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/liblto_plugin.so* %{_libdir}/bfd-plugins/liblto_plugin.so +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/onnx.fdata %ifarch aarch64 %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/libbolt_plugin.so* %endif @@ -3077,10 +3271,13 @@ end %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxtileintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxint8intrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxbf16intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxfp16intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxcomplexintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/x86gprintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/uintrintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/hresetintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/keylockerintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/prfchiintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avxvnniintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mwaitintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512fp16intrin.h @@ -3151,6 +3348,10 @@ end %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/htmxlintrin.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vecintrin.h %endif +%ifarch sw_64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/include/config/sw_64/sw_64-protos.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/include/config/sw_64/sw_64.h +%endif %if %{build_libasan} %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/sanitizer %endif @@ -3953,6 +4154,114 @@ end %doc rpm.doc/changelogs/libcc1/ChangeLog* %changelog +* Sat Dec 07 2024 huzife <634763349@qq.com> - 12.3.1-56 +- Type:Bugfix +- ID:NA +- SUG:NA +- DESC: Fix bugs for if-split. + +* Wed Dec 04 2024 liyancheng <412998149@qq.com> - 12.3.1-55 +- Type:Bugfix +- ID:NA +- SUG:NA +- DESC: Fix bugs for cspgo. + +* Wed Dec 04 2024 Zhenyu Zhao - 12.3.1-54 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Sync patches from openeuler/gcc. + +* Wed Dec 04 2024 Zhenyu Zhao - 12.3.1-53 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Sync patches from openeuler/gcc. + +* Wed Dec 04 2024 Zhenyu Zhao - 12.3.1-52 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Bugfix add no var recored check for ssa_name in struct reorg. + +* Wed Dec 04 2024 Mingchuan Wu - 12.3.1-51 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Sync [late-SLP], [tracer-opt], [bugfix4hip09] patches from openeuler/gcc. + +* Thu Nov 28 2024 swcompiler - 12.3.1-50 +- Type: Sw64 +- DESC: +- Add sw64 architecture support. + +* Wed Nov 27 2024 liyancheng <412998149@qq.com> - 12.3.1-49 +- Type: Sync +- DESC: Add if split optimization + +* Wed Nov 27 2024 Peng Fan - 12.3.1-48 +- Type: BUGFIX +- DESC: +- LoongArch: Allow attributes in non-gnu namespaces. + +* Wed Nov 27 2024 liyancheng <412998149@qq.com> - 12.3.1-47 +- Type: Sync +- DESC: Add cfgo-pgo optimization + +* Wed Nov 27 2024 liyancheng <412998149@qq.com> - 12.3.1-46 +- Type: Sync +- DESC: Add context sensitive PGO + +* Mon Nov 25 2024 Peng Fan - 12.3.1-45 +- Type: BUGFIX +- DESC: +- Fix indentation and numbering errors in makefile. + +* Thu Nov 21 2024 jchzhou - 12.3.1-44 +- Type: Sync +- DESC: Sync patches for fixing building issues with clang +- Source: https://gitee.com/openeuler/gcc/pulls/239 + +* Thu Nov 21 2024 YunQiang Su - 12.3.1-43 +- Type: Sync +- DESC: RISC-V: Install libstdc++/libcc1 etc to /lib64 instead of lib + +* Thu Nov 21 2024 Feiyang Liu - 12.3.1-42 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Sync backport patch varasm-Handle-private-COMDAT from upstream. + +* Thu Nov 21 2024 liyancheng <412998149@qq.com> - 12.3.1-41 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Multi-version lto symbol parse and lto units ipa-inline extension + +* Thu Nov 21 2024 liyancheng <412998149@qq.com> - 12.3.1-40 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Add missing header file for x86 + +* Thu Nov 21 2024 huangzifeng - 12.3.1-39 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Sync patches from openeuler/gcc + +* Thu Nov 21 2024 huangzifeng - 12.3.1-38 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Sync patches from branch openEuler-24.09 + +* Wed Nov 20 2024 Hu,Lin1 - 12.3.1-37 +- Type:Sync +- ID:NA +- SUG:NA +- DESC: Sync some patch from src-openEuler/gcc's openeuler-24.09 + * Tue Nov 19 2024 eastb233 - 12.3.1-36 - Type:Sync - ID:NA