aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/ChangeLog4
-rw-r--r--config/gthr.m427
-rw-r--r--gcc/ChangeLog781
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/Makefile.in2
-rw-r--r--gcc/alias.c63
-rw-r--r--gcc/basic-block.h1
-rw-r--r--gcc/c-family/ChangeLog23
-rw-r--r--gcc/c-family/c-ada-spec.c73
-rw-r--r--gcc/c-family/c-opts.c10
-rw-r--r--gcc/c-family/c.opt8
-rw-r--r--gcc/calls.c9
-rw-r--r--gcc/cfgbuild.c25
-rw-r--r--gcc/cfgexpand.c2
-rw-r--r--gcc/cfgloop.h4
-rw-r--r--gcc/cfgloopmanip.c21
-rw-r--r--gcc/cfgrtl.c29
-rw-r--r--gcc/combine.c30
-rw-r--r--gcc/common.opt8
-rw-r--r--gcc/common/config/rs6000/rs6000-common.c57
-rw-r--r--gcc/config.gcc7
-rw-r--r--gcc/config/arm/arm-arches.def1
-rw-r--r--gcc/config/arm/arm-fpus.def34
-rw-r--r--gcc/config/arm/arm-tables.opt18
-rw-r--r--gcc/config/arm/arm.c24
-rw-r--r--gcc/config/arm/arm.h10
-rw-r--r--gcc/config/arm/arm.md12
-rw-r--r--gcc/config/arm/arm_neon.h32
-rw-r--r--gcc/config/arm/bpabi.h2
-rw-r--r--gcc/config/arm/cortex-a15-neon.md1215
-rw-r--r--gcc/config/arm/cortex-a15.md34
-rw-r--r--gcc/config/arm/neon-docgen.ml2
-rw-r--r--gcc/config/arm/neon-gen.ml24
-rw-r--r--gcc/config/arm/neon-testgen.ml22
-rw-r--r--gcc/config/arm/neon.md56
-rw-r--r--gcc/config/arm/neon.ml10
-rw-r--r--gcc/config/arm/thumb2.md3
-rw-r--r--gcc/config/avr/avr-arch.h1
-rw-r--r--gcc/config/avr/avr-c.c4
-rw-r--r--gcc/config/avr/avr.c4
-rw-r--r--gcc/config/bfin/bfin.md4
-rw-r--r--gcc/config/c6x/c6x.md4
-rw-r--r--gcc/config/i386/darwin.h4
-rw-r--r--gcc/config/i386/i386.c151
-rw-r--r--gcc/config/i386/i386.h86
-rw-r--r--gcc/config/i386/i386.md118
-rw-r--r--gcc/config/i386/sse.md103
-rw-r--r--gcc/config/ia64/ia64.md3
-rw-r--r--gcc/config/iq2000/iq2000.h4
-rw-r--r--gcc/config/linux-android.h4
-rw-r--r--gcc/config/mep/mep.md6
-rw-r--r--gcc/config/rs6000/aix43.h2
-rw-r--r--gcc/config/rs6000/aix51.h2
-rw-r--r--gcc/config/rs6000/aix52.h2
-rw-r--r--gcc/config/rs6000/aix53.h2
-rw-r--r--gcc/config/rs6000/aix61.h2
-rw-r--r--gcc/config/rs6000/aix64.opt4
-rw-r--r--gcc/config/rs6000/altivec.md38
-rw-r--r--gcc/config/rs6000/darwin.opt4
-rw-r--r--gcc/config/rs6000/freebsd.h2
-rw-r--r--gcc/config/rs6000/freebsd64.h17
-rw-r--r--gcc/config/rs6000/linux.h2
-rw-r--r--gcc/config/rs6000/linux64.h33
-rw-r--r--gcc/config/rs6000/option-defaults.h5
-rw-r--r--gcc/config/rs6000/predicates.md6
-rw-r--r--gcc/config/rs6000/rs6000-c.c30
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def51
-rw-r--r--gcc/config/rs6000/rs6000.c236
-rw-r--r--gcc/config/rs6000/rs6000.h58
-rw-r--r--gcc/config/rs6000/rs6000.md33
-rw-r--r--gcc/config/rs6000/rs6000.opt61
-rw-r--r--gcc/config/rs6000/sync.md15
-rw-r--r--gcc/config/rs6000/sysv4.h31
-rw-r--r--gcc/config/rs6000/sysv4.opt18
-rw-r--r--gcc/config/rs6000/t-rs60003
-rw-r--r--gcc/config/s390/s390.md3
-rw-r--r--gcc/config/sh/iterators.md1
-rw-r--r--gcc/config/sh/predicates.md17
-rw-r--r--gcc/config/sh/sh-protos.h19
-rw-r--r--gcc/config/sh/sh.c169
-rw-r--r--gcc/config/sh/sh.md231
-rw-r--r--gcc/config/spu/spu.md3
-rw-r--r--gcc/config/tilegx/tilegx.md3
-rw-r--r--gcc/config/tilepro/tilepro.md3
-rwxr-xr-xgcc/configure8
-rw-r--r--gcc/configure.ac8
-rw-r--r--gcc/cp/ChangeLog55
-rw-r--r--gcc/cp/call.c50
-rw-r--r--gcc/cp/class.c90
-rw-r--r--gcc/cp/cp-tree.h18
-rw-r--r--gcc/cp/decl.c5
-rw-r--r--gcc/cp/error.c5
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/method.c212
-rw-r--r--gcc/cp/name-lookup.c13
-rw-r--r--gcc/cp/parser.c15
-rw-r--r--gcc/cp/pt.c58
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cse.c24
-rw-r--r--gcc/cselib.c21
-rw-r--r--gcc/cselib.h2
-rw-r--r--gcc/data-streamer-in.c29
-rw-r--r--gcc/data-streamer-out.c33
-rw-r--r--gcc/data-streamer.h7
-rw-r--r--gcc/df-problems.c34
-rw-r--r--gcc/doc/arm-neon-intrinsics.texi180
-rw-r--r--gcc/doc/extend.texi42
-rw-r--r--gcc/doc/install.texi2
-rw-r--r--gcc/doc/invoke.texi4
-rw-r--r--gcc/doc/md.texi20
-rw-r--r--gcc/doc/options.texi21
-rw-r--r--gcc/dojump.c20
-rw-r--r--gcc/dse.c43
-rw-r--r--gcc/dwarf2out.c8
-rw-r--r--gcc/except.c10
-rw-r--r--gcc/expr.c47
-rw-r--r--gcc/expr.h6
-rw-r--r--gcc/flags.h8
-rw-r--r--gcc/fortran/ChangeLog24
-rw-r--r--gcc/fortran/resolve.c71
-rw-r--r--gcc/fortran/trans-expr.c356
-rw-r--r--gcc/fortran/trans-stmt.c6
-rw-r--r--gcc/fortran/trans.h6
-rw-r--r--gcc/gcse.c7
-rw-r--r--gcc/genoutput.c66
-rw-r--r--gcc/gimplify.c13
-rw-r--r--gcc/ifcvt.c2
-rw-r--r--gcc/loop-doloop.c14
-rw-r--r--gcc/loop-invariant.c18
-rw-r--r--gcc/loop-iv.c10
-rw-r--r--gcc/loop-unswitch.c1
-rw-r--r--gcc/lto-streamer-in.c4
-rw-r--r--gcc/lto-streamer-out.c5
-rw-r--r--gcc/lto-streamer.h3
-rw-r--r--gcc/opt-functions.awk16
-rw-r--r--gcc/optabs.c28
-rw-r--r--gcc/optc-gen.awk84
-rw-r--r--gcc/opth-gen.awk8
-rw-r--r--gcc/opts.c13
-rw-r--r--gcc/postreload-gcse.c7
-rw-r--r--gcc/regcprop.c15
-rw-r--r--gcc/reload.c285
-rw-r--r--gcc/rtl.h5
-rw-r--r--gcc/rtlanal.c16
-rw-r--r--gcc/sched-deps.c10
-rw-r--r--gcc/stmt.c404
-rw-r--r--gcc/testsuite/ChangeLog196
-rw-r--r--gcc/testsuite/c-c++-common/tm/pr54893.c16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C15
-rw-r--r--gcc/testsuite/g++.dg/init/array30.C7
-rw-r--r--gcc/testsuite/g++.dg/init/array31.C10
-rw-r--r--gcc/testsuite/g++.dg/other/dump-ada-spec-2.C11
-rw-r--r--gcc/testsuite/g++.dg/overload/operator6.C27
-rw-r--r--gcc/testsuite/g++.dg/parse/tmpl-outside1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/tmpl-outside2.C19
-rw-r--r--gcc/testsuite/g++.dg/template/pr29633.C29
-rw-r--r--gcc/testsuite/g++.dg/template/qualttp18.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local-cse.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local-wrap4.C1
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local7g.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/predcom-1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/enum6.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/enum9.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/enum4.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/overload13.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr54925.c27
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-overflow-24.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-apply2.c3
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54796.c25
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54920.c13
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr54915.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/ftest-armv8a-arm.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/ftest-armv8a-thumb.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/ftest-support-arm.h3
-rw-r--r--gcc/testsuite/gcc.target/arm/ftest-support-thumb.h3
-rw-r--r--gcc/testsuite/gcc.target/arm/ftest-support.h1
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vfmaQf32.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vfmaf32.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vfmsQf32.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vfmsf32.c22
-rw-r--r--gcc/testsuite/gcc.target/arm/synchronize.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-load-3.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_2.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_3.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_4.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_5.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_6.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_2.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_3.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_4.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_5.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_6.c8
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-17.c297
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54760-2.c226
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54760-4.c19
-rw-r--r--gcc/testsuite/gcc.target/sh/torture/pr34777.c30
-rw-r--r--gcc/testsuite/gcc.target/sh/torture/sh-torture.exp41
-rw-r--r--gcc/testsuite/gfortran.dg/class_optional_1.f90175
-rw-r--r--gcc/testsuite/gfortran.dg/class_optional_2.f90800
-rw-r--r--gcc/testsuite/gfortran.dg/do_1.f903
-rw-r--r--gcc/testsuite/gfortran.dg/enum_10.f902
-rw-r--r--gcc/testsuite/gfortran.dg/enum_9.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr54889.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/public_private_module_7.f9029
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization13.adb21
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization13.ads17
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization13_pkg.ads5
-rw-r--r--gcc/testsuite/gnat.dg/unchecked_convert9.adb15
-rw-r--r--gcc/testsuite/gnat.dg/unchecked_convert9.ads20
-rw-r--r--gcc/testsuite/lib/target-supports.exp9
-rw-r--r--gcc/trans-mem.c87
-rw-r--r--gcc/tree-ssa-forwprop.c2
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c283
-rw-r--r--gcc/tree-ssa-pre.c2
-rw-r--r--gcc/tree-streamer-in.c120
-rw-r--r--gcc/tree-streamer-out.c64
-rw-r--r--gcc/tree-vect-stmts.c16
-rw-r--r--gcc/tree.c9
-rw-r--r--gcc/tree.h10
-rw-r--r--gcc/var-tracking.c44
-rw-r--r--gcc/web.c32
-rw-r--r--libcpp/ChangeLog8
-rw-r--r--libcpp/files.c2
-rw-r--r--libcpp/lex.c1
-rw-r--r--libcpp/mkdeps.c14
-rw-r--r--libcpp/pch.c1
-rw-r--r--libgcc/ChangeLog13
-rw-r--r--libgcc/config.host2
-rw-r--r--libgcc/config/arm/lib1funcs.S4
-rw-r--r--libgcc/configure4
-rw-r--r--libgcc/configure.ac14
-rw-r--r--libjava/ChangeLog5
-rwxr-xr-xlibjava/configure2
-rw-r--r--libjava/configure.ac2
-rw-r--r--libstdc++-v3/ChangeLog151
-rw-r--r--libstdc++-v3/Makefile.in4
-rw-r--r--libstdc++-v3/acinclude.m45
-rwxr-xr-xlibstdc++-v3/configure36
-rw-r--r--libstdc++-v3/configure.host2
-rw-r--r--libstdc++-v3/doc/Makefile.in4
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2011.xml3
-rw-r--r--libstdc++-v3/include/Makefile.am2
-rw-r--r--libstdc++-v3/include/Makefile.in6
-rw-r--r--libstdc++-v3/include/bits/forward_list.h91
-rw-r--r--libstdc++-v3/include/bits/forward_list.tcc40
-rw-r--r--libstdc++-v3/include/bits/move.h5
-rw-r--r--libstdc++-v3/include/debug/formatter.h7
-rw-r--r--libstdc++-v3/include/debug/macros.h18
-rw-r--r--libstdc++-v3/include/debug/unordered_map96
-rw-r--r--libstdc++-v3/include/debug/unordered_set96
-rw-r--r--libstdc++-v3/include/std/array11
-rw-r--r--libstdc++-v3/include/std/chrono5
-rw-r--r--libstdc++-v3/include/std/tuple26
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in12
-rw-r--r--libstdc++-v3/libsupc++/atexit_thread.cc151
-rw-r--r--libstdc++-v3/po/Makefile.in4
-rw-r--r--libstdc++-v3/python/Makefile.in4
-rw-r--r--libstdc++-v3/src/Makefile.in4
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in4
-rw-r--r--libstdc++-v3/src/c++11/debug.cc5
-rw-r--r--libstdc++-v3/src/c++98/Makefile.in4
-rw-r--r--libstdc++-v3/testsuite/20_util/forward/c_neg.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/forward/f_neg.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/move_if_noexcept/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/comparison_operators/35480_neg.cc3
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/comparison_operators/constexpr.cc29
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc46
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc4
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc55
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy_assign.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc47
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/noexcept.cc76
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/bucket_size_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/cbegin_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/cend_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/end1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/end2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cend_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/bucket_size_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cbegin_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cend_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/max_load_factor_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/bucket_size_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/cbegin_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/cend_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/end1_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/end2_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/debug/max_load_factor_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/Makefile.in4
339 files changed, 10710 insertions, 2068 deletions
diff --git a/config/ChangeLog b/config/ChangeLog
index 7db0c6b04..c74839ac3 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2012-10-15 Pavel Chupin <pavel.v.chupin@intel.com>
+
+ * gthr.m4: New. Define GCC_AC_THREAD_HEADER.
+
2012-09-19 Steve Ellcey <sellcey@mips.com>
* mt-sde: Change -mcode-xonly to -mcode-readable=pcrel.
diff --git a/config/gthr.m4 b/config/gthr.m4
new file mode 100644
index 000000000..7b29f1f33
--- /dev/null
+++ b/config/gthr.m4
@@ -0,0 +1,27 @@
+dnl Copyright (C) 2012 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl Define header location by thread model
+
+dnl usage: GCC_AC_THREAD_HEADER([thread_model])
+AC_DEFUN([GCC_AC_THREAD_HEADER],
+[
+case $1 in
+ aix) thread_header=config/rs6000/gthr-aix.h ;;
+ dce) thread_header=config/pa/gthr-dce.h ;;
+ lynx) thread_header=config/gthr-lynx.h ;;
+ mipssde) thread_header=config/mips/gthr-mipssde.h ;;
+ posix) thread_header=gthr-posix.h ;;
+ rtems) thread_header=config/gthr-rtems.h ;;
+ single) thread_header=gthr-single.h ;;
+ tpf) thread_header=config/s390/gthr-tpf.h ;;
+ vxworks) thread_header=config/gthr-vxworks.h ;;
+ win32) thread_header=config/i386/gthr-win32.h ;;
+esac
+AC_SUBST(thread_header)
+])
+
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 82427de24..bc35544c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,783 @@
+2012-10-19 Alan Modra <amodra@gmail.com>
+
+ * configure.ac (HAVE_LD_NO_DOT_SYMS): Set if using gold.
+ (HAVE_LD_LARGE_TOC): Likewise.
+ * configure: Regenerate.
+
+2012-10-19 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/predicates.md (splat_input_operand): Don't call
+ input_operand for MEMs. Instead check for volatile and call
+ memory_address_addr_space_p with modified mode.
+
+2012-10-18 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (rdpmc): Remove expander.
+ (rdtsc): Ditto.
+ (rdtscp): Ditto.
+ (rdpmc): Rename from *rdpmc.
+ (rdpmc_rex64): Rename from *rdpmc_rex64.
+ (rdtsc): Rename from *rdtsc.
+ (rdtsc_rex64): Rename from *rdtsc_rex64.
+ (rdtscp): Rename from *rdtscp.
+ (rdtscp_rex64): Rename from *rdtscp_rex64.
+
+ * config/i386/i386.c (struct builtin_description bdesc_special_args)
+ <IX86_BUILTIN_RDTSC>: Use CODE_FOR_NOTHING.
+ <IX86_BUILTIN_RDTSCP>: Ditto.
+ (struct builtin_description bdesc__args) <IX86_BUILTIN_RDPMC>: Ditto.
+ (ix86_expand_builtin) <IX86_BUILTIN_{RDPMC,RDTSC,RDTSCP}>: Handle here.
+
+2012-10-18 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * config/sh/sh.c: Fix comment to silence warning.
+
+2012-10-18 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+ Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+ Sameera Deshpande <sameera.deshpande@arm.com>
+
+ * config/arm/cortex-a15-neon.md: New file.
+ * config/arm/cortex-a15.md (cortex_a15_call): Adjust reservation.
+ (cortex_a15_load1): Likewise.
+ (cortex_a15_load3): Likewise.
+ (cortex_a15_store1): Likewise.
+ (cortex_a15_store3): Likewise.
+ (cortex-a15-neon.md): Include.
+
+2012-10-18 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/altivec.md (altivec_lvsl, altivec_lvsr): Add mode.
+ (altivec_vsumsws_nomode): Delete.
+ (reduc_splus_<mode>, reduc_uplus_<mode>): Call gen_altivec_vsumsws
+ instead of gen_altivec_vsumsws_nomode.
+ (altivec_lvlx, altivec_lvlxl, altivec_lvrx, altivec_lvrxl): Add mode.
+ * config/rs6000/rs6000.md (probe_stack): Rename to...
+ (probe_stack_<mode>): ... this. Add mode. Change pattern to
+ use std instead of stw when appropriate.
+ (probe_stack): New expander.
+ (move_from_CR_ov_bit): Add mode.
+ (splitter for compare_plus_ne0_<mode>, splitter for
+ compare_plus_ne0_<mode>_1): Remove constraints.
+ * config/rs6000/sync.md (loadsync): Rename to...
+ (loadsync_<mode>): ... this. Add mode.
+ (atomic_load<mode>): Adjust.
+
+2012-10-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * loop-invariant.c: Include target.h.
+ (check_dependency): Return false for an uninitialized argument register
+ that is likely to be spilled.
+ * Makefile.in (loop-invariant.o): Add $(TARGET_H).
+
+2012-10-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * except.c (sjlj_emit_function_enter): Remove unused variable.
+
+2012-10-18 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+ Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * config/arm/arm.c (neon_builtin_data): Add vfma and vfms builtins.
+ * config/arm/neon-docgen.ml (intrinsic_groups): Add
+ fused-multiply-* groups.
+ * config/neon-gen.ml (print_feature_test_start): New function.
+ (print_feature_test_end): Likewise.
+ (print_variant): Print feature test macros.
+ * config/arm/neon-testgen.ml (emit_prologue): Allow different
+ tests to require different effective targets.
+ (effective_target): New function.
+ (test_intrinsic): Specify correct effective targets.
+ * gcc/config/arm/neon.md (fma<VCVTF:mode>4_intrinsic): New pattern.
+ (fmsub<VCVTF:mode>4_intrinsic): Likewise.
+ (neon_vfma<VCVFT:mode>): New expand.
+ (neon_vfms<VCVFT:mode>): Likewise.
+ * config/neon.ml (opcode): Add Vfma and Vfms.
+ (features): Add Requires_feature.
+ (ops): Add VFMA and VFMS intrinsics.
+ * config/arm/arm_neon.h: Regenerate.
+ * doc/arm-neon-intrinsics.texi: Likewise.
+
+2012-10-18 Richard Guenther <rguenther@suse.de>
+
+ * lto-streamer.h (enum LTO_tags): Add LTO_integer_cst.
+ * lto-streamer-in.c (lto_input_tree): Use it.
+ * lto-streamer-out.c (lto_output_tree): Likewise, for
+ !TREE_OVERFLOW integer constants only.
+ * tree-streamer-in.c (unpack_ts_int_cst_value_fields): New function.
+ (unpack_value_fields): Call it.
+ (streamer_read_integer_cst): Simplify.
+ * tree-streamer-out.c (pack_ts_int_cst_value_fields): New function.
+ (streamer_pack_tree_bitfields): Call it.
+ (streamer_write_integer_cst): Adjust.
+
+2012-10-18 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+ Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * config.gcc: Add support for ARMv8 for arm*-*-* targets.
+ * config/arm/arm-arches.def: Add armv8-a
+ * config/arm/arm-fpus.def: Add fp-armv8, neon-fp-armv8,
+ crypto-neon-fp-armv8. Add crypto field.
+ * config/arm/arm-tables.opt: Regenerate.
+ * config/arm/arm.c (FL_FOR_ARCH8A): Likewise.
+ (arm_arch8): New global variable.
+ (ARM_FPU): Add crypto parameter.
+ (arm_option_override): Set arm_arch8, update comments.
+ * config/arm/arm.h (TARGET_CRYPTO): New macro.
+ (arm_fpu_desc): Add crypto field.
+ (base_architecture): Add ARMv8 entry.
+ (arm_arch8): New variable declaration.
+ * config/arm/bpabi.h: ARMv8 supports BE8.
+ * doc/invoke.texi: Document ARMv8 options.
+
+2012-10-17 Aldy Hernandez <aldyh@redhat.com>
+
+ PR middle-end/54893
+ * trans-mem.c (diagnose_tm_1_op): Allow volatiles inside relaxed
+ transactions.
+
+2012-10-17 Aldy Hernandez <aldyh@redhat.com>
+
+ PR rtl-optimization/54900
+ * ifcvt.c (noce_can_store_speculate_p): Call
+ memory_must_be_modified_in_insn_p.
+ * alias.c (memory_must_be_modified_in_insn_p): New.
+ (set_dest_equal_p): New.
+ * rtl.h (memory_must_be_modified_in_p): Protoize.
+
+2012-10-17 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.opt (rs6000_isa_flags): New flag word to
+ replace target_flags that gives us 63 possible switches.
+ (x_rs6000_isa_flags): Save area for rs6000_isa_flags.
+ (x_rs6000_isa_flags_explicit): Save area for rs6000_isa_flags_explicit.
+ (rs6000_target_flags_explicit): Delete in favor of
+ x_rs6000_isa_flags_explicit.
+ (-mpowerpc64): Change all switches that used to be in target_flags
+ to now be in rs6000_isa_flags. In using rs6000_isa_flags, the
+ options machinary will generate names of the form OPITON_<xxx>
+ instead of TARGET_<xxx> and OPTION_MASK_<xxx> instead of MASK_<xxx>.
+ (-mpowerpc-gpopt): Likewise.
+ (-mpowerpc-gfxopt): Likewise.
+ (-mmfcrf): Likewise.
+ (-mpopcntb): Likewise.
+ (-mfprnd): Likewise.
+ (-mcmpb): Likewise.
+ (-mmfpgpr): Likewise.
+ (-maltivec): Likewise.
+ (-mhard-dfp): Likewise.
+ (-mmulhw): Likewise.
+ (-mdlmzb): Likewise.
+ (-mmultiple): Likewise.
+ (-mstring): Likewise.
+ (-msoft-float): Likewise.
+ (-mhard-float): Likewise.
+ (-mpopcntd): Likewise.
+ (-mvsx): Likewise.
+ (-mno-update): Likewise.
+ (-mupdate): Likewise.
+ (-mrecip-precision): Likewise.
+ (-mminimal-toc): Likewise.
+ (-misel): Likewise.
+ * config/rs6000/aix64.opt (-maix64): Likewise.
+ (-maix32): Likewise.
+ * config/rs6000/sysv4.opt (-mstrict-align): Likewise.
+ (-mrelocatable): Likewise.
+ (-mlittle-endian): Likewise.
+ (-mlittle): Likewise.
+ (-mbig-endian): LIkewise.
+ (-mbig): Likewise.
+ (-meabi): Likewise.
+ (-m64): Likewise.
+ (-m32): Likewise.
+ * config/rs6000/darwin.opt (-m64): Likewise.
+ (-m32): Likewise.
+
+ * config/rs6000/rs6000-cpus.def (ISA_2_1_MASKS): Move the various
+ masks used in rs6000.c here, since they are more logically in this
+ file. Convert from being enums to just #defines, since the types
+ of these masks is now HOST_WIDE_INT instead of int. For
+ POWERPC_MASKS, add MASK_SOFT_FLOAT, since the only use case or'ed
+ in the mask. Change the use in rs6000.c not to do the OR of
+ MASK_SOFT_FLOAT.
+ (ISA_2_1_MASKS): Likewise.
+ (ISA_2_2_MASKS): Likewise.
+ (ISA_2_4_MASKS): Likewise.
+ (ISA_2_5_MASKS_EMBEDDED): Likewise.
+ (ISA_2_5_MASKS_SERVER): Likewise.
+ (POWERPC_7400_MASK): Likewise.
+ (POWERPC_MASKS): Likewise.
+ * config/rs6000/rs6000.c (ISA_2_1_MASKS): Likewise.
+ (ISA_2_1_MASKS): Likewise.
+ (ISA_2_2_MASKS): Likewise.
+ (ISA_2_4_MASKS): Likewise.
+ (ISA_2_5_MASKS_EMBEDDED): Likewise.
+ (ISA_2_5_MASKS_SERVER): Likewise.
+ (POWERPC_7400_MASK): Likewise.
+ (POWERPC_MASKS): Likewise.
+ (rs6000_option_override_internal): Likewise.
+
+ * config/rs6000/rs6000.c (darwin_rs6000_override_options): Change
+ all uses of target_flags to rs6000_isa_flags. Change all uses of
+ target_flags_explicit to rs6000_isa_flags_explicit. Change the
+ use of MASK_<xxx> to OPTION_MASK_<xxx> that options.h defines when
+ we use a secondary flags word. Save/restore/print the new flags
+ word when switching contexts with different target attributes.
+ (rs6000_option_override_internal): Likewise.
+ (rs6000_darwin_file_start): Likewise.
+ (rs6000_opt_masks): Likewise.
+ (rs6000_inner_target_options): Likewise.
+ (rs6000_pragma_target_parse): Likewise.
+ (rs6000_set_current_function): Likewise.
+ (rs6000_function_specific_save): Likewise.
+ (rs6000_function_specific_restore): Likewise.
+ (rs6000_function_specific_print): Likewise.
+ (rs6000_can_inline_p): Likewise.
+ * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Likewise.
+ (rs6000_cpu_cpp_builtins): Likewise.
+ * common/config/rs6000/rs6000-driver.c (rs6000_handle_option):
+ Likewise.
+
+ * config/rs6000/rs6000.h (MASK_ALTIVEC): In moving to using
+ Var(...) for all of the isa switches, the options machinery now
+ uses OPTION_MASK_<xxx> instead of MASK_<xxx> for the mask name.
+ Use #define to map the old name into the new name. For switches
+ that are defined in aix64.opt, sysv4.opt, and darwin.opt, only do
+ the definition if those switches were defined.
+ (MASK_ALTIVEC): Likewise.
+ (MASK_CMPB): Likewise.
+ (MASK_DFP): Likewise.
+ (MASK_DLMZB): Likewise.
+ (MASK_EABI): Likewise.
+ (MASK_FPRND): Likewise.
+ (MASK_HARD_FLOAT): Likewise.
+ (MASK_ISEL): Likewise.
+ (MASK_MFCRF): Likewise.
+ (MASK_MFPGPR): Likewise.
+ (MASK_MULHW): Likewise.
+ (MASK_MULTIPLE): Likewise.
+ (MASK_NO_UPDATE): Likewise.
+ (MASK_POPCNTB): Likewise.
+ (MASK_POPCNTD): Likewise.
+ (MASK_PPC_GFXOPT): Likewise.
+ (MASK_PPC_GPOPT): Likewise.
+ (MASK_RECIP_PRECISION): Likewise.
+ (MASK_SOFT_FLOAT): Likewise.
+ (MASK_STRICT_ALIGN): Likewise.
+ (MASK_STRING): Likewise.
+ (MASK_UPDATE): Likewise.
+ (MASK_VSX): Likewise.
+ (MASK_POWERPC64): Likewise.
+ (MASK_64BIT): Likewise.
+ (MASK_RELOCATABLE): Likewise.
+ (MASK_LITTLE_ENDIAN): Likewise.
+ (MASK_MINIMAL_TOC): Likewise.
+ (MASK_REGNAMES): Likewise.
+ (MASK_PROTOTYPE): Likewise.
+ (rs6000_isa_flags_explicit): Define in terms of the
+ global_options_set structure.
+
+ * gcc/config/rs6000/aix43.h (SUBTARGET_OVERRIDE_OPTIONS):
+ Change use of target_flags to rs6000_isa_flags, target_flags_explicit
+ to rs6000_isa_flags_explicit, and MASK_<xxx> to OPTION_MASK_<xxx>.
+ * gcc/config/rs6000/aix51.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ * gcc/config/rs6000/aix52.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ * gcc/config/rs6000/aix53.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ * gcc/config/rs6000/aix61.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ * gcc/config/rs6000/freebsd64.h (RELOCATABLE_NEEDS_FIXUP): Likewise.
+ (SUBSUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ * gcc/config/rs6000/freebsd.h (RELOCATABLE_NEEDS_FIXUP): Likewise.
+ * gcc/config/rs6000/linux64.h (RELOCATABLE_NEEDS_FIXUP): Likewise.
+ (SUBSUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ (OPTION_LITTLE_ENDIAN): Likewise.
+ (OPTION_RELOCATABLE): Likewise.
+ (OPTION_EABI): Likewise.
+ (OPTION_PROTOTYPE): Likewise.
+ * gcc/config/rs6000/linux.h (RELOCATABLE_NEEDS_FIXUP): Likewise.
+ * gcc/config/rs6000/option-defaults.h (OPTION_MASK_64BIT): Likewise.
+ (OPT_ARCH32): Likewise.
+ (OPT_ARCH64): Likewise.
+ * gcc/config/rs6000/sysv4.h (TARGET_TOC): Likewise.
+ (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ (SUBSUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ (TARGET_OS_SYSV_CPP_BUILTINS): Likewise.
+
+ * config/rs6000/t-rs6000 (rs6000.o): Add rs6000-cpus.def as a
+ dependency.
+
+2012-10-17 Jan Hubicka <jh@suse.cz>
+
+ * cfgloopmanip.c (copy_loop_info): New function.
+ (duplicate_loop): Use it.
+ (loop_version): Use it.
+ * loop-unswitch.c (unswitch_loop): Use it.
+ * cfgloop.h (copy_loop_info): Declare.
+
+2012-10-17 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-loop-ivcanon.c (tree_estimate_loop_size): Add edge_to_cancel
+ parameter and use it to estimate code optimized out in the final
+ iteration.
+ (loop_edge_to_cancel): New function.
+ (try_unroll_loop_completely): New IRRED_IVALIDATED parameter;
+ handle unrolling loops with bounds given via max_loop_iteratins;
+ handle unrolling non-inner loops when code size shrinks;
+ tidy dump output; when the last iteration loop still stays
+ as loop in the CFG forcongly redirect the latch to
+ __builtin_unreachable.
+ (canonicalize_loop_induction_variables): Add irred_invlaidated
+ parameter; record niter bound derrived; dump
+ max_loop_iterations bounds; call try_unroll_loop_completely
+ even if no niter bound is given.
+ (canonicalize_induction_variables): Handle irred_invalidated.
+ (tree_unroll_loops_completely): Handle non-innermost loops;
+ handle irred_invalidated.
+ * cfgloop.h (unlop): Declare.
+ * cfgloopmanip.c (unloop): Export.
+ * tree.c (build_common_builtin_nodes): Build BULTIN_UNREACHABLE.
+
+2012-10-17 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * opth-gen.awk (TARGET_* generation): Always generate TARGET_<xxx>
+ for Mask options, whether they use Var(...) or not.
+
+ * config/linux-android.h (ANDROID_TARGET_OS_CPP_BUILTINS): Use
+ TARGET_<xxx> instead of OPTION_<xxx>.
+ * config/i386/i386.h (TARGET_64BIT): Likewise.
+ (TARGET_MMX): Likewise.
+ (TARGET_3DNOW): Likewise.
+ (TARGET_3DNOW_A): Likewise.
+ (TARGET_SSE): Likewise.
+ (TARGET_SSE2): Likewise.
+ (TARGET_SSE3): Likewise.
+ (TARGET_SSSE3): Likewise.
+ (TARGET_SSE4_1): Likewise.
+ (TARGET_SSE4_2): Likewise.
+ (TARGET_AVX): Likewise.
+ (TARGET_AVX2): Likewise.
+ (TARGET_FMA): Likewise.
+ (TARGET_SSE4A): Likewise.
+ (TARGET_FMA4): Likewise.
+ (TARGET_XOP): Likewise.
+ (TARGET_LWP): Likewise.
+ (TARGET_ROUND): Likewise.
+ (TARGET_ABM): Likewise.
+ (TARGET_BMI): Likewise.
+ (TARGET_BMI2): Likewise.
+ (TARGET_LZCNT): Likewise.
+ (TARGET_TBM): Likewise.
+ (TARGET_POPCNT): Likewise.
+ (TARGET_SAHF): Likewise.
+ (TARGET_MOVBE): Likewise.
+ (TARGET_CRC32): Likewise.
+ (TARGET_AES): Likewise.
+ (TARGET_PCLMUL): Likewise.
+ (TARGET_CMPXCHG16B): Likewise.
+ (TARGET_FSGSBASE): Likewise.
+ (TARGET_RDRND): Likewise.
+ (TARGET_F16C): Likewise.
+ (TARGET_RTM ): Likewise.
+ (TARGET_HLE): Likewise.
+ (TARGET_RDSEED): Likewise.
+ (TARGET_PRFCHW): Likewise.
+ (TARGET_ADX): Likewise.
+ (TARGET_64BIT): Likewise.
+ (TARGET_MMX): Likewise.
+ (TARGET_3DNOW): Likewise.
+ (TARGET_3DNOW_A): Likewise.
+ (TARGET_SSE): Likewise.
+ (TARGET_SSE2): Likewise.
+ (TARGET_SSE3): Likewise.
+ (TARGET_SSSE3): Likewise.
+ (TARGET_SSE4_1): Likewise.
+ (TARGET_SSE4_2): Likewise.
+ (TARGET_AVX): Likewise.
+ (TARGET_AVX2): Likewise.
+ (TARGET_FMA): Likewise.
+ (TARGET_SSE4A): Likewise.
+ (TARGET_FMA4): Likewise.
+ (TARGET_XOP): Likewise.
+ (TARGET_LWP): Likewise.
+ (TARGET_ROUND): Likewise.
+ (TARGET_ABM): Likewise.
+ (TARGET_BMI): Likewise.
+ (TARGET_BMI2): Likewise.
+ (TARGET_LZCNT): Likewise.
+ (TARGET_TBM): Likewise.
+ (TARGET_POPCNT): Likewise.
+ (TARGET_SAHF): Likewise.
+ (TARGET_MOVBE): Likewise.
+ (TARGET_CRC32): Likewise.
+ (TARGET_AES): Likewise.
+ (TARGET_PCLMUL): Likewise.
+ (TARGET_CMPXCHG16B): Likewise.
+ (TARGET_FSGSBASE): Likewise.
+ (TARGET_RDRND): Likewise.
+ (TARGET_F16C): Likewise.
+ (TARGET_RTM): Likewise.
+ (TARGET_HLE): Likewise.
+ (TARGET_RDSEED): Likewise.
+ (TARGET_PRFCHW): Likewise.
+ (TARGET_ADX): Likewise.
+ (TARGET_LP64): Likewise.
+ (TARGET_X32): Likewise.
+ (TARGET_ISA_ROUND): Likewise.
+ * config/i386/darwin.h (TARGET_64BIT): Likewise.
+
+ * doc/options.texi (Mask): Update documentation to specify only
+ TARGET_<xxx> is generated.
+
+2012-10-17 Greta Yorsh <Greta.Yorsh@arm.com>
+
+ * config/arm/arm.md (UNSPEC_PROLOGUE_USE): Rename this...
+ (UNSPEC_REGISTER_USE): ... to this.
+ (prologue_use): Rename this...
+ (force_register_use): ... to this and update output assembly.
+ (epilogue) Rename gen_prologue_use to gen_force_register_use.
+ * config/arm/arm.c (arm_expand_prologue): Likewise.
+ (thumb1_expand_epilogue): Likewise.
+ (arm_expand_epilogue): Likewise.
+ (arm_expand_epilogue): Likewise.
+
+2012-10-17 Georg-Johann Lay <avr@gjlay.de>
+
+ * config/avr/avr-arch.h (avr_extra_arch_macro): Remove prototype.
+ * config/avr/avr.c (avr_extra_arch_macro): Remove variable.
+ (avr_option_override): Remove setting of avr_extra_arch_macro.
+ * config/avr/avr-c.c (avr_extra_arch_macro): Replace with
+ avr_current_device->macro.
+
+2012-10-17 Richard Biener <rguenther@suse.de>
+
+ * tree-streamer-out.c (write_ts_decl_common_tree_pointers):
+ Do not write TREE_CHAIN of PARM_DECLs.
+ (write_ts_decl_non_common_tree_pointers): Instead stream
+ the DECL_ARGUMENTS chain.
+ * tree-streamer-in.c (lto_input_ts_decl_common_tree_pointers):
+ Do not read TREE_CHAIN of PARM_DECLs.
+ (lto_input_ts_decl_non_common_tree_pointes): Instead read
+ the DECL_ARGUMENTS as chain.
+
+2012-10-17 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/iq2000/iq2000.h (call_used_regs): Remove definition.
+
+2012-10-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/54870
+ * tree.h (TREE_ADDRESSABLE): Document special usage on SSA_NAME.
+ * cfgexpand.c (update_alias_info_with_stack_vars ): Set it on the
+ SSA_NAME pointer that points to a partition if there is at least
+ one variable with it set in the partition.
+ * dse.c (local_variable_can_escape): New predicate.
+ (can_escape): Call it.
+ * gimplify.c (mark_addressable): If this is a partitioned decl, also
+ mark the SSA_NAME pointer that points to a partition.
+
+2012-10-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * df-problems.c (df_kill_notes): Split up in two functions.
+ (df_remove_dead_and_unused_notes): New function, first half of
+ df_kill notes to remove all REG_DEAD and REG_UNUSED notes.
+ (df_remove_dead_eq_notes): New function, second half of df_kill_notes
+ to remove REG_EQUAL and REG_EQUIV notes referring to dead registers.
+ (df_note_bb_compute): Call df_remove_dead_and_unused_notes instead
+ of df_kill_notes. Call df_remove_dead_eq_notes after processing insn.
+
+ * web.c (web): Re-add DF_RD_PRUNE_DEAD_DEFS;
+
+2012-10-16 Ian Lance Taylor <iant@google.com>
+
+ * doc/extend.texi (Return Address): Change
+ __builtin_extract_return_address to
+ __builtin_extract_return_addr.
+
+2012-10-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * rtl.h (get_call_rtx_from): New prototype.
+ * rtlanal.c (get_call_rtx_from): New function.
+ * calls.c (emit_call_1): Use it.
+ * dse.c (scan_insn): Likewise
+ * dwarf2out.c (dwarf2out_var_location): Likewise.
+ * sched-deps.c (call_may_noreturn_p): Likewise.
+ * var-tracking.c (prepare_call_arguments): Likewise.
+ * config/sh/sh.c (sh_adjust_cost): Likewise.
+
+2012-10-16 Tom de Vries <tom@codesourcery.com>
+
+ * expr.c (move_by_pieces, move_by_pieces_ninsns, can_store_by_pieces)
+ (store_by_pieces_1): Don't enter loop when no more data is left.
+
+2012-10-16 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * loop-doloop.c (doloop_modify): Pass doloop_end pattern to
+ gen_doloop_begin.
+ (doloop_optimize): Pass flag to indicate if loop is entered at top
+ to gen_doloop_end.
+ * config/arm/thumb2.md (doloop_end): Accept extra operand.
+ * config/bfin/bfin.md (doloop_end): Likewise.
+ * config/c6x/c6x.md (doloop_end): Likewise.
+ * config/ia64/ia64.md (doloop_end): Likewise.
+ * config/mep/mep.md (doloop_begin, doloop_end): Likewise.
+ * config/rs6000/rs6000.md (doloop_end): Likewise.
+ * config/s390/s390.md (doloop_end): Likewise.
+ * config/sh/sh.md (doloop_end): Likewise.
+ * config/spu/spu.md (doloop_end): Likewise.
+ * config/tilegx/tilegx.md (doloop_end): Likewise.
+ * config/tilepro/tilepro.md (doloop_end): Likewise.
+ * doc/md.texi (doloop_end): Document new operand.
+ * basic-block.h (contains_no_active_insn_p): Declare.
+ * cfgrtl.c (contains_no_active_insn_p): New function, factored
+ out of ...
+ (forwarder_block_p): ... here.
+
+2012-10-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/53063
+ PR c/40989
+ * doc/options.texi (EnabledBy): Document new form.
+ * optc-gen.awk: Handle new form of EnabledBy.
+ * common.opt (Wunused-but-set-parameter): Use EnabledBy.
+ (Wunused-parameter): Likewise.
+ * opts.c (finish_options): Do not handle them explicitly.
+ * opt-functions.awk (search_var_name): New.
+
+2012-10-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/53063
+ PR c/40989
+ * optc-gen.awk: Handle new form of LangEnabledBy.
+ * opts.c (set_Wstrict_aliasing): Declare here. Make static.
+ * common.opt (Wstrict-aliasing=,Wstrict-overflow=): Do not use Init.
+ * doc/options.texi (LangEnabledBy): Document new form.
+ * flags.h (set_Wstrict_aliasing): Do not declare.
+
+2012-10-16 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * reload.c (find_reloads_subreg_address): Remove FORCE_REPLACE
+ parameter. Always replace normal subreg with memory reference
+ whenever possible. Return NULL otherwise.
+ (find_reloads_toplev): Always call find_reloads_subreg_address
+ for subregs of registers equivalent to a memory location.
+ Only recurse further if find_reloads_subreg_address fails.
+ (find_reloads_address_1): Only call find_reloads_subreg_address
+ for subregs of registers equivalent to a memory location.
+ Properly handle failure of find_reloads_subreg_address.
+
+2012-10-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/54796
+ * rtl.h: Document jump flag on VALUE.
+ * cselib.h (cselib_set_value_sp_based,
+ cselib_sp_based_value_p): New prototypes.
+ * alias.c (find_base_term): For cselib_sp_based_value_p
+ return static_reg_base_value[STACK_POINTER_REGNUM].
+ * cselib.c (SP_BASED_VALUE_P): Define.
+ (cselib_set_value_sp_based, cselib_sp_based_value_p): New functions.
+ * var-tracking.c (add_stores): Call cselib_set_value_sp_based
+ for not yet preserved VALUEs of sp on sp assignments if
+ hard_frame_pointer_adjustment != -1.
+ (vt_initialize): When setting hard_frame_pointer_adjustment,
+ disassociate sp from its previous value and call
+ cselib_set_value_sp_based on a new VALUE created for sp.
+
+ PR tree-optimization/54889
+ * tree-vect-stmts.c (vectorizable_load): Add VIEW_CONVERT_EXPR if
+ ARRAY_REF newref doesn't have compatible type with vectype element
+ type, use vectype element type for MEM_REF.
+
+2012-10-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * combine.c (record_dead_and_set_regs): Iterate over hard register set
+ with a hard_reg_set_iterator.
+ * cse.c (invalidate_for_call): Likewise.
+ * gcse.c (compute_hash_table_work): Likewise.
+ * loop-iv.c (simplify_using_initial_values): Likewise.
+ * postreload-gcse.c (record_opr_changes): Likewise.
+ * regcprop.c (copyprop_hardreg_forward_1): Likewise.
+ * var-tracking.c (dataflow_set_clear_at_call): Likewise.
+
+2012-10-15 Easwaran Raman <eraman@google.com>
+
+ * optabs.c (emit_cmp_and_jump_insn_1): Add a new parameter to
+ specificy the probability of taking the jump.
+ (emit_cmp_and_jump_insns): Likewise.
+ (expand_compare_and_swap_loop): Make the jump predicted not taken.
+ * dojump.c (do_compare_rtx_and_jump): Remove the code attaching
+ REG_BR_PROB note and pass probability to emit_cmp_and_jump_insns.
+ * cfgbuild.c (compute_outgoing_frequencies): Do not guess outgoing
+ probabilities for branches with more than two successors.
+ * expr.c (emit_block_move_via_loop): Predict the loop backedge loop
+ to be highly taken.
+ (try_casesi): Pass the probability of jumping to the default label.
+ (try_tablejump): Likewise.
+ (do_tablejump): Likewise.
+ * expr.h (try_tablejump): Add a new parameter.
+ (try_casesi): Likewise.
+ (emit_cmp_and_jump_insns): Add probability as default parameter with a
+ default value of -1.
+ * except.c (sjlj_emit_function_enter): Pass probability to
+ emit_cmp_and_jump_insns.
+ * stmt.c (case_node): Add new fields PROB and SUBTREE_PROB.
+ (do_jump_if_equal): Pass probability for REG_BR_PROB note.
+ (add_case_node): Pass estimated probability of jumping to the case
+ label.
+ (emit_case_decision_tree): Pass default_prob to emit_case_nodes.
+ (get_outgoing_edge_probs): New function.
+ (conditional_probability): Likewise.
+ (reset_out_edges_aux): Likewise.
+ (compute_cases_per_edge): Likewise.
+ (emit_case_dispatch_table): Update probabilities of edges coming out
+ of the switch statement.
+ (expand_case): Compute and propagate default edge probability to
+ emit_case_dispatch_table.
+ (expand_sjlj_dispatch_table): Update calls to add_case_node and
+ emit_case_dispatch_table.
+ (balance_case_nodes): Update subtree_prob values.
+ (emit_case_nodes): Compute edge probabilities and add pass them to
+ emit_cmp_and_jump_insns.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * config/sh/sh-protos.h (set_of_reg): New struct.
+ (sh_find_set_of_reg, sh_is_logical_t_store_expr,
+ sh_try_omit_signzero_extend): Declare...
+ * config/sh/sh.c (sh_find_set_of_reg, sh_is_logical_t_store_expr,
+ sh_try_omit_signzero_extend): ...these new functions.
+ * config/sh/sh.md (*logical_op_t): New insn_and_split.
+ (*zero_extend<mode>si2_compact): Use sh_try_omit_signzero_extend
+ in splitter.
+ (*extend<mode>si2_compact_reg): Convert to insn_and_split.
+ Use sh_try_omit_signzero_extend in splitter.
+ (*mov<mode>_reg_reg): Disallow t_reg_operand as operand 1.
+ (*cbranch_t): Rewrite combine part in splitter using new
+ sh_find_set_of_reg function.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54760
+ * config/sh/sh.c (sh_find_base_reg_disp): Stop searching insns when
+ hitting a call insn if GBR is marked as call used.
+ * config/sh/iterators.md (QIHISIDI): New mode iterator.
+ * config/sh/predicates.md (gbr_address_mem): New predicate.
+ * config/sh/sh.md (*movdi_gbr_load, *movdi_gbr_store): New
+ insn_and_split. Use QIHISIDI instead of QIHISI in unnamed GBR
+ addressing splits.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.c: Update function attribute comments.
+ * doc/extend.texi (function_vector): Rephrase SH2A specific part.
+ (nosave_low_regs, renesas, trapa_handler): Document SH specific
+ attributes.
+ (sp_switch, trap_exit): Add to index.
+
+2012-10-15 Matthias Klose <doko@ubuntu.com>
+
+ * config.gcc: Match arm*-*-linux-* for ARM Linux/GNU.
+ * doc/install.texi: Use arm-*-*linux-* instead of arm-*-*linux-gnueabi.
+
+2012-10-15 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/sse.md (UNSPEC_MOVU): Remove.
+ (UNSPEC_LOADU): New.
+ (UNSPEC_STOREU): Ditto.
+ (<sse>_movu<ssemodesuffix><avxsizesuffix>): Split to ...
+ (<sse>_loadu<ssemodesuffix><avxsizesuffix>): ... this and ...
+ (<sse>_storeu<ssemodesuffix><avxsizesuffix>) ... this.
+ (<sse2>_movdqu<avxsizesuffix>): Split to ...
+ (<sse2>_loaddqu<avxsizesuffix>): ... this and ...
+ (<sse2>_storedqu<avxsizesuffix>): ... this.
+ (*sse4_2_pcmpestr_unaligned): Update.
+ (*sse4_2_pcmpistr_unaligned): Ditto.
+
+ * config/i386/i386.c (ix86_avx256_split_vector_move_misalign): Use
+ gen_avx_load{dqu,ups,upd}256 to load from unaligned memory and
+ gen_avx_store{dqu,ups,upd}256 to store to unaligned memory.
+ (ix86_expand_vector_move_misalign): Use gen_sse_loadups or
+ gen_sse2_load{dqu,upd} to load from unaligned memory and
+ gen_sse_loadups or gen_sse2_store{dqu,upd}256 to store to
+ unaligned memory.
+ (struct builtin_description bdesc_spec) <IX86_BUILTIN_LOADUPS>:
+ Use CODE_FOR_sse_loadups.
+ <IX86_BUILTIN_LOADUPD>: Use CODE_FOR_sse2_loadupd.
+ <IX86_BUILTIN_LOADDQU>: Use CODE_FOR_sse2_loaddqu.
+ <IX86_BUILTIN_STOREUPS>: Use CODE_FOR_sse_storeups.
+ <IX86_BUILTIN_STOREUPD>: Use CODE_FOR_sse2_storeupd.
+ <IX86_BUILTIN_STOREDQU>: Use CODE_FOR_sse2_storedqu.
+ <IX86_BUILTIN_LOADUPS256>: Use CODE_FOR_avx_loadups256.
+ <IX86_BUILTIN_LOADUPD256>: Use CODE_FOR_avx_loadupd256.
+ <IX86_BUILTIN_LOADDQU256>: Use CODE_FOR_avx_loaddqu256.
+ <IX86_BUILTIN_STOREUPS256>: Use CODE_FOR_avx_storeups256.
+ <IX86_BUILTIN_STOREUPD256>: Use CODE_FOR_avx_storeupd256.
+ <IX86_BUILTIN_STOREDQU256>: Use CODE_FOR_avx_storedqu256.
+
+2012-10-15 Dodji Seketeli <dodji@redhat.com>
+
+ * alias.c: Cleanup comments.
+
+2012-10-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/54915
+ * tree-ssa-forwprop.c (simplify_vector_constructor): Check
+ argument's type.
+
+2012-10-15 Richard Biener <rguenther@suse.de>
+
+ * data-streamer.h (bp_pack_string_with_length): New function.
+ (bp_pack_string): Likewise.
+ (bp_unpack_indexed_string): Likewise.
+ (bp_unpack_string): Likewise.
+ * data-streamer-out.c (bp_pack_string_with_length): Likewise.
+ (bp_pack_string): Likewise.
+ * data-streamer-in.c (bp_unpack_indexed_string): Likewise.
+ (bp_unpack_string): Likewise.
+ * tree-streamer-out.c (pack_ts_translation_unit_decl_value_fields):
+ Pack TRANSLATION_UNIT_LANGUAGE here, not ...
+ (write_ts_translation_unit_decl_tree_pointers): ... here. Remove.
+ (streamer_pack_tree_bitfields): Adjust.
+ (streamer_write_tree_body): Likewise.
+ * tree-streamer-in.c (unpack_ts_translation_unit_decl_value_fields):
+ Unpack TRANSLATION_UNIT_LANGUAGE here, not ...
+ (lto_input_ts_translation_unit_decl_tree_pointers): ... here. Remove.
+ (unpack_value_fields): Adjust.
+ (streamer_read_tree_body): Likewise.
+
+2012-10-15 J"orn Rennecke <joern.rennecke@arc.com>
+
+ * genoutput.c (process_template): Process '*' in '@' alternatives.
+ * doc/md.texi (node Output Statement): Provide example for the above.
+
+2012-10-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/54920
+ * tree-ssa-pre.c (create_expression_by_pieces): Properly
+ allocate temporary storage for all NARY elements.
+
+2012-10-15 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * web.c (union_match_dups): Properly handle OP_INOUT match_dups.
+
+2012-10-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Do not unnecessarily
+ copy the object in the MEM_P case.
+
+2012-10-15 Richard Guenther <rguenther@suse.de>
+
+ * tree-streamer-out.c (streamer_pack_tree_bitfields): Back
+ BINFO_BASE_ACCESSES and CONSTRUCTOR lengths here.
+ (streamer_write_chain): Write TREE_CHAIN as null-terminated list.
+ (write_ts_exp_tree_pointers): Adjust.
+ (write_ts_binfo_tree_pointers): Likewise.
+ (write_ts_constructor_tree_pointers): Likewise.
+ * tree-streamer-in.c (streamer_read_chain): Read TREE_CHAIN as
+ null-terminated list.
+ (unpack_value_fields): Unpack BINFO_BASE_ACCESSES and
+ CONSTRUCTOR lengths and materialize the arrays.
+ (lto_input_ts_exp_tree_pointers): Adjust.
+ (lto_input_ts_binfo_tree_pointers): Likewise.
+ (lto_input_ts_constructor_tree_pointers): Likewise.
+
2012-10-14 Hans-Peter Nilsson <hp@bitrange.com>
* config/mmix/mmix.c (mmix_opposite_regno): Handle the
@@ -21,7 +801,6 @@
(build_insn_chain): Use df_get_live_out instead of DF_LR_OUT.
(do_reload): Remove the DF_LIVE problem for -O1.
-
2012-10-14 Steven Bosscher <steven@gcc.gnu.org>
PR rtl-optimization/54919
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index bc72ebf08..68ed05b6a 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20121015
+20121019
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9376e00d9..7ae3bb9bd 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3101,7 +3101,7 @@ loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASHTAB_H)
loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(RTL_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) \
- $(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) \
+ $(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(TARGET_H) \
$(OBSTACK_H) $(HASHTAB_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 1a9ff91cf..6aa07b00c 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-15 Matthias Klose <doko@ubuntu.com>
+
+ * gcc-interface/Makefile.in: Match arm*-*-linux-*eabi* for
+ ARM Linux/GNU.
+
2012-10-05 Robert Dewar <dewar@adacore.com>
* sem_ch7.adb: Minor reformatting.
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 18446e0c7..3b2b2a789 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -1850,7 +1850,7 @@ ifeq ($(strip $(filter-out powerpc% e500% linux%,$(arch) $(osys))),)
LIBRARY_VERSION := $(LIB_VERSION)
endif
-ifeq ($(strip $(filter-out arm% linux-gnueabi,$(arch) $(osys)-$(word 4,$(targ)))),)
+ifeq ($(strip $(filter-out arm%-linux,$(arch)-$(osys)) $(if $(findstring eabi,$(word 4,$(targ))),,$(word 4,$(targ)))),)
LIBGNAT_TARGET_PAIRS = \
a-intnam.ads<a-intnam-linux.ads \
s-inmaop.adb<s-inmaop-posix.adb \
diff --git a/gcc/alias.c b/gcc/alias.c
index 0c6a7442b..c5e641763 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -60,14 +60,13 @@ along with GCC; see the file COPYING3. If not see
struct Z z2, *pz;
- py = &px1.y1;
+ py = &x1.y1;
px2 = &x1;
Consider the four questions:
Can a store to x1 interfere with px2->y1?
Can a store to x1 interfere with px2->z2?
- (*px2).z2
Can a store to x1 change the value pointed to by with py?
Can a store to x1 change the value pointed to by with pz?
@@ -78,24 +77,24 @@ along with GCC; see the file COPYING3. If not see
a store through a pointer to an X can overwrite any field that is
contained (recursively) in an X (unless we know that px1 != px2).
- The last two of the questions can be solved in the same way as the
- first two questions but this is too conservative. The observation
- is that in some cases analysis we can know if which (if any) fields
- are addressed and if those addresses are used in bad ways. This
- analysis may be language specific. In C, arbitrary operations may
- be applied to pointers. However, there is some indication that
- this may be too conservative for some C++ types.
+ The last two questions can be solved in the same way as the first
+ two questions but this is too conservative. The observation is
+ that in some cases we can know which (if any) fields are addressed
+ and if those addresses are used in bad ways. This analysis may be
+ language specific. In C, arbitrary operations may be applied to
+ pointers. However, there is some indication that this may be too
+ conservative for some C++ types.
The pass ipa-type-escape does this analysis for the types whose
instances do not escape across the compilation boundary.
Historically in GCC, these two problems were combined and a single
- data structure was used to represent the solution to these
+ data structure that was used to represent the solution to these
problems. We now have two similar but different data structures,
- The data structure to solve the last two question is similar to the
- first, but does not contain have the fields in it whose address are
- never taken. For types that do escape the compilation unit, the
- data structures will have identical information.
+ The data structure to solve the last two questions is similar to
+ the first, but does not contain the fields whose address are never
+ taken. For types that do escape the compilation unit, the data
+ structures will have identical information.
*/
/* The alias sets assigned to MEMs assist the back-end in determining
@@ -1641,6 +1640,9 @@ find_base_term (rtx x)
if (!val)
return ret;
+ if (cselib_sp_based_value_p (val))
+ return static_reg_base_value[STACK_POINTER_REGNUM];
+
f = val->locs;
/* Temporarily reset val->locs to avoid infinite recursion. */
val->locs = NULL;
@@ -2760,6 +2762,39 @@ memory_modified_in_insn_p (const_rtx mem, const_rtx insn)
return memory_modified;
}
+/* Return TRUE if the destination of a set is rtx identical to
+ ITEM. */
+static inline bool
+set_dest_equal_p (const_rtx set, const_rtx item)
+{
+ rtx dest = SET_DEST (set);
+ return rtx_equal_p (dest, item);
+}
+
+/* Like memory_modified_in_insn_p, but return TRUE if INSN will
+ *DEFINITELY* modify the memory contents of MEM. */
+bool
+memory_must_be_modified_in_insn_p (const_rtx mem, const_rtx insn)
+{
+ if (!INSN_P (insn))
+ return false;
+ insn = PATTERN (insn);
+ if (GET_CODE (insn) == SET)
+ return set_dest_equal_p (insn, mem);
+ else if (GET_CODE (insn) == PARALLEL)
+ {
+ int i;
+ for (i = 0; i < XVECLEN (insn, 0); i++)
+ {
+ rtx sub = XVECEXP (insn, 0, i);
+ if (GET_CODE (sub) == SET
+ && set_dest_equal_p (sub, mem))
+ return true;
+ }
+ }
+ return false;
+}
+
/* Initialize the aliasing machinery. Initialize the REG_KNOWN_VALUE
array. */
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 61351fb24..d9bd3b7e5 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -802,6 +802,7 @@ extern bool purge_all_dead_edges (void);
extern bool purge_dead_edges (basic_block);
extern bool fixup_abnormal_edges (void);
extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
+extern bool contains_no_active_insn_p (const_basic_block);
extern bool forwarder_block_p (const_basic_block);
extern bool can_fallthru (basic_block, basic_block);
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index bb82be4d7..454196fb6 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,26 @@
+2012-10-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (LOCATION_COL): Delete.
+ (compare_location): New function.
+ (compare_node): Use it.
+ (compare_comment): Likewise.
+
+2012-10-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/53063
+ PR c/40989
+ * c.opt (Wstrict-aliasing=,Wstrict-overflow=): Use LangEnabledBy.
+ * c-opts.c (c_common_handle_option): Do not set them here. Add
+ comment.
+ (c_common_post_options): Likewise.
+
+2012-10-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX): Define.
+ (dump_generic_ada_node) <INTEGER_CST>: Deal with sizetype specially.
+ Remove POINTER_TYPE handling, add large unsigned handling and use
+ ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX for big numbers.
+
2012-10-12 Jakub Jelinek <jakub@redhat.com>
PR c/54381
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 631ee7a58..4c47ed44a 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -30,6 +30,21 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "cpp-id-data.h"
+/* Adapted from hwint.h to use the Ada prefix. */
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# if HOST_BITS_PER_WIDE_INT == 64
+# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
+ "16#%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x#"
+# else
+# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
+ "16#%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x#"
+# endif
+#else
+ /* We can assume that 'long long' is at least 64 bits. */
+# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
+ "16#%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x#"
+#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
+
/* Local functions, macros and variables. */
static int dump_generic_ada_node (pretty_printer *, tree, tree,
int (*)(tree, cpp_operation), int, int, bool);
@@ -52,8 +67,6 @@ static void dump_ads (const char *, void (*)(const char *),
static char *to_ada_name (const char *, int *);
static bool separate_class_package (tree);
-#define LOCATION_COL(LOC) ((expand_location (LOC)).column)
-
#define INDENT(SPACE) do { \
int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
@@ -538,6 +551,26 @@ decl_sloc (const_tree decl, bool last)
return decl_sloc_common (decl, last, false);
}
+/* Compare two locations LHS and RHS. */
+
+static int
+compare_location (location_t lhs, location_t rhs)
+{
+ expanded_location xlhs = expand_location (lhs);
+ expanded_location xrhs = expand_location (rhs);
+
+ if (xlhs.file != xrhs.file)
+ return filename_cmp (xlhs.file, xrhs.file);
+
+ if (xlhs.line != xrhs.line)
+ return xlhs.line - xrhs.line;
+
+ if (xlhs.column != xrhs.column)
+ return xlhs.column - xrhs.column;
+
+ return 0;
+}
+
/* Compare two declarations (LP and RP) by their source location. */
static int
@@ -546,7 +579,7 @@ compare_node (const void *lp, const void *rp)
const_tree lhs = *((const tree *) lp);
const_tree rhs = *((const tree *) rp);
- return decl_sloc (lhs, true) - decl_sloc (rhs, true);
+ return compare_location (decl_sloc (lhs, true), decl_sloc (rhs, true));
}
/* Compare two comments (LP and RP) by their source location. */
@@ -557,17 +590,7 @@ compare_comment (const void *lp, const void *rp)
const cpp_comment *lhs = (const cpp_comment *) lp;
const cpp_comment *rhs = (const cpp_comment *) rp;
- if (LOCATION_FILE (lhs->sloc) != LOCATION_FILE (rhs->sloc))
- return filename_cmp (LOCATION_FILE (lhs->sloc),
- LOCATION_FILE (rhs->sloc));
-
- if (LOCATION_LINE (lhs->sloc) != LOCATION_LINE (rhs->sloc))
- return LOCATION_LINE (lhs->sloc) - LOCATION_LINE (rhs->sloc);
-
- if (LOCATION_COL (lhs->sloc) != LOCATION_COL (rhs->sloc))
- return LOCATION_COL (lhs->sloc) - LOCATION_COL (rhs->sloc);
-
- return 0;
+ return compare_location (lhs->sloc, rhs->sloc);
}
static tree *to_dump = NULL;
@@ -2175,12 +2198,16 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type,
break;
case INTEGER_CST:
- if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
- {
- pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
- pp_string (buffer, "B"); /* pseudo-unit */
- }
- else if (!host_integerp (node, 0))
+ /* We treat the upper half of the sizetype range as negative. This
+ is consistent with the internal treatment and makes it possible
+ to generate the (0 .. -1) range for flexible array members. */
+ if (TREE_TYPE (node) == sizetype)
+ node = fold_convert (ssizetype, node);
+ if (host_integerp (node, 0))
+ pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
+ else if (host_integerp (node, 1))
+ pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node));
+ else
{
tree val = node;
unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
@@ -2193,12 +2220,10 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type,
low = -low;
}
sprintf (pp_buffer (buffer)->digit_buffer,
- HOST_WIDE_INT_PRINT_DOUBLE_HEX,
- (unsigned HOST_WIDE_INT) high, low);
+ ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+ (unsigned HOST_WIDE_INT) high, low);
pp_string (buffer, pp_buffer (buffer)->digit_buffer);
}
- else
- pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
break;
case REAL_CST:
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 29121b5d4..ebbf7d91c 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -360,6 +360,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
break;
case OPT_Wall:
+ /* ??? Don't add new options here. Use LangEnabledBy in c.opt. */
handle_generated_option (&global_options, &global_options_set,
OPT_Wunused, NULL, value,
c_family_lang_mask, kind, loc,
@@ -375,11 +376,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
warn_sequence_point = value; /* Was C only. */
warn_switch = value;
warn_sizeof_pointer_memaccess = value;
- if (warn_strict_aliasing == -1)
- set_Wstrict_aliasing (&global_options, value);
warn_address = value;
- if (warn_strict_overflow == -1)
- warn_strict_overflow = value;
warn_array_bounds = value;
warn_volatile_register_var = value;
@@ -939,11 +936,6 @@ c_common_post_options (const char **pfilename)
if (warn_pointer_sign == -1)
warn_pointer_sign = 0;
- if (warn_strict_aliasing == -1)
- warn_strict_aliasing = 0;
- if (warn_strict_overflow == -1)
- warn_strict_overflow = 0;
-
/* -Woverlength-strings is off by default, but is enabled by -Wpedantic.
It is never enabled in C++, as the minimum limit is not normative
in that standard. */
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index b02c51532..316698468 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -629,6 +629,14 @@ Wstrict-prototypes
C ObjC Var(warn_strict_prototypes) Warning
Warn about unprototyped function declarations
+Wstrict-aliasing=
+C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall, 3, 0)
+;
+
+Wstrict-overflow=
+C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall, 1, 0)
+;
+
Wstrict-selector-match
ObjC ObjC++ Var(warn_strict_selector_match) Warning
Warn if type signatures of candidate methods do not match exactly
diff --git a/gcc/calls.c b/gcc/calls.c
index 2180a6220..d4ef639dc 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -384,13 +384,8 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
/* Some target create a fresh MEM instead of reusing the one provided
above. Set its MEM_EXPR. */
- call = PATTERN (call_insn);
- if (GET_CODE (call) == PARALLEL)
- call = XVECEXP (call, 0, 0);
- if (GET_CODE (call) == SET)
- call = SET_SRC (call);
- if (GET_CODE (call) == CALL
- && MEM_P (XEXP (call, 0))
+ call = get_call_rtx_from (call_insn);
+ if (call
&& MEM_EXPR (XEXP (call, 0)) == NULL_TREE
&& MEM_EXPR (funmem) != NULL_TREE)
set_mem_expr (XEXP (call, 0), MEM_EXPR (funmem));
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 07ef949d2..6e5c6ef75 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -559,16 +559,35 @@ compute_outgoing_frequencies (basic_block b)
f->count = b->count - e->count;
return;
}
+ else
+ {
+ guess_outgoing_edge_probabilities (b);
+ }
}
-
- if (single_succ_p (b))
+ else if (single_succ_p (b))
{
e = single_succ_edge (b);
e->probability = REG_BR_PROB_BASE;
e->count = b->count;
return;
}
- guess_outgoing_edge_probabilities (b);
+ else
+ {
+ /* We rely on BBs with more than two successors to have sane probabilities
+ and do not guess them here. For BBs terminated by switch statements
+ expanded to jump-table jump, we have done the right thing during
+ expansion. For EH edges, we still guess the probabilities here. */
+ bool complex_edge = false;
+ FOR_EACH_EDGE (e, ei, b->succs)
+ if (e->flags & EDGE_COMPLEX)
+ {
+ complex_edge = true;
+ break;
+ }
+ if (complex_edge)
+ guess_outgoing_edge_probabilities (b);
+ }
+
if (b->count)
FOR_EACH_EDGE (e, ei, b->succs)
e->count = ((b->count * e->probability + REG_BR_PROB_BASE / 2)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 57589adbc..4ae1600d7 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -635,6 +635,8 @@ update_alias_info_with_stack_vars (void)
(void *)(size_t) uid)) = part;
*((tree *) pointer_map_insert (cfun->gimple_df->decls_to_pointers,
decl)) = name;
+ if (TREE_ADDRESSABLE (decl))
+ TREE_ADDRESSABLE (name) = 1;
}
/* Make the SSA name point to all partition members. */
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 95f5d5313..a48550445 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -310,6 +310,7 @@ extern edge create_empty_if_region_on_edge (edge, tree);
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
tree *, tree *, struct loop *);
extern struct loop * duplicate_loop (struct loop *, struct loop *);
+extern void copy_loop_info (struct loop *loop, struct loop *target);
extern void duplicate_subloops (struct loop *, struct loop *);
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge,
@@ -320,7 +321,8 @@ extern struct loop *loopify (edge, edge,
struct loop * loop_version (struct loop *, void *,
basic_block *, unsigned, unsigned, unsigned, bool);
extern bool remove_path (edge);
-void scale_loop_frequencies (struct loop *, int, int);
+extern void unloop (struct loop *, bool *);
+extern void scale_loop_frequencies (struct loop *, int, int);
/* Induction variable analysis. */
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 8a44a0b6f..97a90bbff 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -37,7 +37,6 @@ static int find_path (edge, basic_block **);
static void fix_loop_placements (struct loop *, bool *);
static bool fix_bb_placement (basic_block);
static void fix_bb_placements (basic_block, bool *);
-static void unloop (struct loop *, bool *);
/* Checks whether basic block BB is dominated by DATA. */
static bool
@@ -895,7 +894,7 @@ loopify (edge latch_edge, edge header_edge,
If this may cause the information about irreducible regions to become
invalid, IRRED_INVALIDATED is set to true. */
-static void
+void
unloop (struct loop *loop, bool *irred_invalidated)
{
basic_block *body;
@@ -971,6 +970,20 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated)
}
}
+/* Duplicate loop bounds and other information we store about
+ the loop into its duplicate. */
+
+void
+copy_loop_info (struct loop *loop, struct loop *target)
+{
+ gcc_checking_assert (!target->any_upper_bound && !target->any_estimate);
+ target->any_upper_bound = loop->any_upper_bound;
+ target->nb_iterations_upper_bound = loop->nb_iterations_upper_bound;
+ target->any_estimate = loop->any_estimate;
+ target->nb_iterations_estimate = loop->nb_iterations_estimate;
+ target->estimate_state = loop->estimate_state;
+}
+
/* Copies copy of LOOP as subloop of TARGET loop, placing newly
created loop into loops structure. */
struct loop *
@@ -979,6 +992,8 @@ duplicate_loop (struct loop *loop, struct loop *target)
struct loop *cloop;
cloop = alloc_loop ();
place_new_loop (cloop);
+
+ copy_loop_info (loop, cloop);
/* Mark the new loop as copy of LOOP. */
set_loop_copy (loop, cloop);
@@ -1687,6 +1702,8 @@ loop_version (struct loop *loop,
false /* Do not redirect all edges. */,
then_scale, else_scale);
+ copy_loop_info (loop, nloop);
+
/* loopify redirected latch_edge. Update its PENDING_STMTS. */
lv_flush_pending_stmts (latch_edge);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 1b578d7fe..b58562fcc 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -541,10 +541,9 @@ flow_active_insn_p (const_rtx insn)
/* Return true if the block has no effect and only forwards control flow to
its single destination. */
-/* FIXME: Make this a cfg hook. */
bool
-forwarder_block_p (const_basic_block bb)
+contains_no_active_insn_p (const_basic_block bb)
{
rtx insn;
@@ -552,6 +551,24 @@ forwarder_block_p (const_basic_block bb)
|| !single_succ_p (bb))
return false;
+ for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
+ if (INSN_P (insn) && flow_active_insn_p (insn))
+ return false;
+
+ return (!INSN_P (insn)
+ || (JUMP_P (insn) && simplejump_p (insn))
+ || !flow_active_insn_p (insn));
+}
+
+/* Likewise, but protect loop latches, headers and preheaders. */
+/* FIXME: Make this a cfg hook. */
+
+bool
+forwarder_block_p (const_basic_block bb)
+{
+ if (!contains_no_active_insn_p (bb))
+ return false;
+
/* Protect loop latches, headers and preheaders. */
if (current_loops)
{
@@ -563,13 +580,7 @@ forwarder_block_p (const_basic_block bb)
return false;
}
- for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
- if (INSN_P (insn) && flow_active_insn_p (insn))
- return false;
-
- return (!INSN_P (insn)
- || (JUMP_P (insn) && simplejump_p (insn))
- || !flow_active_insn_p (insn));
+ return true;
}
/* Return nonzero if we can reach target from src by falling through. */
diff --git a/gcc/combine.c b/gcc/combine.c
index c13d00408..bf06d4c11 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -12317,21 +12317,21 @@ record_dead_and_set_regs (rtx insn)
if (CALL_P (insn))
{
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
- {
- reg_stat_type *rsp;
-
- rsp = &VEC_index (reg_stat_type, reg_stat, i);
- rsp->last_set_invalid = 1;
- rsp->last_set = insn;
- rsp->last_set_value = 0;
- rsp->last_set_mode = VOIDmode;
- rsp->last_set_nonzero_bits = 0;
- rsp->last_set_sign_bit_copies = 0;
- rsp->last_death = 0;
- rsp->truncated_to_mode = VOIDmode;
- }
+ hard_reg_set_iterator hrsi;
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, i, hrsi)
+ {
+ reg_stat_type *rsp;
+
+ rsp = &VEC_index (reg_stat_type, reg_stat, i);
+ rsp->last_set_invalid = 1;
+ rsp->last_set = insn;
+ rsp->last_set_value = 0;
+ rsp->last_set_mode = VOIDmode;
+ rsp->last_set_nonzero_bits = 0;
+ rsp->last_set_sign_bit_copies = 0;
+ rsp->last_death = 0;
+ rsp->truncated_to_mode = VOIDmode;
+ }
last_call_luid = mem_last_set = DF_INSN_LUID (insn);
diff --git a/gcc/common.opt b/gcc/common.opt
index 6de670b8a..e21fb71bb 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -609,7 +609,7 @@ Common Warning
Warn about code which might break strict aliasing rules
Wstrict-aliasing=
-Common Joined RejectNegative UInteger Var(warn_strict_aliasing) Init(-1) Warning
+Common Joined RejectNegative UInteger Var(warn_strict_aliasing) Warning
Warn about code which might break strict aliasing rules
Wstrict-overflow
@@ -617,7 +617,7 @@ Common Warning
Warn about optimizations that assume that signed overflow is undefined
Wstrict-overflow=
-Common Joined RejectNegative UInteger Var(warn_strict_overflow) Init(-1) Warning
+Common Joined RejectNegative UInteger Var(warn_strict_overflow) Warning
Warn about optimizations that assume that signed overflow is undefined
Wsuggest-attribute=const
@@ -673,7 +673,7 @@ Common Var(warn_unused) Init(0) Warning
Enable all -Wunused- warnings
Wunused-but-set-parameter
-Common Var(warn_unused_but_set_parameter) Init(-1) Warning
+Common Var(warn_unused_but_set_parameter) Warning EnabledBy(Wunused && Wextra)
Warn when a function parameter is only set, otherwise unused
Wunused-but-set-variable
@@ -689,7 +689,7 @@ Common Var(warn_unused_label) Warning EnabledBy(Wunused)
Warn when a label is unused
Wunused-parameter
-Common Var(warn_unused_parameter) Init(-1) Warning
+Common Var(warn_unused_parameter) Warning EnabledBy(Wunused && Wextra)
Warn when a function parameter is unused
Wunused-value
diff --git a/gcc/common/config/rs6000/rs6000-common.c b/gcc/common/config/rs6000/rs6000-common.c
index c903ba398..c1764bc93 100644
--- a/gcc/common/config/rs6000/rs6000-common.c
+++ b/gcc/common/config/rs6000/rs6000-common.c
@@ -82,23 +82,23 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
switch (code)
{
case OPT_mfull_toc:
- opts->x_target_flags &= ~MASK_MINIMAL_TOC;
+ opts->x_rs6000_isa_flags &= ~OPTION_MASK_MINIMAL_TOC;
opts->x_TARGET_NO_FP_IN_TOC = 0;
opts->x_TARGET_NO_SUM_IN_TOC = 0;
- opts_set->x_target_flags |= MASK_MINIMAL_TOC;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
#ifdef TARGET_USES_SYSV4_OPT
/* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
just the same as -mminimal-toc. */
- opts->x_target_flags |= MASK_MINIMAL_TOC;
- opts_set->x_target_flags |= MASK_MINIMAL_TOC;
+ opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
#endif
break;
#ifdef TARGET_USES_SYSV4_OPT
case OPT_mtoc:
/* Make -mtoc behave like -mminimal-toc. */
- opts->x_target_flags |= MASK_MINIMAL_TOC;
- opts_set->x_target_flags |= MASK_MINIMAL_TOC;
+ opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
break;
#endif
@@ -107,9 +107,10 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
#else
case OPT_m64:
#endif
- opts->x_target_flags |= MASK_POWERPC64;
- opts->x_target_flags |= ~opts_set->x_target_flags & MASK_PPC_GFXOPT;
- opts_set->x_target_flags |= MASK_POWERPC64;
+ opts->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
+ opts->x_rs6000_isa_flags |= (~opts_set->x_rs6000_isa_flags
+ & OPTION_MASK_PPC_GFXOPT);
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
break;
#ifdef TARGET_USES_AIX64_OPT
@@ -117,8 +118,8 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
#else
case OPT_m32:
#endif
- opts->x_target_flags &= ~MASK_POWERPC64;
- opts_set->x_target_flags |= MASK_POWERPC64;
+ opts->x_rs6000_isa_flags &= ~OPTION_MASK_POWERPC64;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64;
break;
case OPT_mminimal_toc:
@@ -181,8 +182,8 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
case OPT_mrelocatable:
if (value == 1)
{
- opts->x_target_flags |= MASK_MINIMAL_TOC;
- opts_set->x_target_flags |= MASK_MINIMAL_TOC;
+ opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC;
opts->x_TARGET_NO_FP_IN_TOC = 1;
}
break;
@@ -190,14 +191,16 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
case OPT_mrelocatable_lib:
if (value == 1)
{
- opts->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
- opts_set->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
+ opts->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE
+ | OPTION_MASK_MINIMAL_TOC);
+ opts_set->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE
+ | OPTION_MASK_MINIMAL_TOC);
opts->x_TARGET_NO_FP_IN_TOC = 1;
}
else
{
- opts->x_target_flags &= ~MASK_RELOCATABLE;
- opts_set->x_target_flags |= MASK_RELOCATABLE;
+ opts->x_rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_RELOCATABLE;
}
break;
#endif
@@ -227,15 +230,15 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
"-msingle-float option equivalent to -mhard-float");
/* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
opts->x_rs6000_double_float = 0;
- opts->x_target_flags &= ~MASK_SOFT_FLOAT;
- opts_set->x_target_flags |= MASK_SOFT_FLOAT;
+ opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
break;
case OPT_mdouble_float:
/* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
opts->x_rs6000_single_float = 1;
- opts->x_target_flags &= ~MASK_SOFT_FLOAT;
- opts_set->x_target_flags |= MASK_SOFT_FLOAT;
+ opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
break;
case OPT_msimple_fpu:
@@ -259,8 +262,8 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
{
/* If -mfpu is not none, then turn off SOFT_FLOAT, turn on
HARD_FLOAT. */
- opts->x_target_flags &= ~MASK_SOFT_FLOAT;
- opts_set->x_target_flags |= MASK_SOFT_FLOAT;
+ opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
opts->x_rs6000_xilinx_fpu = 1;
if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
opts->x_rs6000_single_float = 1;
@@ -272,8 +275,8 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
else
{
/* -mfpu=none is equivalent to -msoft-float. */
- opts->x_target_flags |= MASK_SOFT_FLOAT;
- opts_set->x_target_flags |= MASK_SOFT_FLOAT;
+ opts->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
+ opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0;
}
break;
@@ -297,8 +300,4 @@ rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
-#undef TARGET_DEFAULT_TARGET_FLAGS
-#define TARGET_DEFAULT_TARGET_FLAGS \
- (TARGET_DEFAULT)
-
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 75ca21756..a33b72d8f 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -857,7 +857,7 @@ arm*-*-netbsdelf*)
extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
tmake_file="${tmake_file} arm/t-arm"
;;
-arm*-*-linux-*eabi*) # ARM GNU/Linux with ELF
+arm*-*-linux-*) # ARM GNU/Linux with ELF
tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h arm/elf.h arm/linux-gas.h arm/linux-elf.h"
case $target in
arm*b-*-linux*)
@@ -3154,7 +3154,7 @@ case "${target}" in
"" \
| armv[23456] | armv2a | armv3m | armv4t | armv5t \
| armv5te | armv6j |armv6k | armv6z | armv6zk | armv6-m \
- | armv7 | armv7-a | armv7-r | armv7-m \
+ | armv7 | armv7-a | armv7-r | armv7-m | armv8-a \
| iwmmxt | ep9312)
# OK
;;
@@ -3180,7 +3180,8 @@ case "${target}" in
| vfp | vfp3 | vfpv3 \
| vfpv3-fp16 | vfpv3-d16 | vfpv3-d16-fp16 | vfpv3xd \
| vfpv3xd-fp16 | neon | neon-fp16 | vfpv4 | vfpv4-d16 \
- | fpv4-sp-d16 | neon-vfpv4)
+ | fpv4-sp-d16 | neon-vfpv4 | fp-arm-v8 | neon-fp-armv8 \
+ | crypto-neon-fp-armv8)
# OK
;;
*)
diff --git a/gcc/config/arm/arm-arches.def b/gcc/config/arm/arm-arches.def
index f83639df8..d0b968f88 100644
--- a/gcc/config/arm/arm-arches.def
+++ b/gcc/config/arm/arm-arches.def
@@ -55,5 +55,6 @@ ARM_ARCH("armv7-a", cortexa8, 7A, FL_CO_PROC | FL_FOR_ARCH7A)
ARM_ARCH("armv7-r", cortexr4, 7R, FL_CO_PROC | FL_FOR_ARCH7R)
ARM_ARCH("armv7-m", cortexm3, 7M, FL_CO_PROC | FL_FOR_ARCH7M)
ARM_ARCH("armv7e-m", cortexm4, 7EM, FL_CO_PROC | FL_FOR_ARCH7EM)
+ARM_ARCH("armv8-a", cortexa15, 8A, FL_CO_PROC | FL_FOR_ARCH8A)
ARM_ARCH("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT)
ARM_ARCH("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2)
diff --git a/gcc/config/arm/arm-fpus.def b/gcc/config/arm/arm-fpus.def
index d0fbfd370..377e5e145 100644
--- a/gcc/config/arm/arm-fpus.def
+++ b/gcc/config/arm/arm-fpus.def
@@ -21,24 +21,28 @@
/* Before using #include to read this file, define a macro:
- ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16)
+ ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16, CRYPTO)
The arguments are the fields of struct arm_fpu_desc.
genopt.sh assumes no whitespace up to the first "," in each entry. */
-ARM_FPU("vfp", ARM_FP_MODEL_VFP, 2, VFP_REG_D16, false, false)
-ARM_FPU("vfpv3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false)
-ARM_FPU("vfpv3-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, true)
-ARM_FPU("vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false)
-ARM_FPU("vfpv3-d16-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, true)
-ARM_FPU("vfpv3xd", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, false)
-ARM_FPU("vfpv3xd-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, true)
-ARM_FPU("neon", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , false)
-ARM_FPU("neon-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true, true)
-ARM_FPU("vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, false, true)
-ARM_FPU("vfpv4-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_D16, false, true)
-ARM_FPU("fpv4-sp-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_SINGLE, false, true)
-ARM_FPU("neon-vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, true, true)
+ARM_FPU("vfp", ARM_FP_MODEL_VFP, 2, VFP_REG_D16, false, false, false)
+ARM_FPU("vfpv3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false, false)
+ARM_FPU("vfpv3-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, true, false)
+ARM_FPU("vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false, false)
+ARM_FPU("vfpv3-d16-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, true, false)
+ARM_FPU("vfpv3xd", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, false, false)
+ARM_FPU("vfpv3xd-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, true, false)
+ARM_FPU("neon", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , false, false)
+ARM_FPU("neon-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true, true, false)
+ARM_FPU("vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, false, true, false)
+ARM_FPU("vfpv4-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_D16, false, true, false)
+ARM_FPU("fpv4-sp-d16", ARM_FP_MODEL_VFP, 4, VFP_REG_SINGLE, false, true, false)
+ARM_FPU("neon-vfpv4", ARM_FP_MODEL_VFP, 4, VFP_REG_D32, true, true, false)
+ARM_FPU("fp-armv8", ARM_FP_MODEL_VFP, 8, VFP_REG_D32, false, true, false)
+ARM_FPU("neon-fp-armv8",ARM_FP_MODEL_VFP, 8, VFP_REG_D32, true, true, false)
+ARM_FPU("crypto-neon-fp-armv8",
+ ARM_FP_MODEL_VFP, 8, VFP_REG_D32, true, true, true)
/* Compatibility aliases. */
-ARM_FPU("vfp3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false)
+ARM_FPU("vfp3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false, false)
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index 5f9369553..1616d9da2 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -347,10 +347,13 @@ EnumValue
Enum(arm_arch) String(armv7e-m) Value(22)
EnumValue
-Enum(arm_arch) String(iwmmxt) Value(23)
+Enum(arm_arch) String(armv8-a) Value(23)
EnumValue
-Enum(arm_arch) String(iwmmxt2) Value(24)
+Enum(arm_arch) String(iwmmxt) Value(24)
+
+EnumValue
+Enum(arm_arch) String(iwmmxt2) Value(25)
Enum
Name(arm_fpu) Type(int)
@@ -396,5 +399,14 @@ EnumValue
Enum(arm_fpu) String(neon-vfpv4) Value(12)
EnumValue
-Enum(arm_fpu) String(vfp3) Value(13)
+Enum(arm_fpu) String(fp-armv8) Value(13)
+
+EnumValue
+Enum(arm_fpu) String(neon-fp-armv8) Value(14)
+
+EnumValue
+Enum(arm_fpu) String(crypto-neon-fp-armv8) Value(15)
+
+EnumValue
+Enum(arm_fpu) String(vfp3) Value(16)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 866385cca..327ef223e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -686,6 +686,7 @@ static int thumb_call_reg_needed;
architecture. */
#define FL_ARCH7 (1 << 22) /* Architecture 7. */
#define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */
+#define FL_ARCH8 (1 << 24) /* Architecture 8. */
#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
#define FL_IWMMXT2 (1 << 30) /* "Intel Wireless MMX2 technology". */
@@ -716,6 +717,8 @@ static int thumb_call_reg_needed;
#define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_THUMB_DIV)
#define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_THUMB_DIV)
#define FL_FOR_ARCH7EM (FL_FOR_ARCH7M | FL_ARCH7EM)
+#define FL_FOR_ARCH8A (FL_FOR_ARCH7 | FL_ARCH6K | FL_ARCH8 | FL_THUMB_DIV \
+ | FL_ARM_DIV | FL_NOTM)
/* The bits in this mask specify which
instructions we are allowed to generate. */
@@ -765,6 +768,9 @@ int arm_arch_notm = 0;
/* Nonzero if instructions present in ARMv7E-M can be used. */
int arm_arch7em = 0;
+/* Nonzero if instructions present in ARMv8 can be used. */
+int arm_arch8 = 0;
+
/* Nonzero if this chip can benefit from load scheduling. */
int arm_ld_sched = 0;
@@ -1059,8 +1065,8 @@ char arm_arch_name[] = "__ARM_ARCH_0UNK__";
static const struct arm_fpu_desc all_fpus[] =
{
-#define ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16) \
- { NAME, MODEL, REV, VFP_REGS, NEON, FP16 },
+#define ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16, CRYPTO) \
+ { NAME, MODEL, REV, VFP_REGS, NEON, FP16, CRYPTO },
#include "arm-fpus.def"
#undef ARM_FPU
};
@@ -1743,6 +1749,7 @@ arm_option_override (void)
arm_arch6m = arm_arch6 && !arm_arch_notm;
arm_arch7 = (insn_flags & FL_ARCH7) != 0;
arm_arch7em = (insn_flags & FL_ARCH7EM) != 0;
+ arm_arch8 = (insn_flags & FL_ARCH8) != 0;
arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0;
arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
@@ -1959,6 +1966,7 @@ arm_option_override (void)
/* Enable -munaligned-access by default for
- all ARMv6 architecture-based processors
- ARMv7-A, ARMv7-R, and ARMv7-M architecture-based processors.
+ - ARMv8 architecture-base processors.
Disable -munaligned-access by default for
- all pre-ARMv6 architecture-based processors
@@ -16732,7 +16740,7 @@ arm_expand_prologue (void)
}
emit_set_insn (ip_rtx, insn);
/* Add a USE to stop propagate_one_insn() from barfing. */
- emit_insn (gen_prologue_use (ip_rtx));
+ emit_insn (gen_force_register_use (ip_rtx));
}
}
else
@@ -18718,6 +18726,8 @@ static neon_builtin_datum neon_builtin_data[] =
VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si),
+ VAR2 (TERNOP, vfma, v2sf, v4sf),
+ VAR2 (TERNOP, vfms, v2sf, v4sf),
VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si),
VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si),
@@ -22621,7 +22631,7 @@ thumb1_expand_epilogue (void)
/* Emit a USE (stack_pointer_rtx), so that
the stack adjustment will not be deleted. */
- emit_insn (gen_prologue_use (stack_pointer_rtx));
+ emit_insn (gen_force_register_use (stack_pointer_rtx));
if (crtl->profile || !TARGET_SCHED_PROLOG)
emit_insn (gen_blockage ());
@@ -22845,7 +22855,7 @@ arm_expand_epilogue (bool really_return)
/* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not
deleted. */
- emit_insn (gen_prologue_use (stack_pointer_rtx));
+ emit_insn (gen_force_register_use (stack_pointer_rtx));
}
else
{
@@ -22863,7 +22873,7 @@ arm_expand_epilogue (bool really_return)
emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
/* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not
deleted. */
- emit_insn (gen_prologue_use (stack_pointer_rtx));
+ emit_insn (gen_force_register_use (stack_pointer_rtx));
}
}
else
@@ -22881,7 +22891,7 @@ arm_expand_epilogue (bool really_return)
GEN_INT (amount)));
/* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is
not deleted. */
- emit_insn (gen_prologue_use (stack_pointer_rtx));
+ emit_insn (gen_force_register_use (stack_pointer_rtx));
}
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 34d364f00..4ac5de708 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -296,6 +296,9 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
/* FPU supports fused-multiply-add operations. */
#define TARGET_FMA (TARGET_VFP && arm_fpu_desc->rev >= 4)
+/* FPU supports Crypto extensions. */
+#define TARGET_CRYPTO (TARGET_VFP && arm_fpu_desc->crypto)
+
/* FPU supports Neon instructions. The setting of this macro gets
revealed via __ARM_NEON__ so we add extra guards upon TARGET_32BIT
and TARGET_HARD_FLOAT to ensure that NEON instructions are
@@ -400,6 +403,7 @@ extern const struct arm_fpu_desc
enum vfp_reg_type regs;
int neon;
int fp16;
+ int crypto;
} *arm_fpu_desc;
/* Which floating point hardware to schedule for. */
@@ -443,7 +447,8 @@ enum base_architecture
BASE_ARCH_7A = 7,
BASE_ARCH_7R = 7,
BASE_ARCH_7M = 7,
- BASE_ARCH_7EM = 7
+ BASE_ARCH_7EM = 7,
+ BASE_ARCH_8A = 8
};
/* The major revision number of the ARM Architecture implemented by the target. */
@@ -482,6 +487,9 @@ extern int arm_arch_notm;
/* Nonzero if instructions present in ARMv7E-M can be used. */
extern int arm_arch7em;
+/* Nonzero if this chip supports the ARM Architecture 8 extensions. */
+extern int arm_arch8;
+
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index b45fea021..7c80f91fb 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -76,7 +76,7 @@
; that points at the containing instruction.
UNSPEC_PRLG_STK ; A special barrier that prevents frame accesses
; being scheduled before the stack adjustment insn.
- UNSPEC_PROLOGUE_USE ; As USE insns are not meaningful after reload,
+ UNSPEC_REGISTER_USE ; As USE insns are not meaningful after reload,
; this unspec is used to prevent the deletion of
; instructions setting registers for EH handling
; and stack frame generation. Operand 0 is the
@@ -10610,7 +10610,7 @@
"TARGET_EITHER"
"
if (crtl->calls_eh_return)
- emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
+ emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
if (TARGET_THUMB1)
{
thumb1_expand_epilogue ();
@@ -10644,7 +10644,7 @@
;; does not think that it is unused by the sibcall branch that
;; will replace the standard function epilogue.
(define_expand "sibcall_epilogue"
- [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
+ [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
(unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
"TARGET_32BIT"
"
@@ -11260,10 +11260,10 @@
""
)
-(define_insn "prologue_use"
- [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
+(define_insn "force_register_use"
+ [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
""
- "%@ %0 needed for prologue"
+ "%@ %0 needed"
[(set_attr "length" "0")]
)
diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h
index b486d57be..8fec83f28 100644
--- a/gcc/config/arm/arm_neon.h
+++ b/gcc/config/arm/arm_neon.h
@@ -1350,6 +1350,38 @@ vqdmlsl_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c)
return (int64x2_t)__builtin_neon_vqdmlslv2si (__a, __b, __c, 1);
}
+#ifdef __ARM_FEATURE_FMA
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vfma_f32 (float32x2_t __a, float32x2_t __b, float32x2_t __c)
+{
+ return (float32x2_t)__builtin_neon_vfmav2sf (__a, __b, __c, 3);
+}
+
+#endif
+#ifdef __ARM_FEATURE_FMA
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vfmaq_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c)
+{
+ return (float32x4_t)__builtin_neon_vfmav4sf (__a, __b, __c, 3);
+}
+
+#endif
+#ifdef __ARM_FEATURE_FMA
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vfms_f32 (float32x2_t __a, float32x2_t __b, float32x2_t __c)
+{
+ return (float32x2_t)__builtin_neon_vfmsv2sf (__a, __b, __c, 3);
+}
+
+#endif
+#ifdef __ARM_FEATURE_FMA
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vfmsq_f32 (float32x4_t __a, float32x4_t __b, float32x4_t __c)
+{
+ return (float32x4_t)__builtin_neon_vfmsv4sf (__a, __b, __c, 3);
+}
+
+#endif
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vsub_s8 (int8x8_t __a, int8x8_t __b)
{
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
index f6d1a3df7..67e17a1b0 100644
--- a/gcc/config/arm/bpabi.h
+++ b/gcc/config/arm/bpabi.h
@@ -64,6 +64,7 @@
|march=armv7-m|mcpu=cortex-m3 \
|march=armv7e-m|mcpu=cortex-m4 \
|march=armv6-m|mcpu=cortex-m0 \
+ |march=armv8-a \
:%{!r:--be8}}}"
#else
#define BE8_LINK_SPEC \
@@ -74,6 +75,7 @@
|march=armv7-m|mcpu=cortex-m3 \
|march=armv7e-m|mcpu=cortex-m4 \
|march=armv6-m|mcpu=cortex-m0 \
+ |march=armv8-a \
:%{!r:--be8}}}"
#endif
diff --git a/gcc/config/arm/cortex-a15-neon.md b/gcc/config/arm/cortex-a15-neon.md
new file mode 100644
index 000000000..afb67a587
--- /dev/null
+++ b/gcc/config/arm/cortex-a15-neon.md
@@ -0,0 +1,1215 @@
+;; ARM Cortex-A15 NEON pipeline description
+;; Copyright (C) 2012 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
+;; <http://www.gnu.org/licenses/>.
+
+(define_automaton "cortex_a15_neon")
+
+;; Dispatch unit.
+(define_cpu_unit "ca15_cx_ij, ca15_cx_ik" "cortex_a15_neon")
+
+;; Accumulate.
+(define_cpu_unit "ca15_cx_acc" "cortex_a15_neon")
+
+;; The 32x32 integer multiply-accumulate pipeline.
+(define_cpu_unit "ca15_cx_imac1" "cortex_a15_neon")
+(define_reservation "ca15_cx_imac" "(ca15_cx_ij+ca15_cx_imac1)")
+
+
+;; The 64-bit ALU pipeline.
+(define_cpu_unit "ca15_cx_ialu1, ca15_cx_ialu2" "cortex_a15_neon")
+
+;; IALU with accumulate.
+(define_reservation "ca15_cx_ialu_with_acc" "ca15_cx_ik+ca15_cx_ialu2+ca15_cx_acc")
+
+(define_reservation "ca15_cx_ialu"
+ "((ca15_cx_ij+ca15_cx_ialu1)|(ca15_cx_ik+ca15_cx_ialu2))")
+
+;; Integer shift pipeline.
+(define_cpu_unit "ca15_cx_ishf" "cortex_a15_neon")
+(define_reservation "ca15_cx_ishf_with_acc" "ca15_cx_ik+ca15_cx_ishf+ca15_cx_acc")
+
+;; SIMD multiply pipeline.
+(define_cpu_unit "ca15_cx_fmul1, ca15_cx_fmul2, ca15_cx_fmul3, ca15_cx_fmul4"
+ "cortex_a15_neon")
+
+(define_reservation "ca15_cx_fmul"
+ "(ca15_cx_ij+(ca15_cx_fmul1|ca15_cx_fmul2))|\
+ (ca15_cx_ik+(ca15_cx_fmul3|ca15_cx_fmul4))")
+
+(define_reservation "ca15_cx_fmul_2"
+ "(ca15_cx_ij+(ca15_cx_fmul1|ca15_cx_fmul2))+\
+ (ca15_cx_ik+(ca15_cx_fmul3|ca15_cx_fmul4))")
+
+;; SIMD ALU pipeline.
+(define_cpu_unit "ca15_cx_falu1, ca15_cx_falu2, ca15_cx_falu3, ca15_cx_falu4"
+ "cortex_a15_neon")
+
+(define_reservation "ca15_cx_falu"
+ "(ca15_cx_ij+(ca15_cx_falu1|ca15_cx_falu2))|\
+ (ca15_cx_ik+(ca15_cx_falu3|ca15_cx_falu4))")
+
+(define_reservation "ca15_cx_falu_2"
+ "(ca15_cx_ij+(ca15_cx_falu1|ca15_cx_falu2))+\
+ (ca15_cx_ik+(ca15_cx_falu3|ca15_cx_falu4))")
+
+;; SIMD multiply-accumulate pipeline.
+;; This can be used if fmul and falu are not reserved.
+(define_reservation "ca15_cx_fmac"
+ "((ca15_cx_ij+ca15_cx_fmul1),nothing*2,ca15_cx_falu1)|\
+ ((ca15_cx_ij+ca15_cx_fmul2),nothing*2,ca15_cx_falu2)|\
+ ((ca15_cx_ik+ca15_cx_fmul3),nothing*2,ca15_cx_falu3)|\
+ ((ca15_cx_ik+ca15_cx_fmul4),nothing*2,ca15_cx_falu4)")
+
+(define_reservation "ca15_cx_fmac_2"
+ "(((ca15_cx_ij+ca15_cx_fmul1),nothing*2,ca15_cx_falu1)|\
+ ((ca15_cx_ij+ca15_cx_fmul2),nothing*2,ca15_cx_falu2))+\
+ (((ca15_cx_ik+ca15_cx_fmul3),nothing*2,ca15_cx_falu3)|\
+ ((ca15_cx_ik+ca15_cx_fmul4),nothing*2,ca15_cx_falu4))")
+
+
+;; Vector FP multiply pipeline
+(define_cpu_unit "ca15_cx_vfp_i" "cortex_a15_neon")
+
+(define_reservation "ca15_cx_vfp" "ca15_cx_ik+ca15_cx_vfp_i")
+
+;; Load permute pipeline
+(define_reservation "ca15_cx_perm" "ca15_cx_ij|ca15_cx_ik")
+(define_reservation "ca15_cx_perm_2" "ca15_cx_ij+ca15_cx_ik")
+
+(define_insn_reservation "cortex_a15_neon_int_1" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_int_1"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_int_2" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_int_2"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_int_3" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_int_3"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_int_4" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_int_4"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_int_5" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_int_5"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_vqneg_vqabs" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_vqneg_vqabs"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_vmov" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_vmov"))
+ "ca15_issue1,ca15_cx_ialu")
+
+(define_insn_reservation "cortex_a15_neon_vaba" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_vaba"))
+ "ca15_issue1,ca15_cx_ialu_with_acc")
+
+(define_insn_reservation "cortex_a15_neon_vaba_qqq" 8
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_vaba_qqq"))
+ "ca15_issue2,ca15_cx_ialu_with_acc*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
+ "ca15_issue1,ca15_cx_imac")
+
+(define_insn_reservation "cortex_a15_neon_mul_qqq_8_16_32_ddd_32" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32"))
+ "ca15_issue1,ca15_cx_imac*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))
+ "ca15_issue1,ca15_cx_imac*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"))
+ "ca15_issue1,ca15_cx_imac")
+
+(define_insn_reservation
+ "cortex_a15_neon_mla_qqq_8_16" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mla_qqq_8_16"))
+ "ca15_issue1,ca15_cx_imac*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mla_ddd_32_qqd_16_ddd_32_scalar_\
+ qdd_64_32_long_scalar_qdd_64_32_long" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
+ "ca15_issue1,ca15_cx_imac")
+
+(define_insn_reservation
+ "cortex_a15_neon_mla_qqq_32_qqd_32_scalar" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mla_qqq_32_qqd_32_scalar"))
+ "ca15_issue1,ca15_cx_imac*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mul_ddd_16_scalar_32_16_long_scalar" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mul_ddd_16_scalar_32_16_long_scalar"))
+ "ca15_issue1,ca15_cx_imac")
+
+(define_insn_reservation
+ "cortex_a15_neon_mul_qqd_32_scalar" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mul_qqd_32_scalar"))
+ "ca15_issue1,ca15_cx_imac*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
+ "ca15_issue1,ca15_cx_imac")
+
+(define_insn_reservation
+ "cortex_a15_neon_shift_1" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_shift_1"))
+ "ca15_issue1,ca15_cx_ik+ca15_cx_ishf")
+
+(define_insn_reservation
+ "cortex_a15_neon_shift_2" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_shift_2"))
+ "ca15_issue1,ca15_cx_ik+ca15_cx_ishf")
+
+(define_insn_reservation
+ "cortex_a15_neon_shift_3" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_shift_3"))
+ "ca15_issue2,(ca15_cx_ik+ca15_cx_ishf)*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_vshl_ddd" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vshl_ddd"))
+ "ca15_issue1,ca15_cx_ik+ca15_cx_ishf")
+
+(define_insn_reservation
+ "cortex_a15_neon_vqshl_vrshl_vqrshl_qqq" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vqshl_vrshl_vqrshl_qqq"))
+ "ca15_issue2,(ca15_cx_ik+ca15_cx_ishf)*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_vsra_vrsra" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vsra_vrsra"))
+ "ca15_issue1,ca15_cx_ishf_with_acc")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vadd_ddd_vabs_dd" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vadd_ddd_vabs_dd"))
+ "ca15_issue1,ca15_cx_falu")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vadd_qqq_vabs_qq" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vadd_qqq_vabs_qq"))
+ "ca15_issue2,ca15_cx_falu_2")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vmul_ddd" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vmul_ddd"))
+ "ca15_issue1,ca15_cx_fmul")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vmul_qqd" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vmul_qqd"))
+ "ca15_issue2,ca15_cx_fmul_2")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vmla_ddd" 9
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vmla_ddd"))
+ "ca15_issue1,ca15_cx_fmac")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vmla_qqq" 11
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vmla_qqq"))
+ "ca15_issue2,ca15_cx_fmac_2")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vmla_ddd_scalar" 9
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vmla_ddd_scalar"))
+ "ca15_issue1,ca15_cx_fmac")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vmla_qqq_scalar" 11
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vmla_qqq_scalar"))
+ "ca15_issue2,ca15_cx_fmac_2")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vrecps_vrsqrts_ddd" 9
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vrecps_vrsqrts_ddd"))
+ "ca15_issue1,ca15_cx_fmac")
+
+(define_insn_reservation
+ "cortex_a15_neon_fp_vrecps_vrsqrts_qqq" 11
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_fp_vrecps_vrsqrts_qqq"))
+ "ca15_issue2,ca15_cx_fmac_2")
+
+(define_insn_reservation
+ "cortex_a15_neon_bp_simple" 4
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_bp_simple"))
+ "ca15_issue3,ca15_ls+ca15_cx_perm_2,ca15_cx_perm")
+
+(define_insn_reservation
+ "cortex_a15_neon_bp_2cycle" 4
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_bp_2cycle"))
+ "ca15_issue1,ca15_cx_perm")
+
+(define_insn_reservation
+ "cortex_a15_neon_bp_3cycle" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_bp_3cycle"))
+ "ca15_issue3,ca15_cx_ialu+ca15_cx_perm_2,ca15_cx_perm")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld1_1_2_regs" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld1_1_2_regs"))
+ "ca15_issue2,ca15_ls,ca15_ldr")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld1_3_4_regs" 8
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld1_3_4_regs"))
+ "ca15_issue3,ca15_ls1+ca15_ls2,ca15_ldr,ca15_ldr")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld2_2_regs_vld1_vld2_all_lanes" 9
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld2_2_regs_vld1_vld2_all_lanes"))
+ "ca15_issue3,ca15_ls,ca15_ldr")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld2_4_regs" 12
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld2_4_regs"))
+ "ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_ldr*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld3_vld4" 12
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld3_vld4"))
+ "ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_ldr*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_vst1_1_2_regs_vst2_2_regs" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vst1_1_2_regs_vst2_2_regs"))
+ "ca15_issue3,ca15_issue3+ca15_cx_perm+ca15_ls1+ca15_ls2,ca15_str*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_vst1_3_4_regs" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vst1_3_4_regs"))
+ "ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_str*3")
+
+(define_insn_reservation
+ "cortex_a15_neon_vst2_4_regs_vst3_vst4" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vst2_4_regs_vst3_vst4"))
+ "ca15_issue3,ca15_issue3+ca15_cx_perm_2+ca15_ls1+ca15_ls2,\
+ ca15_issue3+ca15_str,ca15_str*3")
+
+(define_insn_reservation
+ "cortex_a15_neon_vst3_vst4" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vst3_vst4"))
+ "ca15_issue3,ca15_issue3+ca15_cx_perm_2+ca15_ls1+ca15_ls2,ca15_str*4")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld1_vld2_lane" 9
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld1_vld2_lane"))
+ "ca15_issue3,ca15_ls,ca15_ldr")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld3_vld4_lane" 10
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld3_vld4_lane"))
+ "ca15_issue3,ca15_issue3+ca15_ls,ca15_issue3+ca15_ldr")
+
+(define_insn_reservation
+ "cortex_a15_neon_vst1_vst2_lane" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vst1_vst2_lane"))
+ "ca15_issue3,ca15_cx_perm+ca15_ls,ca15_str")
+
+(define_insn_reservation
+ "cortex_a15_neon_vst3_vst4_lane" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vst3_vst4_lane"))
+ "ca15_issue3,ca15_issue3+ca15_cx_perm+ca15_ls1+ca15_ls2,ca15_str*2")
+
+(define_insn_reservation
+ "cortex_a15_neon_vld3_vld4_all_lanes" 11
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_vld3_vld4_all_lanes"))
+ "ca15_issue3,ca15_issue3+ca15_ls,ca15_ldr")
+
+(define_insn_reservation
+ "cortex_a15_neon_ldm_2" 20
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_ldm_2"))
+ "ca15_issue3*6")
+
+(define_insn_reservation
+ "cortex_a15_neon_stm_2" 0
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_stm_2"))
+ "ca15_issue3*6")
+
+(define_insn_reservation
+ "cortex_a15_neon_mcr" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mcr"))
+ "ca15_issue2,ca15_ls,ca15_cx_perm")
+
+(define_insn_reservation
+ "cortex_a15_neon_mcr_2_mcrr" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mcr_2_mcrr"))
+ "ca15_issue2,ca15_ls1+ca15_ls2")
+
+(define_insn_reservation
+ "cortex_a15_neon_mrc" 5
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mrc"))
+ "ca15_issue1,ca15_ls")
+
+(define_insn_reservation
+ "cortex_a15_neon_mrrc" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "neon_type"
+ "neon_mrrc"))
+ "ca15_issue2,ca15_ls1+ca15_ls2")
+
+(define_insn_reservation "cortex_a15_vfp_const" 4
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fconsts,fconstd"))
+ "ca15_issue1,ca15_cx_perm")
+
+(define_insn_reservation "cortex_a15_vfp_adds_subs" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fadds"))
+ "ca15_issue1,ca15_cx_vfp")
+
+(define_insn_reservation "cortex_a15_vfp_addd_subd" 10
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "faddd"))
+ "ca15_issue2,ca15_cx_vfp*2")
+
+(define_insn_reservation "cortex_a15_vfp_muls" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fmuls"))
+ "ca15_issue1,ca15_cx_vfp")
+
+(define_insn_reservation "cortex_a15_vfp_muld" 12
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fmuld"))
+ "ca15_issue2,ca15_cx_vfp*2")
+
+(define_insn_reservation "cortex_a15_vfp_macs" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fmacs"))
+ "ca15_issue1,ca15_cx_vfp")
+
+(define_insn_reservation "cortex_a15_vfp_macd" 11
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fmacd"))
+ "ca15_issue2,ca15_cx_vfp*2")
+
+(define_insn_reservation "cortex_a15_vfp_cvt" 6
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "f_cvt"))
+ "ca15_issue1,ca15_cx_vfp")
+
+(define_insn_reservation "cortex_a15_vfp_cmpd" 8
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fcmpd"))
+ "ca15_issue2,ca15_cx_perm,ca15_cx_vfp")
+
+(define_insn_reservation "cortex_a15_vfp_cmps" 8
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fcmps"))
+ "ca15_issue2,ca15_cx_perm,ca15_cx_vfp")
+
+(define_insn_reservation "cortex_a15_vfp_arithd" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "ffarithd"))
+ "ca15_issue2,ca15_cx_perm*2")
+
+(define_insn_reservation "cortex_a15_vfp_cpys" 4
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fcpys"))
+ "ca15_issue1,ca15_cx_perm")
+
+(define_insn_reservation "cortex_a15_vfp_ariths" 7
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "ffariths"))
+ "ca15_issue1,ca15_cx_perm")
+
+(define_insn_reservation "cortex_a15_vfp_divs" 10
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fdivs"))
+ "ca15_issue1,ca15_cx_ik")
+
+(define_insn_reservation "cortex_a15_vfp_divd" 18
+ (and (eq_attr "tune" "cortexa15")
+ (eq_attr "type" "fdivd"))
+ "ca15_issue1,ca15_cx_ik")
+
+;; Define bypasses.
+(define_bypass 5 "cortex_a15_neon_mcr_2_mcrr"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_mcr"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 10 "cortex_a15_neon_vld3_vld4_all_lanes"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 9 "cortex_a15_neon_vld3_vld4_lane"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 8 "cortex_a15_neon_vld1_vld2_lane"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 11 "cortex_a15_neon_vld3_vld4"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 11 "cortex_a15_neon_vld2_4_regs"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 8 "cortex_a15_neon_vld2_2_regs_vld1_vld2_all_lanes"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 7 "cortex_a15_neon_vld1_3_4_regs"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_vld1_1_2_regs"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_bp_3cycle"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 3 "cortex_a15_neon_bp_2cycle"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 3 "cortex_a15_neon_bp_simple"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 10 "cortex_a15_neon_fp_vrecps_vrsqrts_qqq"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 8 "cortex_a15_neon_fp_vrecps_vrsqrts_ddd"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 10 "cortex_a15_neon_fp_vmla_qqq_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 8 "cortex_a15_neon_fp_vmla_ddd_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 10 "cortex_a15_neon_fp_vmla_qqq"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 8 "cortex_a15_neon_fp_vmla_ddd"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_fp_vmul_qqd"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_fp_vmul_ddd"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_fp_vadd_qqq_vabs_qq"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_fp_vadd_ddd_vabs_dd"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_vsra_vrsra"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_vqshl_vrshl_vqrshl_qqq"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_vshl_ddd"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_shift_3"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_shift_2"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_shift_1"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_mul_qqd_32_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_mul_ddd_16_scalar_32_16_long_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_mla_qqq_32_qqd_32_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_mla_qqq_8_16"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6
+ "cortex_a15_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_mul_qqq_8_16_32_ddd_32"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 5 "cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 7 "cortex_a15_neon_vaba_qqq"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 6 "cortex_a15_neon_vaba"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_vmov"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_vqneg_vqabs"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_int_5"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_int_4"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_int_3"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_int_2"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
+(define_bypass 4 "cortex_a15_neon_int_1"
+ "cortex_a15_neon_int_1,\
+ cortex_a15_neon_int_4,\
+ cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mul_qqq_8_16_32_ddd_32,\
+ cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ cortex_a15_neon_mla_qqq_8_16,\
+ cortex_a15_neon_fp_vadd_ddd_vabs_dd,\
+ cortex_a15_neon_fp_vadd_qqq_vabs_qq,\
+ cortex_a15_neon_fp_vmla_ddd,\
+ cortex_a15_neon_fp_vmla_qqq,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_ddd,\
+ cortex_a15_neon_fp_vrecps_vrsqrts_qqq")
+
diff --git a/gcc/config/arm/cortex-a15.md b/gcc/config/arm/cortex-a15.md
index ccab7cbe9..b86c6e706 100644
--- a/gcc/config/arm/cortex-a15.md
+++ b/gcc/config/arm/cortex-a15.md
@@ -24,7 +24,7 @@
;; The Cortex-A15 core is modelled as a triple issue pipeline that has
;; the following dispatch units.
;; 1. Two pipelines for simple integer operations: SX1, SX2
-;; 2. Two pipelines for Neon and FP data-processing operations: CX1, CX2
+;; 2. Individual units for Neon and FP operations as in cortex-a15-neon.md
;; 3. One pipeline for branch operations: BX
;; 4. One pipeline for integer multiply and divide operations: MX
;; 5. Two pipelines for load and store operations: LS1, LS2
@@ -44,7 +44,6 @@
;; The main dispatch units
(define_cpu_unit "ca15_sx1, ca15_sx2" "cortex_a15")
-(define_cpu_unit "ca15_cx1, ca15_cx2" "cortex_a15")
(define_cpu_unit "ca15_ls1, ca15_ls2" "cortex_a15")
(define_cpu_unit "ca15_bx, ca15_mx" "cortex_a15")
@@ -129,20 +128,6 @@
(eq_attr "neon_type" "none")))
"ca15_issue1,ca15_bx")
-
-;; We lie with calls. They take up all issue slots, and form a block in the
-;; pipeline. The result however is available the next cycle.
-;;
-;; Addition of new units requires this to be updated.
-(define_insn_reservation "cortex_a15_call" 1
- (and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "call")
- (eq_attr "neon_type" "none")))
- "ca15_issue3,\
- ca15_sx1+ca15_sx2+ca15_bx+ca15_mx+ca15_cx1+ca15_cx2+ca15_ls1+ca15_ls2,\
- ca15_sx1_alu+ca15_sx1_shf+ca15_sx1_sat+ca15_sx2_alu+ca15_sx2_shf\
- +ca15_sx2_sat+ca15_ldr+ca15_str")
-
;; Load-store execution Unit
;;
;; Loads of up to two words.
@@ -173,6 +158,23 @@
(eq_attr "neon_type" "none")))
"ca15_issue2,ca15_ls1+ca15_ls2,ca15_str,ca15_str")
+;; We include Neon.md here to ensure that the branch can block the Neon units.
+(include "cortex-a15-neon.md")
+
+;; We lie with calls. They take up all issue slots, and form a block in the
+;; pipeline. The result however is available the next cycle.
+(define_insn_reservation "cortex_a15_call" 1
+ (and (eq_attr "tune" "cortexa15")
+ (and (eq_attr "type" "call")
+ (eq_attr "neon_type" "none")))
+ "ca15_issue3,\
+ ca15_sx1+ca15_sx2+ca15_bx+ca15_mx+ca15_cx_ij+ca15_cx_ik+ca15_ls1+ca15_ls2+\
+ ca15_cx_imac1+ca15_cx_ialu1+ca15_cx_ialu2+ca15_cx_ishf+\
+ ca15_cx_acc+ca15_cx_fmul1+ca15_cx_fmul2+ca15_cx_fmul3+ca15_cx_fmul4+\
+ ca15_cx_falu1+ca15_cx_falu2+ca15_cx_falu3+ca15_cx_falu4+ca15_cx_vfp_i,\
+ ca15_sx1_alu+ca15_sx1_shf+ca15_sx1_sat+ca15_sx2_alu+\
+ ca15_sx2_shf+ca15_sx2_sat+ca15_ldr+ca15_str")
+
;; Simple execution unit bypasses
(define_bypass 1 "cortex_a15_alu"
"cortex_a15_alu,cortex_a15_alu_shift,cortex_a15_alu_shift_reg")
diff --git a/gcc/config/arm/neon-docgen.ml b/gcc/config/arm/neon-docgen.ml
index 23e37b498..043b1e06a 100644
--- a/gcc/config/arm/neon-docgen.ml
+++ b/gcc/config/arm/neon-docgen.ml
@@ -103,6 +103,8 @@ let intrinsic_groups =
"Multiplication", single_opcode Vmul;
"Multiply-accumulate", single_opcode Vmla;
"Multiply-subtract", single_opcode Vmls;
+ "Fused-multiply-accumulate", single_opcode Vfma;
+ "Fused-multiply-subtract", single_opcode Vfms;
"Subtraction", single_opcode Vsub;
"Comparison (equal-to)", single_opcode Vceq;
"Comparison (greater-than-or-equal-to)", single_opcode Vcge;
diff --git a/gcc/config/arm/neon-gen.ml b/gcc/config/arm/neon-gen.ml
index 29679aaca..6c4e2726a 100644
--- a/gcc/config/arm/neon-gen.ml
+++ b/gcc/config/arm/neon-gen.ml
@@ -286,6 +286,24 @@ let get_shuffle features =
| _ -> None
with Not_found -> None
+let print_feature_test_start features =
+ try
+ match List.find (fun feature ->
+ match feature with Requires_feature _ -> true
+ | _ -> false)
+ features with
+ Requires_feature feature ->
+ Format.printf "#ifdef __ARM_FEATURE_%s@\n" feature
+ | _ -> assert false
+ with Not_found -> assert true
+
+let print_feature_test_end features =
+ let feature =
+ List.exists (function Requires_feature x -> true
+ | _ -> false) features in
+ if feature then Format.printf "#endif@\n"
+
+
let print_variant opcode features shape name (ctype, asmtype, elttype) =
let bits = infoword_value elttype features in
let modesuf = mode_suffix elttype shape in
@@ -302,7 +320,11 @@ let print_variant opcode features shape name (ctype, asmtype, elttype) =
return ctype builtin in
let body = pdecls @ rdecls @ stmts
and fnname = (intrinsic_name name) ^ "_" ^ (string_of_elt elttype) in
- print_function ctype fnname body
+ begin
+ print_feature_test_start features;
+ print_function ctype fnname body;
+ print_feature_test_end features;
+ end
(* When this function processes the element types in the ops table, it rewrites
them in a list of tuples (a,b,c):
diff --git a/gcc/config/arm/neon-testgen.ml b/gcc/config/arm/neon-testgen.ml
index a69a53917..4645f3901 100644
--- a/gcc/config/arm/neon-testgen.ml
+++ b/gcc/config/arm/neon-testgen.ml
@@ -46,13 +46,14 @@ let open_test_file dir name =
failwith ("Could not create test source file " ^ name ^ ": " ^ str)
(* Emit prologue code to a test source file. *)
-let emit_prologue chan test_name =
+let emit_prologue chan test_name effective_target =
Printf.fprintf chan "/* Test the `%s' ARM Neon intrinsic. */\n" test_name;
Printf.fprintf chan "/* This file was autogenerated by neon-testgen. */\n\n";
Printf.fprintf chan "/* { dg-do assemble } */\n";
- Printf.fprintf chan "/* { dg-require-effective-target arm_neon_ok } */\n";
+ Printf.fprintf chan "/* { dg-require-effective-target %s_ok } */\n"
+ effective_target;
Printf.fprintf chan "/* { dg-options \"-save-temps -O0\" } */\n";
- Printf.fprintf chan "/* { dg-add-options arm_neon } */\n";
+ Printf.fprintf chan "/* { dg-add-options %s } */\n" effective_target;
Printf.fprintf chan "\n#include \"arm_neon.h\"\n\n";
Printf.fprintf chan "void test_%s (void)\n{\n" test_name
@@ -156,6 +157,17 @@ let check_types tys =
then (Const :: flags, String.sub ty 6 ((String.length ty) - 6))
else (flags, ty)) tys'
+(* Work out what the effective target should be. *)
+let effective_target features =
+ try
+ match List.find (fun feature ->
+ match feature with Requires_feature _ -> true
+ | _ -> false)
+ features with
+ Requires_feature "FMA" -> "arm_neonv2"
+ | _ -> assert false
+ with Not_found -> "arm_neon"
+
(* Given an intrinsic shape, produce a regexp that will match
the right-hand sides of instructions generated by an intrinsic of
that shape. *)
@@ -263,8 +275,10 @@ let test_intrinsic dir opcode features shape name munge elt_ty =
"!?\\(\\[ \t\\]+@\\[a-zA-Z0-9 \\]+\\)?\\n")
(analyze_all_shapes features shape analyze_shape)
in
+ let effective_target = effective_target features
+ in
(* Emit file and function prologues. *)
- emit_prologue chan test_name;
+ emit_prologue chan test_name effective_target;
(* Emit local variable declarations. *)
emit_automatics chan c_types features;
Printf.fprintf chan "\n";
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index b89d5383a..92e03b097 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -722,6 +722,10 @@
)
;; Fused multiply-accumulate
+;; We define each insn twice here:
+;; 1: with flag_unsafe_math_optimizations for the widening multiply phase
+;; to be able to use when converting to FMA.
+;; 2: without flag_unsafe_math_optimizations for the intrinsics to use.
(define_insn "fma<VCVTF:mode>4"
[(set (match_operand:VCVTF 0 "register_operand" "=w")
(fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
@@ -735,6 +739,19 @@
(const_string "neon_fp_vmla_qqq")))]
)
+(define_insn "fma<VCVTF:mode>4_intrinsic"
+ [(set (match_operand:VCVTF 0 "register_operand" "=w")
+ (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
+ (match_operand:VCVTF 2 "register_operand" "w")
+ (match_operand:VCVTF 3 "register_operand" "0")))]
+ "TARGET_NEON && TARGET_FMA"
+ "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
+ [(set (attr "neon_type")
+ (if_then_else (match_test "<Is_d_reg>")
+ (const_string "neon_fp_vmla_ddd")
+ (const_string "neon_fp_vmla_qqq")))]
+)
+
(define_insn "*fmsub<VCVTF:mode>4"
[(set (match_operand:VCVTF 0 "register_operand" "=w")
(fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
@@ -748,6 +765,19 @@
(const_string "neon_fp_vmla_qqq")))]
)
+(define_insn "fmsub<VCVTF:mode>4_intrinsic"
+ [(set (match_operand:VCVTF 0 "register_operand" "=w")
+ (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
+ (match_operand:VCVTF 2 "register_operand" "w")
+ (match_operand:VCVTF 3 "register_operand" "0")))]
+ "TARGET_NEON && TARGET_FMA"
+ "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
+ [(set (attr "neon_type")
+ (if_then_else (match_test "<Is_d_reg>")
+ (const_string "neon_fp_vmla_ddd")
+ (const_string "neon_fp_vmla_qqq")))]
+)
+
(define_insn "ior<mode>3"
[(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
(ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
@@ -1925,6 +1955,32 @@
DONE;
})
+(define_expand "neon_vfma<VCVTF:mode>"
+ [(match_operand:VCVTF 0 "s_register_operand")
+ (match_operand:VCVTF 1 "s_register_operand")
+ (match_operand:VCVTF 2 "s_register_operand")
+ (match_operand:VCVTF 3 "s_register_operand")
+ (match_operand:SI 4 "immediate_operand")]
+ "TARGET_NEON && TARGET_FMA"
+{
+ emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3],
+ operands[1]));
+ DONE;
+})
+
+(define_expand "neon_vfms<VCVTF:mode>"
+ [(match_operand:VCVTF 0 "s_register_operand")
+ (match_operand:VCVTF 1 "s_register_operand")
+ (match_operand:VCVTF 2 "s_register_operand")
+ (match_operand:VCVTF 3 "s_register_operand")
+ (match_operand:SI 4 "immediate_operand")]
+ "TARGET_NEON && TARGET_FMA"
+{
+ emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3],
+ operands[1]));
+ DONE;
+})
+
; Used for intrinsics when flag_unsafe_math_optimizations is false.
(define_insn "neon_vmla<mode>_unspec"
diff --git a/gcc/config/arm/neon.ml b/gcc/config/arm/neon.ml
index 56869c03c..101f8f654 100644
--- a/gcc/config/arm/neon.ml
+++ b/gcc/config/arm/neon.ml
@@ -102,6 +102,8 @@ type opcode =
| Vmul
| Vmla
| Vmls
+ | Vfma
+ | Vfms
| Vsub
| Vceq
| Vcge
@@ -275,6 +277,8 @@ type features =
| Const_valuator of (int -> int)
| Fixed_vector_reg
| Fixed_core_reg
+ (* Mark that the intrinsic requires __ARM_FEATURE_string to be defined. *)
+ | Requires_feature of string
exception MixedMode of elts * elts
@@ -802,6 +806,12 @@ let ops =
Vmls, [], Long, "vmlsl", elts_same_io, su_8_32;
Vmls, [Saturating; Doubling], Long, "vqdmlsl", elts_same_io, [S16; S32];
+ (* Fused-multiply-accumulate. *)
+ Vfma, [Requires_feature "FMA"], All (3, Dreg), "vfma", elts_same_io, [F32];
+ Vfma, [Requires_feature "FMA"], All (3, Qreg), "vfmaQ", elts_same_io, [F32];
+ Vfms, [Requires_feature "FMA"], All (3, Dreg), "vfms", elts_same_io, [F32];
+ Vfms, [Requires_feature "FMA"], All (3, Qreg), "vfmsQ", elts_same_io, [F32];
+
(* Subtraction. *)
Vsub, [], All (3, Dreg), "vsub", sign_invar_2, F32 :: su_8_32;
Vsub, [No_op], All (3, Dreg), "vsub", sign_invar_2, [S64; U64];
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 57d1539ee..a5302f479 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -996,7 +996,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
- (use (match_operand 4 "" ""))] ; label
+ (use (match_operand 4 "" "")) ; label
+ (use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
"TARGET_32BIT"
"
{
diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h
index b28bec9b8..a2a1a51c2 100644
--- a/gcc/config/avr/avr-arch.h
+++ b/gcc/config/avr/avr-arch.h
@@ -149,7 +149,6 @@ struct arch_info_s
/* Preprocessor macros to define depending on MCU type. */
-extern const char *avr_extra_arch_macro;
extern const struct base_arch_s *avr_current_arch;
extern const struct mcu_type_s *avr_current_device;
extern const struct mcu_type_s avr_mcu_types[];
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c
index 6eb0ebaed..6e7f8c711 100644
--- a/gcc/config/avr/avr-c.c
+++ b/gcc/config/avr/avr-c.c
@@ -88,8 +88,8 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
if (avr_current_arch->macro)
cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_current_arch->macro);
- if (avr_extra_arch_macro)
- cpp_define (pfile, avr_extra_arch_macro);
+ if (avr_current_device->macro)
+ cpp_define (pfile, avr_current_device->macro);
if (AVR_HAVE_RAMPD) cpp_define (pfile, "__AVR_HAVE_RAMPD__");
if (AVR_HAVE_RAMPX) cpp_define (pfile, "__AVR_HAVE_RAMPX__");
if (AVR_HAVE_RAMPY) cpp_define (pfile, "__AVR_HAVE_RAMPY__");
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 1c5bab2ba..9ae526636 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -195,9 +195,6 @@ rtx rampz_rtx;
static GTY(()) rtx xstring_empty;
static GTY(()) rtx xstring_e;
-/* Preprocessor macros to define depending on MCU type. */
-const char *avr_extra_arch_macro;
-
/* Current architecture. */
const struct base_arch_s *avr_current_arch;
@@ -310,7 +307,6 @@ avr_option_override (void)
avr_current_device = &avr_mcu_types[avr_mcu_index];
avr_current_arch = &avr_arch_types[avr_current_device->arch];
- avr_extra_arch_macro = avr_current_device->macro;
/* RAM addresses of some SFRs common to all Devices in respective Arch. */
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index 1774d3adf..63ad17550 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -1933,6 +1933,7 @@
; operand 2 is the maximum number of loop iterations
; operand 3 is the number of levels of enclosed loops
; operand 4 is the label to jump to at the top of the loop
+; operand 5 indicates if the loop is entered at the top
(define_expand "doloop_end"
[(parallel [(set (pc) (if_then_else
(ne (match_operand:SI 0 "" "")
@@ -1943,7 +1944,7 @@
(plus:SI (match_dup 0)
(const_int -1)))
(unspec [(const_int 0)] UNSPEC_LSETUP_END)
- (clobber (match_scratch:SI 5 ""))])]
+ (clobber (match_operand 5 ""))])] ; match_scratch
""
{
/* The loop optimizer doesn't check the predicates... */
@@ -1956,6 +1957,7 @@
&& (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
FAIL;
bfin_hardware_loop ();
+ operands[5] = gen_rtx_SCRATCH (SImode);
})
(define_insn "loop_end"
diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md
index 99f02d5dc..e612ef682 100644
--- a/gcc/config/c6x/c6x.md
+++ b/gcc/config/c6x/c6x.md
@@ -1425,6 +1425,7 @@
; operand 2 is the maximum number of loop iterations
; operand 3 is the number of levels of enclosed loops
; operand 4 is the label to jump to at the top of the loop
+; operand 5 indicates if the loop is entered at the top
(define_expand "doloop_end"
[(parallel [(set (pc) (if_then_else
(ne (match_operand:SI 0 "" "")
@@ -1434,12 +1435,13 @@
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))
- (clobber (match_scratch:SI 5 ""))])]
+ (clobber (match_operand 5 ""))])] ; match_scratch
"TARGET_INSNS_64PLUS && optimize"
{
/* The loop optimizer doesn't check the predicates... */
if (GET_MODE (operands[0]) != SImode)
FAIL;
+ operands[5] = gen_rtx_SCRATCH (SImode);
})
(define_insn "mvilc"
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index 83da29325..46f20b15e 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -1,5 +1,5 @@
/* Target definitions for x86 running Darwin.
- Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2010, 2011
+ Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#define DARWIN_X86 1
#undef TARGET_64BIT
-#define TARGET_64BIT OPTION_ISA_64BIT
+#define TARGET_64BIT TARGET_ISA_64BIT
#ifdef IN_LIBGCC2
#undef TARGET_64BIT
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c10e49458..e095d9872 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16059,7 +16059,8 @@ ix86_avx256_split_vector_move_misalign (rtx op0, rtx op1)
{
rtx m;
rtx (*extract) (rtx, rtx, rtx);
- rtx (*move_unaligned) (rtx, rtx);
+ rtx (*load_unaligned) (rtx, rtx);
+ rtx (*store_unaligned) (rtx, rtx);
enum machine_mode mode;
switch (GET_MODE (op0))
@@ -16068,39 +16069,52 @@ ix86_avx256_split_vector_move_misalign (rtx op0, rtx op1)
gcc_unreachable ();
case V32QImode:
extract = gen_avx_vextractf128v32qi;
- move_unaligned = gen_avx_movdqu256;
+ load_unaligned = gen_avx_loaddqu256;
+ store_unaligned = gen_avx_storedqu256;
mode = V16QImode;
break;
case V8SFmode:
extract = gen_avx_vextractf128v8sf;
- move_unaligned = gen_avx_movups256;
+ load_unaligned = gen_avx_loadups256;
+ store_unaligned = gen_avx_storeups256;
mode = V4SFmode;
break;
case V4DFmode:
extract = gen_avx_vextractf128v4df;
- move_unaligned = gen_avx_movupd256;
+ load_unaligned = gen_avx_loadupd256;
+ store_unaligned = gen_avx_storeupd256;
mode = V2DFmode;
break;
}
- if (MEM_P (op1) && TARGET_AVX256_SPLIT_UNALIGNED_LOAD)
+ if (MEM_P (op1))
{
- rtx r = gen_reg_rtx (mode);
- m = adjust_address (op1, mode, 0);
- emit_move_insn (r, m);
- m = adjust_address (op1, mode, 16);
- r = gen_rtx_VEC_CONCAT (GET_MODE (op0), r, m);
- emit_move_insn (op0, r);
+ if (TARGET_AVX256_SPLIT_UNALIGNED_LOAD)
+ {
+ rtx r = gen_reg_rtx (mode);
+ m = adjust_address (op1, mode, 0);
+ emit_move_insn (r, m);
+ m = adjust_address (op1, mode, 16);
+ r = gen_rtx_VEC_CONCAT (GET_MODE (op0), r, m);
+ emit_move_insn (op0, r);
+ }
+ else
+ emit_insn (load_unaligned (op0, op1));
}
- else if (MEM_P (op0) && TARGET_AVX256_SPLIT_UNALIGNED_STORE)
+ else if (MEM_P (op0))
{
- m = adjust_address (op0, mode, 0);
- emit_insn (extract (m, op1, const0_rtx));
- m = adjust_address (op0, mode, 16);
- emit_insn (extract (m, op1, const1_rtx));
+ if (TARGET_AVX256_SPLIT_UNALIGNED_STORE)
+ {
+ m = adjust_address (op0, mode, 0);
+ emit_insn (extract (m, op1, const0_rtx));
+ m = adjust_address (op0, mode, 16);
+ emit_insn (extract (m, op1, const1_rtx));
+ }
+ else
+ emit_insn (store_unaligned (op0, op1));
}
else
- emit_insn (move_unaligned (op0, op1));
+ gcc_unreachable ();
}
/* Implement the movmisalign patterns for SSE. Non-SSE modes go
@@ -16195,7 +16209,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
op0 = gen_lowpart (V16QImode, op0);
op1 = gen_lowpart (V16QImode, op1);
/* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_movdqu (op0, op1));
+ emit_insn (gen_sse2_loaddqu (op0, op1));
}
else if (TARGET_SSE2 && mode == V2DFmode)
{
@@ -16207,7 +16221,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
|| optimize_function_for_size_p (cfun))
{
/* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_movupd (op0, op1));
+ emit_insn (gen_sse2_loadupd (op0, op1));
return;
}
@@ -16245,7 +16259,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
{
op0 = gen_lowpart (V4SFmode, op0);
op1 = gen_lowpart (V4SFmode, op1);
- emit_insn (gen_sse_movups (op0, op1));
+ emit_insn (gen_sse_loadups (op0, op1));
return;
}
@@ -16270,7 +16284,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
op0 = gen_lowpart (V16QImode, op0);
op1 = gen_lowpart (V16QImode, op1);
/* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_movdqu (op0, op1));
+ emit_insn (gen_sse2_storedqu (op0, op1));
}
else if (TARGET_SSE2 && mode == V2DFmode)
{
@@ -16279,7 +16293,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
|| TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
|| optimize_function_for_size_p (cfun))
/* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_movupd (op0, op1));
+ emit_insn (gen_sse2_storeupd (op0, op1));
else
{
m = adjust_address (op0, DFmode, 0);
@@ -16299,7 +16313,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
|| optimize_function_for_size_p (cfun))
{
op0 = gen_lowpart (V4SFmode, op0);
- emit_insn (gen_sse_movups (op0, op1));
+ emit_insn (gen_sse_storeups (op0, op1));
}
else
{
@@ -26754,8 +26768,8 @@ static const struct builtin_description bdesc_pcmpistr[] =
/* Special builtins with variable number of arguments. */
static const struct builtin_description bdesc_special_args[] =
{
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtsc, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtscp, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED },
{ ~OPTION_MASK_ISA_64BIT, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID },
/* MMX */
@@ -26765,9 +26779,9 @@ static const struct builtin_description bdesc_special_args[] =
{ OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_femms, "__builtin_ia32_femms", IX86_BUILTIN_FEMMS, UNKNOWN, (int) VOID_FTYPE_VOID },
/* SSE */
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movups, "__builtin_ia32_storeups", IX86_BUILTIN_STOREUPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF },
+ { OPTION_MASK_ISA_SSE, CODE_FOR_sse_storeups, "__builtin_ia32_storeups", IX86_BUILTIN_STOREUPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF },
{ OPTION_MASK_ISA_SSE, CODE_FOR_sse_movntv4sf, "__builtin_ia32_movntps", IX86_BUILTIN_MOVNTPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movups, "__builtin_ia32_loadups", IX86_BUILTIN_LOADUPS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
+ { OPTION_MASK_ISA_SSE, CODE_FOR_sse_loadups, "__builtin_ia32_loadups", IX86_BUILTIN_LOADUPS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
{ OPTION_MASK_ISA_SSE, CODE_FOR_sse_loadhps_exp, "__builtin_ia32_loadhps", IX86_BUILTIN_LOADHPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_PCV2SF },
{ OPTION_MASK_ISA_SSE, CODE_FOR_sse_loadlps_exp, "__builtin_ia32_loadlps", IX86_BUILTIN_LOADLPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_PCV2SF },
@@ -26781,14 +26795,14 @@ static const struct builtin_description bdesc_special_args[] =
/* SSE2 */
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_lfence, "__builtin_ia32_lfence", IX86_BUILTIN_LFENCE, UNKNOWN, (int) VOID_FTYPE_VOID },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_mfence, 0, IX86_BUILTIN_MFENCE, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movupd, "__builtin_ia32_storeupd", IX86_BUILTIN_STOREUPD, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movdqu, "__builtin_ia32_storedqu", IX86_BUILTIN_STOREDQU, UNKNOWN, (int) VOID_FTYPE_PCHAR_V16QI },
+ { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_storeupd, "__builtin_ia32_storeupd", IX86_BUILTIN_STOREUPD, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V2DF },
+ { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_storedqu, "__builtin_ia32_storedqu", IX86_BUILTIN_STOREDQU, UNKNOWN, (int) VOID_FTYPE_PCHAR_V16QI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movntv2df, "__builtin_ia32_movntpd", IX86_BUILTIN_MOVNTPD, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V2DF },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movntv2di, "__builtin_ia32_movntdq", IX86_BUILTIN_MOVNTDQ, UNKNOWN, (int) VOID_FTYPE_PV2DI_V2DI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movntisi, "__builtin_ia32_movnti", IX86_BUILTIN_MOVNTI, UNKNOWN, (int) VOID_FTYPE_PINT_INT },
{ OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse2_movntidi, "__builtin_ia32_movnti64", IX86_BUILTIN_MOVNTI64, UNKNOWN, (int) VOID_FTYPE_PLONGLONG_LONGLONG },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movupd, "__builtin_ia32_loadupd", IX86_BUILTIN_LOADUPD, UNKNOWN, (int) V2DF_FTYPE_PCDOUBLE },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movdqu, "__builtin_ia32_loaddqu", IX86_BUILTIN_LOADDQU, UNKNOWN, (int) V16QI_FTYPE_PCCHAR },
+ { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loadupd, "__builtin_ia32_loadupd", IX86_BUILTIN_LOADUPD, UNKNOWN, (int) V2DF_FTYPE_PCDOUBLE },
+ { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loaddqu, "__builtin_ia32_loaddqu", IX86_BUILTIN_LOADDQU, UNKNOWN, (int) V16QI_FTYPE_PCCHAR },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loadhpd_exp, "__builtin_ia32_loadhpd", IX86_BUILTIN_LOADHPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_PCDOUBLE },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loadlpd_exp, "__builtin_ia32_loadlpd", IX86_BUILTIN_LOADLPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_PCDOUBLE },
@@ -26813,12 +26827,12 @@ static const struct builtin_description bdesc_special_args[] =
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_v4df, "__builtin_ia32_vbroadcastf128_pd256", IX86_BUILTIN_VBROADCASTPD256, UNKNOWN, (int) V4DF_FTYPE_PCV2DF },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_v8sf, "__builtin_ia32_vbroadcastf128_ps256", IX86_BUILTIN_VBROADCASTPS256, UNKNOWN, (int) V8SF_FTYPE_PCV4SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movupd256, "__builtin_ia32_loadupd256", IX86_BUILTIN_LOADUPD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movups256, "__builtin_ia32_loadups256", IX86_BUILTIN_LOADUPS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movupd256, "__builtin_ia32_storeupd256", IX86_BUILTIN_STOREUPD256, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movups256, "__builtin_ia32_storeups256", IX86_BUILTIN_STOREUPS256, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movdqu256, "__builtin_ia32_loaddqu256", IX86_BUILTIN_LOADDQU256, UNKNOWN, (int) V32QI_FTYPE_PCCHAR },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movdqu256, "__builtin_ia32_storedqu256", IX86_BUILTIN_STOREDQU256, UNKNOWN, (int) VOID_FTYPE_PCHAR_V32QI },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_loadupd256, "__builtin_ia32_loadupd256", IX86_BUILTIN_LOADUPD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_loadups256, "__builtin_ia32_loadups256", IX86_BUILTIN_LOADUPS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_storeupd256, "__builtin_ia32_storeupd256", IX86_BUILTIN_STOREUPD256, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V4DF },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_storeups256, "__builtin_ia32_storeups256", IX86_BUILTIN_STOREUPS256, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V8SF },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_loaddqu256, "__builtin_ia32_loaddqu256", IX86_BUILTIN_LOADDQU256, UNKNOWN, (int) V32QI_FTYPE_PCCHAR },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_storedqu256, "__builtin_ia32_storedqu256", IX86_BUILTIN_STOREDQU256, UNKNOWN, (int) VOID_FTYPE_PCHAR_V32QI },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_lddqu256, "__builtin_ia32_lddqu256", IX86_BUILTIN_LDDQU256, UNKNOWN, (int) V32QI_FTYPE_PCCHAR },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_movntv4di, "__builtin_ia32_movntdq256", IX86_BUILTIN_MOVNTDQ256, UNKNOWN, (int) VOID_FTYPE_PV4DI_V4DI },
@@ -26873,7 +26887,7 @@ static const struct builtin_description bdesc_args[] =
{
{ ~OPTION_MASK_ISA_64BIT, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT },
{ OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64 },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdpmc, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT },
{ ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT },
{ ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT },
{ ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT },
@@ -30438,7 +30452,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
enum insn_code icode;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
tree arg0, arg1, arg2, arg3, arg4;
- rtx op0, op1, op2, op3, op4, pat;
+ rtx op0, op1, op2, op3, op4, pat, insn;
enum machine_mode mode0, mode1, mode2, mode3, mode4;
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
@@ -30619,6 +30633,65 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return target;
}
+ case IX86_BUILTIN_RDPMC:
+ case IX86_BUILTIN_RDTSC:
+ case IX86_BUILTIN_RDTSCP:
+
+ op0 = gen_reg_rtx (DImode);
+ op1 = gen_reg_rtx (DImode);
+
+ if (fcode == IX86_BUILTIN_RDPMC)
+ {
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op2 = expand_normal (arg0);
+ if (!register_operand (op2, SImode))
+ op2 = copy_to_mode_reg (SImode, op2);
+
+ insn = (TARGET_64BIT
+ ? gen_rdpmc_rex64 (op0, op1, op2)
+ : gen_rdpmc (op0, op2));
+ emit_insn (insn);
+ }
+ else if (fcode == IX86_BUILTIN_RDTSC)
+ {
+ insn = (TARGET_64BIT
+ ? gen_rdtsc_rex64 (op0, op1)
+ : gen_rdtsc (op0));
+ emit_insn (insn);
+ }
+ else
+ {
+ op2 = gen_reg_rtx (SImode);
+
+ insn = (TARGET_64BIT
+ ? gen_rdtscp_rex64 (op0, op1, op2)
+ : gen_rdtscp (op0, op2));
+ emit_insn (insn);
+
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op4 = expand_normal (arg0);
+ if (!address_operand (op4, VOIDmode))
+ {
+ op4 = convert_memory_address (Pmode, op4);
+ op4 = copy_addr_to_reg (op4);
+ }
+ emit_move_insn (gen_rtx_MEM (SImode, op4), op2);
+ }
+
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+
+ if (TARGET_64BIT)
+ {
+ op1 = expand_simple_binop (DImode, ASHIFT, op1, GEN_INT (32),
+ op1, 1, OPTAB_DIRECT);
+ op0 = expand_simple_binop (DImode, IOR, op0, op1,
+ op0, 1, OPTAB_DIRECT);
+ }
+
+ emit_move_insn (target, op0);
+ return target;
+
case IX86_BUILTIN_LLWPCB:
arg0 = CALL_EXPR_ARG (exp, 0);
op0 = expand_normal (arg0);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 2e709526e..16db3ca10 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GCC for IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -41,51 +41,51 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* Redefines for option macros. */
-#define TARGET_64BIT OPTION_ISA_64BIT
-#define TARGET_MMX OPTION_ISA_MMX
-#define TARGET_3DNOW OPTION_ISA_3DNOW
-#define TARGET_3DNOW_A OPTION_ISA_3DNOW_A
-#define TARGET_SSE OPTION_ISA_SSE
-#define TARGET_SSE2 OPTION_ISA_SSE2
-#define TARGET_SSE3 OPTION_ISA_SSE3
-#define TARGET_SSSE3 OPTION_ISA_SSSE3
-#define TARGET_SSE4_1 OPTION_ISA_SSE4_1
-#define TARGET_SSE4_2 OPTION_ISA_SSE4_2
-#define TARGET_AVX OPTION_ISA_AVX
-#define TARGET_AVX2 OPTION_ISA_AVX2
-#define TARGET_FMA OPTION_ISA_FMA
-#define TARGET_SSE4A OPTION_ISA_SSE4A
-#define TARGET_FMA4 OPTION_ISA_FMA4
-#define TARGET_XOP OPTION_ISA_XOP
-#define TARGET_LWP OPTION_ISA_LWP
-#define TARGET_ROUND OPTION_ISA_ROUND
-#define TARGET_ABM OPTION_ISA_ABM
-#define TARGET_BMI OPTION_ISA_BMI
-#define TARGET_BMI2 OPTION_ISA_BMI2
-#define TARGET_LZCNT OPTION_ISA_LZCNT
-#define TARGET_TBM OPTION_ISA_TBM
-#define TARGET_POPCNT OPTION_ISA_POPCNT
-#define TARGET_SAHF OPTION_ISA_SAHF
-#define TARGET_MOVBE OPTION_ISA_MOVBE
-#define TARGET_CRC32 OPTION_ISA_CRC32
-#define TARGET_AES OPTION_ISA_AES
-#define TARGET_PCLMUL OPTION_ISA_PCLMUL
-#define TARGET_CMPXCHG16B OPTION_ISA_CX16
-#define TARGET_FSGSBASE OPTION_ISA_FSGSBASE
-#define TARGET_RDRND OPTION_ISA_RDRND
-#define TARGET_F16C OPTION_ISA_F16C
-#define TARGET_RTM OPTION_ISA_RTM
-#define TARGET_HLE OPTION_ISA_HLE
-#define TARGET_RDSEED OPTION_ISA_RDSEED
-#define TARGET_PRFCHW OPTION_ISA_PRFCHW
-#define TARGET_ADX OPTION_ISA_ADX
-
-#define TARGET_LP64 OPTION_ABI_64
-#define TARGET_X32 OPTION_ABI_X32
+#define TARGET_64BIT TARGET_ISA_64BIT
+#define TARGET_MMX TARGET_ISA_MMX
+#define TARGET_3DNOW TARGET_ISA_3DNOW
+#define TARGET_3DNOW_A TARGET_ISA_3DNOW_A
+#define TARGET_SSE TARGET_ISA_SSE
+#define TARGET_SSE2 TARGET_ISA_SSE2
+#define TARGET_SSE3 TARGET_ISA_SSE3
+#define TARGET_SSSE3 TARGET_ISA_SSSE3
+#define TARGET_SSE4_1 TARGET_ISA_SSE4_1
+#define TARGET_SSE4_2 TARGET_ISA_SSE4_2
+#define TARGET_AVX TARGET_ISA_AVX
+#define TARGET_AVX2 TARGET_ISA_AVX2
+#define TARGET_FMA TARGET_ISA_FMA
+#define TARGET_SSE4A TARGET_ISA_SSE4A
+#define TARGET_FMA4 TARGET_ISA_FMA4
+#define TARGET_XOP TARGET_ISA_XOP
+#define TARGET_LWP TARGET_ISA_LWP
+#define TARGET_ROUND TARGET_ISA_ROUND
+#define TARGET_ABM TARGET_ISA_ABM
+#define TARGET_BMI TARGET_ISA_BMI
+#define TARGET_BMI2 TARGET_ISA_BMI2
+#define TARGET_LZCNT TARGET_ISA_LZCNT
+#define TARGET_TBM TARGET_ISA_TBM
+#define TARGET_POPCNT TARGET_ISA_POPCNT
+#define TARGET_SAHF TARGET_ISA_SAHF
+#define TARGET_MOVBE TARGET_ISA_MOVBE
+#define TARGET_CRC32 TARGET_ISA_CRC32
+#define TARGET_AES TARGET_ISA_AES
+#define TARGET_PCLMUL TARGET_ISA_PCLMUL
+#define TARGET_CMPXCHG16B TARGET_ISA_CX16
+#define TARGET_FSGSBASE TARGET_ISA_FSGSBASE
+#define TARGET_RDRND TARGET_ISA_RDRND
+#define TARGET_F16C TARGET_ISA_F16C
+#define TARGET_RTM TARGET_ISA_RTM
+#define TARGET_HLE TARGET_ISA_HLE
+#define TARGET_RDSEED TARGET_ISA_RDSEED
+#define TARGET_PRFCHW TARGET_ISA_PRFCHW
+#define TARGET_ADX TARGET_ISA_ADX
+
+#define TARGET_LP64 TARGET_ABI_64
+#define TARGET_X32 TARGET_ABI_X32
/* SSE4.1 defines round instructions */
#define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1
-#define OPTION_ISA_ROUND ((ix86_isa_flags & OPTION_MASK_ISA_ROUND) != 0)
+#define TARGET_ISA_ROUND ((ix86_isa_flags & OPTION_MASK_ISA_ROUND) != 0)
#include "config/vxworks-dummy.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fa10cb4a4..299115d4a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -17975,40 +17975,7 @@
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
-(define_expand "rdpmc"
- [(match_operand:DI 0 "register_operand")
- (match_operand:SI 1 "register_operand")]
- ""
-{
- rtx reg = gen_reg_rtx (DImode);
- rtx si;
-
- si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, operands[1]),
- UNSPECV_RDPMC);
-
- if (TARGET_64BIT)
- {
- rtvec vec = rtvec_alloc (2);
- rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
- rtx upper = gen_reg_rtx (DImode);
- rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
- gen_rtvec (1, const0_rtx),
- UNSPECV_RDPMC);
- RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
- RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
- emit_insn (load);
- upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
- NULL, 1, OPTAB_DIRECT);
- reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
- OPTAB_DIRECT);
- }
- else
- emit_insn (gen_rtx_SET (VOIDmode, reg, si));
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
- DONE;
-})
-
-(define_insn "*rdpmc"
+(define_insn "rdpmc"
[(set (match_operand:DI 0 "register_operand" "=A")
(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
UNSPECV_RDPMC))]
@@ -18017,44 +17984,18 @@
[(set_attr "type" "other")
(set_attr "length" "2")])
-(define_insn "*rdpmc_rex64"
+(define_insn "rdpmc_rex64"
[(set (match_operand:DI 0 "register_operand" "=a")
(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
UNSPECV_RDPMC))
- (set (match_operand:DI 1 "register_operand" "=d")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
+ (set (match_operand:DI 1 "register_operand" "=d")
+ (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
"TARGET_64BIT"
"rdpmc"
[(set_attr "type" "other")
(set_attr "length" "2")])
-(define_expand "rdtsc"
- [(set (match_operand:DI 0 "register_operand")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
- ""
-{
- if (TARGET_64BIT)
- {
- rtvec vec = rtvec_alloc (2);
- rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
- rtx upper = gen_reg_rtx (DImode);
- rtx lower = gen_reg_rtx (DImode);
- rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
- gen_rtvec (1, const0_rtx),
- UNSPECV_RDTSC);
- RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
- RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
- emit_insn (load);
- upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
- NULL, 1, OPTAB_DIRECT);
- lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
- OPTAB_DIRECT);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
- DONE;
- }
-})
-
-(define_insn "*rdtsc"
+(define_insn "rdtsc"
[(set (match_operand:DI 0 "register_operand" "=A")
(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
"!TARGET_64BIT"
@@ -18062,7 +18003,7 @@
[(set_attr "type" "other")
(set_attr "length" "2")])
-(define_insn "*rdtsc_rex64"
+(define_insn "rdtsc_rex64"
[(set (match_operand:DI 0 "register_operand" "=a")
(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
(set (match_operand:DI 1 "register_operand" "=d")
@@ -18072,48 +18013,7 @@
[(set_attr "type" "other")
(set_attr "length" "2")])
-(define_expand "rdtscp"
- [(match_operand:DI 0 "register_operand")
- (match_operand:SI 1 "memory_operand")]
- ""
-{
- rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
- gen_rtvec (1, const0_rtx),
- UNSPECV_RDTSCP);
- rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
- gen_rtvec (1, const0_rtx),
- UNSPECV_RDTSCP);
- rtx reg = gen_reg_rtx (DImode);
- rtx tmp = gen_reg_rtx (SImode);
-
- if (TARGET_64BIT)
- {
- rtvec vec = rtvec_alloc (3);
- rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
- rtx upper = gen_reg_rtx (DImode);
- RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
- RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
- RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
- emit_insn (load);
- upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
- NULL, 1, OPTAB_DIRECT);
- reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
- OPTAB_DIRECT);
- }
- else
- {
- rtvec vec = rtvec_alloc (2);
- rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
- RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
- RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
- emit_insn (load);
- }
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
- emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
- DONE;
-})
-
-(define_insn "*rdtscp"
+(define_insn "rdtscp"
[(set (match_operand:DI 0 "register_operand" "=A")
(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
(set (match_operand:SI 1 "register_operand" "=c")
@@ -18123,11 +18023,11 @@
[(set_attr "type" "other")
(set_attr "length" "3")])
-(define_insn "*rdtscp_rex64"
+(define_insn "rdtscp_rex64"
[(set (match_operand:DI 0 "register_operand" "=a")
(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
(set (match_operand:DI 1 "register_operand" "=d")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
(set (match_operand:SI 2 "register_operand" "=c")
(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
"TARGET_64BIT"
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index a73c815eb..299b0d936 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -21,7 +21,8 @@
(define_c_enum "unspec" [
;; SSE
UNSPEC_MOVNT
- UNSPEC_MOVU
+ UNSPEC_LOADU
+ UNSPEC_STOREU
;; SSE3
UNSPEC_LDDQU
@@ -586,12 +587,12 @@
DONE;
})
-(define_insn "<sse>_movu<ssemodesuffix><avxsizesuffix>"
- [(set (match_operand:VF 0 "nonimmediate_operand" "=x,m")
+(define_insn "<sse>_loadu<ssemodesuffix><avxsizesuffix>"
+ [(set (match_operand:VF 0 "register_operand" "=x")
(unspec:VF
- [(match_operand:VF 1 "nonimmediate_operand" "xm,x")]
- UNSPEC_MOVU))]
- "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ [(match_operand:VF 1 "memory_operand" "m")]
+ UNSPEC_LOADU))]
+ "TARGET_SSE"
{
switch (get_attr_mode (insn))
{
@@ -618,11 +619,79 @@
]
(const_string "<MODE>")))])
-(define_insn "<sse2>_movdqu<avxsizesuffix>"
- [(set (match_operand:VI1 0 "nonimmediate_operand" "=x,m")
- (unspec:VI1 [(match_operand:VI1 1 "nonimmediate_operand" "xm,x")]
- UNSPEC_MOVU))]
- "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+(define_insn "<sse>_storeu<ssemodesuffix><avxsizesuffix>"
+ [(set (match_operand:VF 0 "memory_operand" "=m")
+ (unspec:VF
+ [(match_operand:VF 1 "register_operand" "x")]
+ UNSPEC_STOREU))]
+ "TARGET_SSE"
+{
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V8SF:
+ case MODE_V4SF:
+ return "%vmovups\t{%1, %0|%0, %1}";
+ default:
+ return "%vmovu<ssemodesuffix>\t{%1, %0|%0, %1}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
+ (set_attr "prefix" "maybe_vex")
+ (set (attr "mode")
+ (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
+ (const_string "<ssePSmode>")
+ (and (eq_attr "alternative" "1")
+ (match_test "TARGET_SSE_TYPELESS_STORES"))
+ (const_string "<ssePSmode>")
+ (match_test "TARGET_AVX")
+ (const_string "<MODE>")
+ (match_test "optimize_function_for_size_p (cfun)")
+ (const_string "V4SF")
+ ]
+ (const_string "<MODE>")))])
+
+(define_insn "<sse2>_loaddqu<avxsizesuffix>"
+ [(set (match_operand:VI1 0 "register_operand" "=x")
+ (unspec:VI1 [(match_operand:VI1 1 "memory_operand" "m")]
+ UNSPEC_LOADU))]
+ "TARGET_SSE2"
+{
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V8SF:
+ case MODE_V4SF:
+ return "%vmovups\t{%1, %0|%0, %1}";
+ default:
+ return "%vmovdqu\t{%1, %0|%0, %1}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
+ (set (attr "prefix_data16")
+ (if_then_else
+ (match_test "TARGET_AVX")
+ (const_string "*")
+ (const_string "1")))
+ (set_attr "prefix" "maybe_vex")
+ (set (attr "mode")
+ (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
+ (const_string "<ssePSmode>")
+ (and (eq_attr "alternative" "1")
+ (match_test "TARGET_SSE_TYPELESS_STORES"))
+ (const_string "<ssePSmode>")
+ (match_test "TARGET_AVX")
+ (const_string "<sseinsnmode>")
+ (match_test "optimize_function_for_size_p (cfun)")
+ (const_string "V4SF")
+ ]
+ (const_string "<sseinsnmode>")))])
+
+(define_insn "<sse2>_storedqu<avxsizesuffix>"
+ [(set (match_operand:VI1 0 "memory_operand" "=m")
+ (unspec:VI1 [(match_operand:VI1 1 "register_operand" "x")]
+ UNSPEC_STOREU))]
+ "TARGET_SSE2"
{
switch (get_attr_mode (insn))
{
@@ -9307,7 +9376,7 @@
(match_operand:SI 3 "register_operand" "a")
(unspec:V16QI
[(match_operand:V16QI 4 "memory_operand" "m")]
- UNSPEC_MOVU)
+ UNSPEC_LOADU)
(match_operand:SI 5 "register_operand" "d")
(match_operand:SI 6 "const_0_to_255_operand" "n")]
UNSPEC_PCMPESTR))
@@ -9315,7 +9384,7 @@
(unspec:V16QI
[(match_dup 2)
(match_dup 3)
- (unspec:V16QI [(match_dup 4)] UNSPEC_MOVU)
+ (unspec:V16QI [(match_dup 4)] UNSPEC_LOADU)
(match_dup 5)
(match_dup 6)]
UNSPEC_PCMPESTR))
@@ -9323,7 +9392,7 @@
(unspec:CC
[(match_dup 2)
(match_dup 3)
- (unspec:V16QI [(match_dup 4)] UNSPEC_MOVU)
+ (unspec:V16QI [(match_dup 4)] UNSPEC_LOADU)
(match_dup 5)
(match_dup 6)]
UNSPEC_PCMPESTR))]
@@ -9498,19 +9567,19 @@
[(match_operand:V16QI 2 "register_operand" "x")
(unspec:V16QI
[(match_operand:V16QI 3 "memory_operand" "m")]
- UNSPEC_MOVU)
+ UNSPEC_LOADU)
(match_operand:SI 4 "const_0_to_255_operand" "n")]
UNSPEC_PCMPISTR))
(set (match_operand:V16QI 1 "register_operand" "=Yz")
(unspec:V16QI
[(match_dup 2)
- (unspec:V16QI [(match_dup 3)] UNSPEC_MOVU)
+ (unspec:V16QI [(match_dup 3)] UNSPEC_LOADU)
(match_dup 4)]
UNSPEC_PCMPISTR))
(set (reg:CC FLAGS_REG)
(unspec:CC
[(match_dup 2)
- (unspec:V16QI [(match_dup 3)] UNSPEC_MOVU)
+ (unspec:V16QI [(match_dup 3)] UNSPEC_LOADU)
(match_dup 4)]
UNSPEC_PCMPISTR))]
"TARGET_SSE4_2
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index aa5e78636..f84f1ad63 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -3960,7 +3960,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
- (use (match_operand 4 "" ""))] ; label
+ (use (match_operand 4 "" "")) ; label
+ (use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
""
{
/* Only use cloop on innermost loops. */
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index 130acc9b3..5d91c037d 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -560,10 +560,6 @@ while (0)
#define FUNCTION_MODE SImode
-/* Standard GCC variables that we reference. */
-
-extern char call_used_regs[];
-
/* IQ2000 external variables defined in iq2000.c. */
/* Comparison type. */
diff --git a/gcc/config/linux-android.h b/gcc/config/linux-android.h
index acbc6627f..e74e261d7 100644
--- a/gcc/config/linux-android.h
+++ b/gcc/config/linux-android.h
@@ -1,5 +1,5 @@
/* Configuration file for Linux Android targets.
- Copyright (C) 2008, 2010
+ Copyright (C) 2008, 2010, 2012
Free Software Foundation, Inc.
Contributed by Doug Kwan (dougkwan@google.com)
Rewritten by CodeSourcery, Inc.
@@ -22,7 +22,7 @@
#define ANDROID_TARGET_OS_CPP_BUILTINS() \
do { \
- if (OPTION_ANDROID) \
+ if (TARGET_ANDROID) \
builtin_define ("__ANDROID__"); \
} while (0)
diff --git a/gcc/config/mep/mep.md b/gcc/config/mep/mep.md
index 773a9a0aa..35b6e1490 100644
--- a/gcc/config/mep/mep.md
+++ b/gcc/config/mep/mep.md
@@ -2079,7 +2079,8 @@
[(use (match_operand 0 "register_operand" ""))
(use (match_operand:QI 1 "const_int_operand" ""))
(use (match_operand:QI 2 "const_int_operand" ""))
- (use (match_operand:QI 3 "const_int_operand" ""))]
+ (use (match_operand:QI 3 "const_int_operand" ""))
+ (use (match_operand 4 "" ""))]
"!profile_arc_flag && TARGET_OPT_REPEAT"
"if (INTVAL (operands[3]) > 1)
FAIL;
@@ -2115,7 +2116,8 @@
(use (match_operand:QI 1 "const_int_operand" ""))
(use (match_operand:QI 2 "const_int_operand" ""))
(use (match_operand:QI 3 "const_int_operand" ""))
- (use (label_ref (match_operand 4 "" "")))]
+ (use (label_ref (match_operand 4 "" "")))
+ (use (match_operand 5 "" ""))]
"!profile_arc_flag && TARGET_OPT_REPEAT"
"if (INTVAL (operands[3]) > 1)
FAIL;
diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h
index 8ff211107..091a462d1 100644
--- a/gcc/config/rs6000/aix43.h
+++ b/gcc/config/rs6000/aix43.h
@@ -26,7 +26,7 @@
do { \
if (TARGET_64BIT && ! TARGET_POWERPC64) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \
} \
if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \
diff --git a/gcc/config/rs6000/aix51.h b/gcc/config/rs6000/aix51.h
index d62d3fb5d..099c4dfd8 100644
--- a/gcc/config/rs6000/aix51.h
+++ b/gcc/config/rs6000/aix51.h
@@ -26,7 +26,7 @@
do { \
if (TARGET_64BIT && ! TARGET_POWERPC64) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \
} \
if (TARGET_POWERPC64 && ! TARGET_64BIT) \
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index 02b966d1f..a37ce622d 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -26,7 +26,7 @@
do { \
if (TARGET_64BIT && ! TARGET_POWERPC64) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \
} \
if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index 870eb0618..7faba7318 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -26,7 +26,7 @@
do { \
if (TARGET_64BIT && ! TARGET_POWERPC64) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \
} \
if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index f0a09e6c5..8de6fee3f 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -26,7 +26,7 @@
do { \
if (TARGET_64BIT && ! TARGET_POWERPC64) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \
} \
if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \
diff --git a/gcc/config/rs6000/aix64.opt b/gcc/config/rs6000/aix64.opt
index 9a10b200e..2dabd8098 100644
--- a/gcc/config/rs6000/aix64.opt
+++ b/gcc/config/rs6000/aix64.opt
@@ -20,11 +20,11 @@
; <http://www.gnu.org/licenses/>.
maix64
-Target Report RejectNegative Negative(maix32) Mask(64BIT)
+Target Report RejectNegative Negative(maix32) Mask(64BIT) Var(rs6000_isa_flags)
Compile for 64-bit pointers
maix32
-Target Report RejectNegative Negative(maix64) InverseMask(64BIT)
+Target Report RejectNegative Negative(maix64) InverseMask(64BIT) Var(rs6000_isa_flags)
Compile for 32-bit pointers
mpe
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 8c168c85d..7ca496f93 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -1674,14 +1674,16 @@
(define_insn "altivec_lvsl"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
+ (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
+ UNSPEC_LVSL))]
"TARGET_ALTIVEC"
"lvsl %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvsr"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
+ (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
+ UNSPEC_LVSR))]
"TARGET_ALTIVEC"
"lvsr %0,%y1"
[(set_attr "type" "vecload")])
@@ -1831,47 +1833,37 @@
operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
})
-(define_insn "altivec_vsumsws_nomode"
- [(set (match_operand 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
- (match_operand:V4SI 2 "register_operand" "v")]
- UNSPEC_VSUMSWS))
- (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
- "TARGET_ALTIVEC"
- "vsumsws %0,%1,%2"
- [(set_attr "type" "veccomplex")])
-
(define_expand "reduc_splus_<mode>"
[(set (match_operand:VIshort 0 "register_operand" "=v")
(unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
UNSPEC_REDUC_PLUS))]
"TARGET_ALTIVEC"
- "
-{
+{
rtx vzero = gen_reg_rtx (V4SImode);
rtx vtmp1 = gen_reg_rtx (V4SImode);
+ rtx dest = gen_lowpart (V4SImode, operands[0]);
emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
- emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
+ emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero));
DONE;
-}")
+})
(define_expand "reduc_uplus_v16qi"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
UNSPEC_REDUC_PLUS))]
"TARGET_ALTIVEC"
- "
{
rtx vzero = gen_reg_rtx (V4SImode);
rtx vtmp1 = gen_reg_rtx (V4SImode);
+ rtx dest = gen_lowpart (V4SImode, operands[0]);
emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
- emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
+ emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero));
DONE;
-}")
+})
(define_expand "neg<mode>2"
[(use (match_operand:VI 0 "register_operand" ""))
@@ -2348,7 +2340,7 @@
;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
(define_insn "altivec_lvlx"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand 1 "memory_operand" "Z")]
+ (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
UNSPEC_LVLX))]
"TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
"lvlx %0,%y1"
@@ -2356,7 +2348,7 @@
(define_insn "altivec_lvlxl"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand 1 "memory_operand" "Z")]
+ (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
UNSPEC_LVLXL))]
"TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
"lvlxl %0,%y1"
@@ -2364,7 +2356,7 @@
(define_insn "altivec_lvrx"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand 1 "memory_operand" "Z")]
+ (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
UNSPEC_LVRX))]
"TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
"lvrx %0,%y1"
@@ -2372,7 +2364,7 @@
(define_insn "altivec_lvrxl"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand 1 "memory_operand" "Z")]
+ (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
UNSPEC_LVRXL))]
"TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
"lvrxl %0,%y1"
diff --git a/gcc/config/rs6000/darwin.opt b/gcc/config/rs6000/darwin.opt
index 3787511b6..2abba3482 100644
--- a/gcc/config/rs6000/darwin.opt
+++ b/gcc/config/rs6000/darwin.opt
@@ -34,9 +34,9 @@ findirect-data
Driver RejectNegative Alias(mfix-and-continue)
m64
-Target RejectNegative Negative(m32) Mask(64BIT)
+Target RejectNegative Negative(m32) Mask(64BIT) Var(rs6000_isa_flags)
Generate 64-bit code
m32
-Target RejectNegative Negative(m64) InverseMask(64BIT)
+Target RejectNegative Negative(m64) InverseMask(64BIT) Var(rs6000_isa_flags)
Generate 32-bit code
diff --git a/gcc/config/rs6000/freebsd.h b/gcc/config/rs6000/freebsd.h
index 50c6697a7..ee447195f 100644
--- a/gcc/config/rs6000/freebsd.h
+++ b/gcc/config/rs6000/freebsd.h
@@ -72,7 +72,7 @@
-mrelocatable or -mrelocatable-lib is given. */
#undef RELOCATABLE_NEEDS_FIXUP
#define RELOCATABLE_NEEDS_FIXUP \
- (target_flags & target_flags_explicit & MASK_RELOCATABLE)
+ (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
diff --git a/gcc/config/rs6000/freebsd64.h b/gcc/config/rs6000/freebsd64.h
index d434ace28..69e150705 100644
--- a/gcc/config/rs6000/freebsd64.h
+++ b/gcc/config/rs6000/freebsd64.h
@@ -57,7 +57,7 @@ extern int dot_symbols;
-mrelocatable or -mrelocatable-lib is given. */
#undef RELOCATABLE_NEEDS_FIXUP
#define RELOCATABLE_NEEDS_FIXUP \
- (target_flags & target_flags_explicit & MASK_RELOCATABLE)
+ (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
#undef RS6000_ABI_NAME
#define RS6000_ABI_NAME "freebsd"
@@ -79,14 +79,14 @@ extern int dot_symbols;
error (INVALID_64BIT, "call"); \
} \
dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \
- if (target_flags & MASK_RELOCATABLE) \
+ if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \
{ \
- target_flags &= ~MASK_RELOCATABLE; \
+ rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \
error (INVALID_64BIT, "relocatable"); \
} \
- if (target_flags & MASK_EABI) \
+ if (rs6000_isa_flags & OPTION_MASK_EABI) \
{ \
- target_flags &= ~MASK_EABI; \
+ rs6000_isa_flags &= ~OPTION_MASK_EABI; \
error (INVALID_64BIT, "eabi"); \
} \
if (TARGET_PROTOTYPE) \
@@ -94,12 +94,13 @@ extern int dot_symbols;
target_prototype = 0; \
error (INVALID_64BIT, "prototype"); \
} \
- if ((target_flags & MASK_POWERPC64) == 0) \
+ if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
error ("-m64 requires a PowerPC64 cpu"); \
} \
- if ((target_flags_explicit & MASK_MINIMAL_TOC) != 0) \
+ if ((rs6000_isa_flags_explicit \
+ & OPTION_MASK_MINIMAL_TOC) != 0) \
{ \
if (global_options_set.x_rs6000_current_cmodel \
&& rs6000_current_cmodel != CMODEL_SMALL) \
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 336727428..02477df71 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -109,7 +109,7 @@
-mrelocatable or -mrelocatable-lib is given. */
#undef RELOCATABLE_NEEDS_FIXUP
#define RELOCATABLE_NEEDS_FIXUP \
- (target_flags & target_flags_explicit & MASK_RELOCATABLE)
+ (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
#define TARGET_POSIX_IO
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 8c32301a7..28ba8f8f6 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -81,7 +81,7 @@ extern int dot_symbols;
-mrelocatable or -mrelocatable-lib is given. */
#undef RELOCATABLE_NEEDS_FIXUP
#define RELOCATABLE_NEEDS_FIXUP \
- (target_flags & target_flags_explicit & MASK_RELOCATABLE)
+ (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
#undef RS6000_ABI_NAME
#define RS6000_ABI_NAME "linux"
@@ -103,14 +103,14 @@ extern int dot_symbols;
error (INVALID_64BIT, "call"); \
} \
dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \
- if (target_flags & MASK_RELOCATABLE) \
+ if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \
{ \
- target_flags &= ~MASK_RELOCATABLE; \
+ rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \
error (INVALID_64BIT, "relocatable"); \
} \
- if (target_flags & MASK_EABI) \
+ if (rs6000_isa_flags & OPTION_MASK_EABI) \
{ \
- target_flags &= ~MASK_EABI; \
+ rs6000_isa_flags &= ~OPTION_MASK_EABI; \
error (INVALID_64BIT, "eabi"); \
} \
if (TARGET_PROTOTYPE) \
@@ -118,12 +118,13 @@ extern int dot_symbols;
target_prototype = 0; \
error (INVALID_64BIT, "prototype"); \
} \
- if ((target_flags & MASK_POWERPC64) == 0) \
+ if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \
{ \
- target_flags |= MASK_POWERPC64; \
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
error ("-m64 requires a PowerPC64 cpu"); \
} \
- if ((target_flags_explicit & MASK_MINIMAL_TOC) != 0) \
+ if ((rs6000_isa_flags_explicit \
+ & OPTION_MASK_MINIMAL_TOC) != 0) \
{ \
if (global_options_set.x_rs6000_current_cmodel \
&& rs6000_current_cmodel != CMODEL_SMALL) \
@@ -213,20 +214,20 @@ extern int dot_symbols;
#ifndef RS6000_BI_ARCH
/* 64-bit PowerPC Linux is always big-endian. */
-#undef TARGET_LITTLE_ENDIAN
-#define TARGET_LITTLE_ENDIAN 0
+#undef OPTION_LITTLE_ENDIAN
+#define OPTION_LITTLE_ENDIAN 0
/* 64-bit PowerPC Linux always has a TOC. */
#undef TARGET_TOC
#define TARGET_TOC 1
/* Some things from sysv4.h we don't do when 64 bit. */
-#undef TARGET_RELOCATABLE
-#define TARGET_RELOCATABLE 0
-#undef TARGET_EABI
-#define TARGET_EABI 0
-#undef TARGET_PROTOTYPE
-#define TARGET_PROTOTYPE 0
+#undef OPTION_RELOCATABLE
+#define OPTION_RELOCATABLE 0
+#undef OPTION_EABI
+#define OPTION_EABI 0
+#undef OPTION_PROTOTYPE
+#define OPTION_PROTOTYPE 0
#undef RELOCATABLE_NEEDS_FIXUP
#define RELOCATABLE_NEEDS_FIXUP 0
diff --git a/gcc/config/rs6000/option-defaults.h b/gcc/config/rs6000/option-defaults.h
index 0ecbe75c0..aaa9b3dde 100644
--- a/gcc/config/rs6000/option-defaults.h
+++ b/gcc/config/rs6000/option-defaults.h
@@ -35,11 +35,12 @@
#define OPT_32 "m32"
#endif
-#ifndef MASK_64BIT
+#ifndef OPTION_MASK_64BIT
+#define OPTION_MASK_64BIT 0
#define MASK_64BIT 0
#endif
-#if TARGET_DEFAULT & MASK_64BIT
+#if TARGET_DEFAULT & OPTION_MASK_64BIT
#define OPT_ARCH64 "!"OPT_32
#define OPT_ARCH32 OPT_32
#else
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 99130ba6e..fc20a5e57 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -940,12 +940,16 @@
{
if (MEM_P (op))
{
+ if (! volatile_ok && MEM_VOLATILE_P (op))
+ return 0;
if (mode == DFmode)
mode = V2DFmode;
else if (mode == DImode)
mode = V2DImode;
else
- gcc_unreachable ();
+ gcc_unreachable ();
+ return memory_address_addr_space_p (mode, XEXP (op, 0),
+ MEM_ADDR_SPACE (op));
}
return input_operand (op, mode);
})
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 4c265665c..295015f6f 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -295,31 +295,31 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
(define_p) ? "define" : "undef",
flags, bu_mask);
- /* target_flags based options. */
+ /* rs6000_isa_flags based options. */
rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC");
- if ((flags & MASK_PPC_GPOPT) != 0)
+ if ((flags & OPTION_MASK_PPC_GPOPT) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCSQ");
- if ((flags & MASK_PPC_GFXOPT) != 0)
+ if ((flags & OPTION_MASK_PPC_GFXOPT) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCGR");
- if ((flags & MASK_POWERPC64) != 0)
+ if ((flags & OPTION_MASK_POWERPC64) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC64");
- if ((flags & MASK_MFCRF) != 0)
+ if ((flags & OPTION_MASK_MFCRF) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR4");
- if ((flags & MASK_POPCNTB) != 0)
+ if ((flags & OPTION_MASK_POPCNTB) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5");
- if ((flags & MASK_FPRND) != 0)
+ if ((flags & OPTION_MASK_FPRND) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5X");
- if ((flags & MASK_CMPB) != 0)
+ if ((flags & OPTION_MASK_CMPB) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6");
- if ((flags & MASK_MFPGPR) != 0)
+ if ((flags & OPTION_MASK_MFPGPR) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6X");
- if ((flags & MASK_POPCNTD) != 0)
+ if ((flags & OPTION_MASK_POPCNTD) != 0)
rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR7");
- if ((flags & MASK_SOFT_FLOAT) != 0)
+ if ((flags & OPTION_MASK_SOFT_FLOAT) != 0)
rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT");
- if ((flags & MASK_RECIP_PRECISION) != 0)
+ if ((flags & OPTION_MASK_RECIP_PRECISION) != 0)
rs6000_define_or_undefine_macro (define_p, "__RECIP_PRECISION__");
- if ((flags & MASK_ALTIVEC) != 0)
+ if ((flags & OPTION_MASK_ALTIVEC) != 0)
{
const char *vec_str = (define_p) ? "__VEC__=10206" : "__VEC__";
rs6000_define_or_undefine_macro (define_p, "__ALTIVEC__");
@@ -329,7 +329,7 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
if (!flag_iso)
rs6000_define_or_undefine_macro (define_p, "__APPLE_ALTIVEC__");
}
- if ((flags & MASK_VSX) != 0)
+ if ((flags & OPTION_MASK_VSX) != 0)
rs6000_define_or_undefine_macro (define_p, "__VSX__");
/* options from the builtin masks. */
@@ -345,7 +345,7 @@ void
rs6000_cpu_cpp_builtins (cpp_reader *pfile)
{
/* Define all of the common macros. */
- rs6000_target_modify_macros (true, target_flags,
+ rs6000_target_modify_macros (true, rs6000_isa_flags,
rs6000_builtin_mask_calculate ());
if (TARGET_FRE)
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index cfac0e732..fd4314649 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -18,6 +18,57 @@
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+/* ISA masks. */
+#ifndef ISA_2_1_MASKS
+#define ISA_2_1_MASKS OPTION_MASK_MFCRF
+#define ISA_2_2_MASKS (ISA_2_1_MASKS | OPTION_MASK_POPCNTB)
+#define ISA_2_4_MASKS (ISA_2_2_MASKS | OPTION_MASK_FPRND)
+
+ /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
+ ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
+ fre, fsqrt, etc. were no longer documented as optional. Group masks by
+ server and embedded. */
+#define ISA_2_5_MASKS_EMBEDDED (ISA_2_2_MASKS \
+ | OPTION_MASK_CMPB \
+ | OPTION_MASK_RECIP_PRECISION \
+ | OPTION_MASK_PPC_GFXOPT \
+ | OPTION_MASK_PPC_GPOPT)
+
+#define ISA_2_5_MASKS_SERVER (ISA_2_5_MASKS_EMBEDDED | OPTION_MASK_DFP)
+
+ /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
+ altivec is a win so enable it. */
+#define ISA_2_6_MASKS_EMBEDDED (ISA_2_5_MASKS_EMBEDDED | OPTION_MASK_POPCNTD)
+#define ISA_2_6_MASKS_SERVER (ISA_2_5_MASKS_SERVER \
+ | OPTION_MASK_POPCNTD \
+ | OPTION_MASK_ALTIVEC \
+ | OPTION_MASK_VSX)
+
+#define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC)
+
+/* Mask of all options to set the default isa flags based on -mcpu=<xxx>. */
+#define POWERPC_MASKS (OPTION_MASK_ALTIVEC \
+ | OPTION_MASK_CMPB \
+ | OPTION_MASK_DFP \
+ | OPTION_MASK_DLMZB \
+ | OPTION_MASK_FPRND \
+ | OPTION_MASK_ISEL \
+ | OPTION_MASK_MFCRF \
+ | OPTION_MASK_MFPGPR \
+ | OPTION_MASK_MULHW \
+ | OPTION_MASK_NO_UPDATE \
+ | OPTION_MASK_POPCNTB \
+ | OPTION_MASK_POPCNTD \
+ | OPTION_MASK_POWERPC64 \
+ | OPTION_MASK_PPC_GFXOPT \
+ | OPTION_MASK_PPC_GPOPT \
+ | OPTION_MASK_RECIP_PRECISION \
+ | OPTION_MASK_SOFT_FLOAT \
+ | OPTION_MASK_STRICT_ALIGN \
+ | OPTION_MASK_VSX)
+
+#endif
+
/* This table occasionally claims that a processor does not support a
particular feature even though it does, but the feature is slower than the
alternative. Thus, it shouldn't be relied on as a complete description of
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b6f3a9c94..81dc6f32d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1121,7 +1121,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
{ NULL, 0, 0, false, false, false, NULL, false }
};
-#ifndef MASK_STRICT_ALIGN
+#ifndef OPTION_MASK_STRICT_ALIGN
+#define OPTION_MASK_STRICT_ALIGN 0
#define MASK_STRICT_ALIGN 0
#endif
#ifndef TARGET_PROFILE_KERNEL
@@ -1464,48 +1465,7 @@ static const struct attribute_spec rs6000_attribute_table[] =
#define TARGET_VECTORIZE_VEC_PERM_CONST_OK rs6000_vectorize_vec_perm_const_ok
-/* Simplifications for entries below. */
-
-enum {
- POWERPC_7400_MASK = MASK_PPC_GFXOPT | MASK_ALTIVEC
-};
-
-/* Some OSs don't support saving the high part of 64-bit registers on context
- switch. Other OSs don't support saving Altivec registers. On those OSs, we
- don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
- either, the user must explicitly specify them and we won't interfere with
- the user's specification. */
-
-enum {
- POWERPC_MASKS = (MASK_PPC_GPOPT | MASK_STRICT_ALIGN
- | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
- | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
- | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
- | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
- | MASK_RECIP_PRECISION)
-};
-
-/* Masks for instructions set at various powerpc ISAs. */
-enum {
- ISA_2_1_MASKS = MASK_MFCRF,
- ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
- ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
-
- /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
- ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
- fre, fsqrt, etc. were no longer documented as optional. Group masks by
- server and embedded. */
- ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
- | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
- ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
-
- /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
- altivec is a win so enable it. */
- ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
- ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
- | MASK_VSX)
-};
-
+/* Processor table. */
struct rs6000_ptt
{
const char *const name; /* Canonical processor name. */
@@ -2357,21 +2317,21 @@ darwin_rs6000_override_options (void)
if (TARGET_64BIT && ! TARGET_POWERPC64)
{
- target_flags |= MASK_POWERPC64;
+ rs6000_isa_flags |= OPTION_MASK_POWERPC64;
warning (0, "-m64 requires PowerPC64 architecture, enabling");
}
if (flag_mkernel)
{
rs6000_default_long_calls = 1;
- target_flags |= MASK_SOFT_FLOAT;
+ rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT;
}
/* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
Altivec. */
if (!flag_mkernel && !flag_apple_kext
&& TARGET_64BIT
- && ! (target_flags_explicit & MASK_ALTIVEC))
- target_flags |= MASK_ALTIVEC;
+ && ! (rs6000_isa_flags_explicit & OPTION_MASK_ALTIVEC))
+ rs6000_isa_flags |= OPTION_MASK_ALTIVEC;
/* Unless the user (not the configurer) has explicitly overridden
it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
@@ -2379,10 +2339,10 @@ darwin_rs6000_override_options (void)
if (!flag_mkernel
&& !flag_apple_kext
&& strverscmp (darwin_macosx_version_min, "10.5") >= 0
- && ! (target_flags_explicit & MASK_ALTIVEC)
+ && ! (rs6000_isa_flags_explicit & OPTION_MASK_ALTIVEC)
&& ! global_options_set.x_rs6000_cpu_index)
{
- target_flags |= MASK_ALTIVEC;
+ rs6000_isa_flags |= OPTION_MASK_ALTIVEC;
}
}
#endif
@@ -2463,18 +2423,24 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_pointer_size = 32;
}
- set_masks = POWERPC_MASKS | MASK_SOFT_FLOAT;
+ /* Some OSs don't support saving the high part of 64-bit registers on context
+ switch. Other OSs don't support saving Altivec registers. On those OSs,
+ we don't touch the OPTION_MASK_POWERPC64 or OPTION_MASK_ALTIVEC settings;
+ if the user wants either, the user must explicitly specify them and we
+ won't interfere with the user's specification. */
+
+ set_masks = POWERPC_MASKS;
#ifdef OS_MISSING_POWERPC64
if (OS_MISSING_POWERPC64)
- set_masks &= ~MASK_POWERPC64;
+ set_masks &= ~OPTION_MASK_POWERPC64;
#endif
#ifdef OS_MISSING_ALTIVEC
if (OS_MISSING_ALTIVEC)
- set_masks &= ~MASK_ALTIVEC;
+ set_masks &= ~(OPTION_MASK_ALTIVEC | OPTION_MASK_VSX);
#endif
/* Don't override by the processor default if given explicitly. */
- set_masks &= ~target_flags_explicit;
+ set_masks &= ~rs6000_isa_flags_explicit;
/* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
the cpu in a target attribute or pragma, but did not specify a tuning
@@ -2512,13 +2478,20 @@ rs6000_option_override_internal (bool global_init_p)
TARGET_DEFAULT. */
if (have_cpu)
{
- target_flags &= ~set_masks;
- target_flags |= (processor_target_table[cpu_index].target_enable
- & set_masks);
+ rs6000_isa_flags &= ~set_masks;
+ rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable
+ & set_masks);
}
else
- target_flags |= (processor_target_table[cpu_index].target_enable
- & ~target_flags_explicit);
+ rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable
+ & ~rs6000_isa_flags_explicit);
+
+ /* If no -mcpu=<xxx>, inherit any default options that were cleared via
+ POWERPC_MASKS. Originally, TARGET_DEFAULT was used to initialize
+ target_flags via the TARGET_DEFAULT_TARGET_FLAGS hook. When we switched
+ to using rs6000_isa_flags, we need to do the initialization here. */
+ if (!have_cpu)
+ rs6000_isa_flags |= (TARGET_DEFAULT & ~rs6000_isa_flags_explicit);
if (rs6000_tune_index >= 0)
tune_index = rs6000_tune_index;
@@ -2603,7 +2576,8 @@ rs6000_option_override_internal (bool global_init_p)
use instructions that would be microcoded on the Cell, use the
load/store multiple and string instructions. */
if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
- target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
+ rs6000_isa_flags |= ~rs6000_isa_flags_explicit & (OPTION_MASK_MULTIPLE
+ | OPTION_MASK_STRING);
/* Don't allow -mmultiple or -mstring on little endian systems
unless the cpu is a 750, because the hardware doesn't support the
@@ -2615,15 +2589,15 @@ rs6000_option_override_internal (bool global_init_p)
{
if (TARGET_MULTIPLE)
{
- target_flags &= ~MASK_MULTIPLE;
- if ((target_flags_explicit & MASK_MULTIPLE) != 0)
+ rs6000_isa_flags &= ~OPTION_MASK_MULTIPLE;
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_MULTIPLE) != 0)
warning (0, "-mmultiple is not supported on little endian systems");
}
if (TARGET_STRING)
{
- target_flags &= ~MASK_STRING;
- if ((target_flags_explicit & MASK_STRING) != 0)
+ rs6000_isa_flags &= ~OPTION_MASK_STRING;
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_STRING) != 0)
warning (0, "-mstring is not supported on little endian systems");
}
}
@@ -2635,10 +2609,10 @@ rs6000_option_override_internal (bool global_init_p)
if (!TARGET_HARD_FLOAT || !TARGET_FPRS
|| !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
{
- if (target_flags_explicit & MASK_VSX)
+ if (rs6000_isa_flags_explicit & OPTION_MASK_VSX)
msg = N_("-mvsx requires hardware floating point");
else
- target_flags &= ~ MASK_VSX;
+ rs6000_isa_flags &= ~ OPTION_MASK_VSX;
}
else if (TARGET_PAIRED_FLOAT)
msg = N_("-mvsx and -mpaired are incompatible");
@@ -2649,9 +2623,10 @@ rs6000_option_override_internal (bool global_init_p)
msg = N_("-mvsx used with little endian code");
else if (TARGET_AVOID_XFORM > 0)
msg = N_("-mvsx needs indexed addressing");
- else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
+ else if (!TARGET_ALTIVEC && (rs6000_isa_flags_explicit
+ & OPTION_MASK_ALTIVEC))
{
- if (target_flags_explicit & MASK_VSX)
+ if (rs6000_isa_flags_explicit & OPTION_MASK_VSX)
msg = N_("-mvsx and -mno-altivec are incompatible");
else
msg = N_("-mno-altivec disables vsx");
@@ -2660,27 +2635,27 @@ rs6000_option_override_internal (bool global_init_p)
if (msg)
{
warning (0, msg);
- target_flags &= ~ MASK_VSX;
- target_flags_explicit |= MASK_VSX;
+ rs6000_isa_flags &= ~ OPTION_MASK_VSX;
+ rs6000_isa_flags_explicit |= OPTION_MASK_VSX;
}
}
/* For the newer switches (vsx, dfp, etc.) set some of the older options,
unless the user explicitly used the -mno-<option> to disable the code. */
if (TARGET_VSX)
- target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
+ rs6000_isa_flags |= (ISA_2_6_MASKS_SERVER & ~rs6000_isa_flags_explicit);
else if (TARGET_POPCNTD)
- target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
+ rs6000_isa_flags |= (ISA_2_6_MASKS_EMBEDDED & ~rs6000_isa_flags_explicit);
else if (TARGET_DFP)
- target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
+ rs6000_isa_flags |= (ISA_2_5_MASKS_SERVER & ~rs6000_isa_flags_explicit);
else if (TARGET_CMPB)
- target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
+ rs6000_isa_flags |= (ISA_2_5_MASKS_EMBEDDED & ~rs6000_isa_flags_explicit);
else if (TARGET_FPRND)
- target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
+ rs6000_isa_flags |= (ISA_2_4_MASKS & ~rs6000_isa_flags_explicit);
else if (TARGET_POPCNTB)
- target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
+ rs6000_isa_flags |= (ISA_2_2_MASKS & ~rs6000_isa_flags_explicit);
else if (TARGET_ALTIVEC)
- target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
+ rs6000_isa_flags |= (OPTION_MASK_PPC_GFXOPT & ~rs6000_isa_flags_explicit);
/* E500mc does "better" if we inline more aggressively. Respect the
user's opinion, though. */
@@ -2759,7 +2734,8 @@ rs6000_option_override_internal (bool global_init_p)
unless the altivec ABI was set. This is set by default for 64-bit, but
not for 32-bit. */
if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
- target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
+ rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC)
+ & ~rs6000_isa_flags_explicit);
/* Enable Altivec ABI for AIX -maltivec. */
if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
@@ -2837,14 +2813,14 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_single_float = TARGET_E500_SINGLE || TARGET_E500_DOUBLE;
rs6000_double_float = TARGET_E500_DOUBLE;
- target_flags &= ~MASK_STRING;
+ rs6000_isa_flags &= ~OPTION_MASK_STRING;
break;
default:
- if (have_cpu && !(target_flags_explicit & MASK_ISEL))
- target_flags &= ~MASK_ISEL;
+ if (have_cpu && !(rs6000_isa_flags_explicit & OPTION_MASK_ISEL))
+ rs6000_isa_flags &= ~OPTION_MASK_ISEL;
break;
}
@@ -25330,7 +25306,7 @@ rs6000_darwin_file_start (void)
i = 0;
while (mapping[i].arg != NULL
&& strcmp (mapping[i].arg, cpu_id) != 0
- && (mapping[i].if_set & target_flags) == 0)
+ && (mapping[i].if_set & rs6000_isa_flags) == 0)
i++;
fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
@@ -27431,48 +27407,48 @@ struct rs6000_opt_mask {
static struct rs6000_opt_mask const rs6000_opt_masks[] =
{
- { "altivec", MASK_ALTIVEC, false, true },
- { "cmpb", MASK_CMPB, false, true },
- { "dlmzb", MASK_DLMZB, false, true },
- { "fprnd", MASK_FPRND, false, true },
- { "hard-dfp", MASK_DFP, false, true },
- { "isel", MASK_ISEL, false, true },
- { "mfcrf", MASK_MFCRF, false, true },
- { "mfpgpr", MASK_MFPGPR, false, true },
- { "mulhw", MASK_MULHW, false, true },
- { "multiple", MASK_MULTIPLE, false, true },
- { "update", MASK_NO_UPDATE, true , true },
- { "popcntb", MASK_POPCNTB, false, true },
- { "popcntd", MASK_POPCNTD, false, true },
- { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
- { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
- { "recip-precision", MASK_RECIP_PRECISION, false, true },
- { "string", MASK_STRING, false, true },
- { "vsx", MASK_VSX, false, true },
-#ifdef MASK_64BIT
+ { "altivec", OPTION_MASK_ALTIVEC, false, true },
+ { "cmpb", OPTION_MASK_CMPB, false, true },
+ { "dlmzb", OPTION_MASK_DLMZB, false, true },
+ { "fprnd", OPTION_MASK_FPRND, false, true },
+ { "hard-dfp", OPTION_MASK_DFP, false, true },
+ { "isel", OPTION_MASK_ISEL, false, true },
+ { "mfcrf", OPTION_MASK_MFCRF, false, true },
+ { "mfpgpr", OPTION_MASK_MFPGPR, false, true },
+ { "mulhw", OPTION_MASK_MULHW, false, true },
+ { "multiple", OPTION_MASK_MULTIPLE, false, true },
+ { "update", OPTION_MASK_NO_UPDATE, true , true },
+ { "popcntb", OPTION_MASK_POPCNTB, false, true },
+ { "popcntd", OPTION_MASK_POPCNTD, false, true },
+ { "powerpc-gfxopt", OPTION_MASK_PPC_GFXOPT, false, true },
+ { "powerpc-gpopt", OPTION_MASK_PPC_GPOPT, false, true },
+ { "recip-precision", OPTION_MASK_RECIP_PRECISION, false, true },
+ { "string", OPTION_MASK_STRING, false, true },
+ { "vsx", OPTION_MASK_VSX, false, true },
+#ifdef OPTION_MASK_64BIT
#if TARGET_AIX_OS
- { "aix64", MASK_64BIT, false, false },
- { "aix32", MASK_64BIT, true, false },
+ { "aix64", OPTION_MASK_64BIT, false, false },
+ { "aix32", OPTION_MASK_64BIT, true, false },
#else
- { "64", MASK_64BIT, false, false },
- { "32", MASK_64BIT, true, false },
+ { "64", OPTION_MASK_64BIT, false, false },
+ { "32", OPTION_MASK_64BIT, true, false },
#endif
#endif
-#ifdef MASK_EABI
- { "eabi", MASK_EABI, false, false },
+#ifdef OPTION_MASK_EABI
+ { "eabi", OPTION_MASK_EABI, false, false },
#endif
-#ifdef MASK_LITTLE_ENDIAN
- { "little", MASK_LITTLE_ENDIAN, false, false },
- { "big", MASK_LITTLE_ENDIAN, true, false },
+#ifdef OPTION_MASK_LITTLE_ENDIAN
+ { "little", OPTION_MASK_LITTLE_ENDIAN, false, false },
+ { "big", OPTION_MASK_LITTLE_ENDIAN, true, false },
#endif
-#ifdef MASK_RELOCATABLE
- { "relocatable", MASK_RELOCATABLE, false, false },
+#ifdef OPTION_MASK_RELOCATABLE
+ { "relocatable", OPTION_MASK_RELOCATABLE, false, false },
#endif
-#ifdef MASK_STRICT_ALIGN
- { "strict-align", MASK_STRICT_ALIGN, false, false },
+#ifdef OPTION_MASK_STRICT_ALIGN
+ { "strict-align", OPTION_MASK_STRICT_ALIGN, false, false },
#endif
- { "soft-float", MASK_SOFT_FLOAT, false, false },
- { "string", MASK_STRING, false, false },
+ { "soft-float", OPTION_MASK_SOFT_FLOAT, false, false },
+ { "string", OPTION_MASK_STRING, false, false },
};
/* Builtin mask mapping for printing the flags. */
@@ -27583,20 +27559,20 @@ rs6000_inner_target_options (tree args, bool attr_p)
else
{
error_p = false;
- target_flags_explicit |= mask;
+ rs6000_isa_flags_explicit |= mask;
/* VSX needs altivec, so -mvsx automagically sets
altivec. */
- if (mask == MASK_VSX && !invert)
- mask |= MASK_ALTIVEC;
+ if (mask == OPTION_MASK_VSX && !invert)
+ mask |= OPTION_MASK_ALTIVEC;
if (rs6000_opt_masks[i].invert)
invert = !invert;
if (invert)
- target_flags &= ~mask;
+ rs6000_isa_flags &= ~mask;
else
- target_flags |= mask;
+ rs6000_isa_flags |= mask;
}
break;
}
@@ -27851,14 +27827,14 @@ rs6000_pragma_target_parse (tree args, tree pop_target)
{
prev_opt = TREE_TARGET_OPTION (prev_tree);
prev_bumask = prev_opt->x_rs6000_builtin_mask;
- prev_flags = prev_opt->x_target_flags;
+ prev_flags = prev_opt->x_rs6000_isa_flags;
cur_opt = TREE_TARGET_OPTION (cur_tree);
- cur_flags = cur_opt->x_target_flags;
+ cur_flags = cur_opt->x_rs6000_isa_flags;
cur_bumask = cur_opt->x_rs6000_builtin_mask;
diff_bumask = (prev_bumask ^ cur_bumask);
- diff_flags = (prev_flags ^ cur_flags);
+ diff_flags = (prev_flags ^ cur_flags);
if ((diff_flags != 0) || (diff_bumask != 0))
{
@@ -27961,7 +27937,8 @@ rs6000_set_current_function (tree fndecl)
static void
rs6000_function_specific_save (struct cl_target_option *ptr)
{
- ptr->rs6000_target_flags_explicit = target_flags_explicit;
+ ptr->x_rs6000_isa_flags = rs6000_isa_flags;
+ ptr->x_rs6000_isa_flags_explicit = rs6000_isa_flags_explicit;
}
/* Restore the current options */
@@ -27969,7 +27946,8 @@ rs6000_function_specific_save (struct cl_target_option *ptr)
static void
rs6000_function_specific_restore (struct cl_target_option *ptr)
{
- target_flags_explicit = ptr->rs6000_target_flags_explicit;
+ rs6000_isa_flags = ptr->x_rs6000_isa_flags;
+ rs6000_isa_flags_explicit = ptr->x_rs6000_isa_flags_explicit;
(void) rs6000_option_override_internal (false);
}
@@ -27980,10 +27958,10 @@ rs6000_function_specific_print (FILE *file, int indent,
struct cl_target_option *ptr)
{
rs6000_print_isa_options (file, indent, "Isa options set",
- ptr->x_target_flags);
+ ptr->x_rs6000_isa_flags);
rs6000_print_isa_options (file, indent, "Isa options explicit",
- ptr->rs6000_target_flags_explicit);
+ ptr->x_rs6000_isa_flags_explicit);
}
/* Helper function to print the current isa or misc options on a line. */
@@ -28093,8 +28071,8 @@ rs6000_can_inline_p (tree caller, tree callee)
/* Callee's options should a subset of the caller's, i.e. a vsx function
can inline an altivec function but a non-vsx function can't inline a
vsx function. */
- if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
- == callee_opts->x_target_flags)
+ if ((caller_opts->x_rs6000_isa_flags & callee_opts->x_rs6000_isa_flags)
+ == callee_opts->x_rs6000_isa_flags)
ret = true;
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 82388d93b..d299e6313 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -465,6 +465,64 @@ extern int rs6000_vector_align[];
#define TARGET_FCTIDUZ TARGET_POPCNTD
#define TARGET_FCTIWUZ TARGET_POPCNTD
+/* In switching from using target_flags to using rs6000_isa_flags, the options
+ machinery creates OPTION_MASK_<xxx> instead of MASK_<xxx>. For now map
+ OPTION_MASK_<xxx> back into MASK_<xxx>. */
+#define MASK_ALTIVEC OPTION_MASK_ALTIVEC
+#define MASK_CMPB OPTION_MASK_CMPB
+#define MASK_DFP OPTION_MASK_DFP
+#define MASK_DLMZB OPTION_MASK_DLMZB
+#define MASK_EABI OPTION_MASK_EABI
+#define MASK_FPRND OPTION_MASK_FPRND
+#define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT
+#define MASK_ISEL OPTION_MASK_ISEL
+#define MASK_MFCRF OPTION_MASK_MFCRF
+#define MASK_MFPGPR OPTION_MASK_MFPGPR
+#define MASK_MULHW OPTION_MASK_MULHW
+#define MASK_MULTIPLE OPTION_MASK_MULTIPLE
+#define MASK_NO_UPDATE OPTION_MASK_NO_UPDATE
+#define MASK_POPCNTB OPTION_MASK_POPCNTB
+#define MASK_POPCNTD OPTION_MASK_POPCNTD
+#define MASK_PPC_GFXOPT OPTION_MASK_PPC_GFXOPT
+#define MASK_PPC_GPOPT OPTION_MASK_PPC_GPOPT
+#define MASK_RECIP_PRECISION OPTION_MASK_RECIP_PRECISION
+#define MASK_SOFT_FLOAT OPTION_MASK_SOFT_FLOAT
+#define MASK_STRICT_ALIGN OPTION_MASK_STRICT_ALIGN
+#define MASK_STRING OPTION_MASK_STRING
+#define MASK_UPDATE OPTION_MASK_UPDATE
+#define MASK_VSX OPTION_MASK_VSX
+
+#ifndef IN_LIBGCC2
+#define MASK_POWERPC64 OPTION_MASK_POWERPC64
+#endif
+
+#ifdef TARGET_64BIT
+#define MASK_64BIT OPTION_MASK_64BIT
+#endif
+
+#ifdef TARGET_RELOCATABLE
+#define MASK_RELOCATABLE OPTION_MASK_RELOCATABLE
+#endif
+
+#ifdef TARGET_LITTLE_ENDIAN
+#define MASK_LITTLE_ENDIAN OPTION_MASK_LITTLE_ENDIAN
+#endif
+
+#ifdef TARGET_MINIMAL_TOC
+#define MASK_MINIMAL_TOC OPTION_MASK_MINIMAL_TOC
+#endif
+
+#ifdef TARGET_REGNAMES
+#define MASK_REGNAMES OPTION_MASK_REGNAMES
+#endif
+
+#ifdef TARGET_PROTOTYPE
+#define MASK_PROTOTYPE OPTION_MASK_PROTOTYPE
+#endif
+
+/* Explicit ISA options that were set. */
+#define rs6000_isa_flags_explicit global_options_set.x_rs6000_isa_flags
+
/* For power systems, we want to enable Altivec and VSX builtins even if the
user did not use -maltivec or -mvsx to allow the builtins to be used inside
of #pragma GCC target or the target attribute to change the code level for a
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 96f4f6a83..2625bd72c 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -11134,15 +11134,26 @@
""
"")
-(define_insn "probe_stack"
+(define_expand "probe_stack"
[(set (match_operand 0 "memory_operand" "=m")
(unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
""
- "*
+{
+ if (TARGET_64BIT)
+ emit_insn (gen_probe_stack_di (operands[0]));
+ else
+ emit_insn (gen_probe_stack_si (operands[0]));
+ DONE;
+})
+
+(define_insn "probe_stack_<mode>"
+ [(set (match_operand:P 0 "memory_operand" "=m")
+ (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
+ ""
{
operands[1] = gen_rtx_REG (Pmode, 0);
- return \"stw%U0%X0 %1,%0\";
-}"
+ return "st<wd>%U0%X0 %1,%0";
+}
[(set_attr "type" "store")
(set_attr "length" "4")])
@@ -11560,7 +11571,8 @@
;; Same as above, but get the OV/ORDERED bit.
(define_insn "move_from_CR_ov_bit"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
+ (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
+ UNSPEC_MV_CR_OV))]
"TARGET_ISEL"
"mfcr %0\;rlwinm %0,%0,%t1,1"
[(set_attr "type" "mfcr")
@@ -12008,9 +12020,9 @@
(define_split
[(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
- (compare:CC (ne:P (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (compare:CC (ne:P (match_operand:SI 1 "gpc_reg_operand" "")
(const_int 0))
- (neg:P (match_operand:P 2 "gpc_reg_operand" "r,r"))))
+ (neg:P (match_operand:P 2 "gpc_reg_operand" ""))))
(clobber (match_scratch:P 3 ""))
(clobber (match_scratch:P 4 ""))]
"reload_completed"
@@ -12041,9 +12053,9 @@
(define_split
[(set (match_operand:CCEQ 0 "cc_reg_not_micro_cr0_operand" "")
- (compare:CCEQ (ne:P (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (compare:CCEQ (ne:P (match_operand:SI 1 "gpc_reg_operand" "")
(const_int 0))
- (neg:P (match_operand:P 2 "gpc_reg_operand" "r,r"))))
+ (neg:P (match_operand:P 2 "gpc_reg_operand" ""))))
(clobber (match_scratch:P 3 ""))
(clobber (match_scratch:P 4 ""))]
"reload_completed"
@@ -13085,7 +13097,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
- (use (match_operand 4 "" ""))] ; label
+ (use (match_operand 4 "" "")) ; label
+ (use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
""
"
{
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 58b769438..0f38e1792 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -22,6 +22,17 @@
HeaderInclude
config/rs6000/rs6000-opts.h
+;; ISA flag bits (on/off)
+Variable
+HOST_WIDE_INT rs6000_isa_flags = TARGET_DEFAULT
+
+TargetSave
+HOST_WIDE_INT x_rs6000_isa_flags
+
+;; Miscellaneous flag bits that were set explicitly by the user
+TargetSave
+HOST_WIDE_INT x_rs6000_isa_flags_explicit
+
;; Current processor
TargetVariable
enum processor_type rs6000_cpu = PROCESSOR_PPC603
@@ -86,80 +97,76 @@ HOST_WIDE_INT rs6000_builtin_mask
TargetVariable
unsigned int rs6000_debug
-;; Save for target_flags_explicit
-TargetSave
-int rs6000_target_flags_explicit
-
;; This option existed in the past, but now is always on.
mpowerpc
Target RejectNegative Undocumented Ignore
mpowerpc64
-Target Report Mask(POWERPC64)
+Target Report Mask(POWERPC64) Var(rs6000_isa_flags)
Use PowerPC-64 instruction set
mpowerpc-gpopt
-Target Report Mask(PPC_GPOPT) Save
+Target Report Mask(PPC_GPOPT) Var(rs6000_isa_flags)
Use PowerPC General Purpose group optional instructions
mpowerpc-gfxopt
-Target Report Mask(PPC_GFXOPT) Save
+Target Report Mask(PPC_GFXOPT) Var(rs6000_isa_flags)
Use PowerPC Graphics group optional instructions
mmfcrf
-Target Report Mask(MFCRF) Save
+Target Report Mask(MFCRF) Var(rs6000_isa_flags)
Use PowerPC V2.01 single field mfcr instruction
mpopcntb
-Target Report Mask(POPCNTB) Save
+Target Report Mask(POPCNTB) Var(rs6000_isa_flags)
Use PowerPC V2.02 popcntb instruction
mfprnd
-Target Report Mask(FPRND) Save
+Target Report Mask(FPRND) Var(rs6000_isa_flags)
Use PowerPC V2.02 floating point rounding instructions
mcmpb
-Target Report Mask(CMPB) Save
+Target Report Mask(CMPB) Var(rs6000_isa_flags)
Use PowerPC V2.05 compare bytes instruction
mmfpgpr
-Target Report Mask(MFPGPR) Save
+Target Report Mask(MFPGPR) Var(rs6000_isa_flags)
Use extended PowerPC V2.05 move floating point to/from GPR instructions
maltivec
-Target Report Mask(ALTIVEC) Save
+Target Report Mask(ALTIVEC) Var(rs6000_isa_flags)
Use AltiVec instructions
mhard-dfp
-Target Report Mask(DFP) Save
+Target Report Mask(DFP) Var(rs6000_isa_flags)
Use decimal floating point instructions
mmulhw
-Target Report Mask(MULHW) Save
+Target Report Mask(MULHW) Var(rs6000_isa_flags)
Use 4xx half-word multiply instructions
mdlmzb
-Target Report Mask(DLMZB) Save
+Target Report Mask(DLMZB) Var(rs6000_isa_flags)
Use 4xx string-search dlmzb instruction
mmultiple
-Target Report Mask(MULTIPLE) Save
+Target Report Mask(MULTIPLE) Var(rs6000_isa_flags)
Generate load/store multiple instructions
mstring
-Target Report Mask(STRING) Save
+Target Report Mask(STRING) Var(rs6000_isa_flags)
Generate string instructions for block moves
msoft-float
-Target Report RejectNegative Mask(SOFT_FLOAT)
+Target Report RejectNegative Mask(SOFT_FLOAT) Var(rs6000_isa_flags)
Do not use hardware floating point
mhard-float
-Target Report RejectNegative InverseMask(SOFT_FLOAT, HARD_FLOAT)
+Target Report RejectNegative InverseMask(SOFT_FLOAT, HARD_FLOAT) Var(rs6000_isa_flags)
Use hardware floating point
mpopcntd
-Target Report Mask(POPCNTD) Save
+Target Report Mask(POPCNTD) Var(rs6000_isa_flags)
Use PowerPC V2.06 popcntd instruction
mfriz
@@ -171,7 +178,7 @@ Target RejectNegative Joined Var(rs6000_veclibabi_name)
Vector library ABI to use
mvsx
-Target Report Mask(VSX) Save
+Target Report Mask(VSX) Var(rs6000_isa_flags)
Use vector/scalar (VSX) instructions
mvsx-scalar-double
@@ -211,11 +218,11 @@ Target Undocumented Report Var(TARGET_VECTORIZE_BUILTINS) Init(-1)
; Explicitly control whether we vectorize the builtins or not.
mno-update
-Target Report RejectNegative Mask(NO_UPDATE) Save
+Target Report RejectNegative Mask(NO_UPDATE) Var(rs6000_isa_flags)
Do not generate load/store with update instructions
mupdate
-Target Report RejectNegative InverseMask(NO_UPDATE, UPDATE)
+Target Report RejectNegative InverseMask(NO_UPDATE, UPDATE) Var(rs6000_isa_flags)
Generate load/store with update instructions
msingle-pic-base
@@ -258,7 +265,7 @@ Target Report RejectNegative Joined Var(rs6000_recip_name)
Generate software reciprocal divide and square root for better throughput.
mrecip-precision
-Target Report Mask(RECIP_PRECISION) Save
+Target Report Mask(RECIP_PRECISION) Var(rs6000_isa_flags)
Assume that the reciprocal estimate instructions provide more accuracy.
mno-fp-in-toc
@@ -285,7 +292,7 @@ Place symbol+offset constants in TOC
; This is at the cost of having 2 extra loads and one extra store per
; function, and one less allocable register.
mminimal-toc
-Target Report Mask(MINIMAL_TOC)
+Target Report Mask(MINIMAL_TOC) Var(rs6000_isa_flags)
Use only one TOC entry per procedure
mfull-toc
@@ -309,7 +316,7 @@ Target Report Var(rs6000_block_move_inline_limit) Init(0) RejectNegative Joined
Specify how many bytes should be moved inline before calling out to memcpy/memmove
misel
-Target Report Mask(ISEL) Save
+Target Report Mask(ISEL) Var(rs6000_isa_flags)
Generate isel instructions
misel=no
diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md
index ab60cbcd4..42ac90373 100644
--- a/gcc/config/rs6000/sync.md
+++ b/gcc/config/rs6000/sync.md
@@ -100,8 +100,8 @@
;; The control dependency used for load dependency described
;; in B.2.3 of the Power ISA 2.06B.
-(define_insn "loadsync"
- [(unspec_volatile:BLK [(match_operand 0 "register_operand" "r")]
+(define_insn "loadsync_<mode>"
+ [(unspec_volatile:BLK [(match_operand:INT1 0 "register_operand" "r")]
UNSPECV_ISYNC)
(clobber (match_scratch:CC 1 "=y"))]
""
@@ -129,7 +129,16 @@
case MEMMODEL_CONSUME:
case MEMMODEL_ACQUIRE:
case MEMMODEL_SEQ_CST:
- emit_insn (gen_loadsync (operands[0]));
+ if (GET_MODE (operands[0]) == QImode)
+ emit_insn (gen_loadsync_qi (operands[0]));
+ else if (GET_MODE (operands[0]) == HImode)
+ emit_insn (gen_loadsync_hi (operands[0]));
+ else if (GET_MODE (operands[0]) == SImode)
+ emit_insn (gen_loadsync_si (operands[0]));
+ else if (GET_MODE (operands[0]) == DImode)
+ emit_insn (gen_loadsync_di (operands[0]));
+ else
+ gcc_unreachable ();
break;
default:
gcc_unreachable ();
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 978ba31ab..70a5908fb 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -40,9 +40,10 @@
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc"
-#define TARGET_TOC ((target_flags & MASK_64BIT) \
- || ((target_flags & (MASK_RELOCATABLE \
- | MASK_MINIMAL_TOC)) \
+#define TARGET_TOC ((rs6000_isa_flags & OPTION_MASK_64BIT) \
+ || ((rs6000_isa_flags \
+ & (OPTION_MASK_RELOCATABLE \
+ | OPTION_MASK_MINIMAL_TOC)) \
&& flag_pic > 1) \
|| DEFAULT_ABI == ABI_AIX)
@@ -77,13 +78,13 @@ do { \
else if (!strcmp (rs6000_abi_name, "sysv-noeabi")) \
{ \
rs6000_current_abi = ABI_V4; \
- target_flags &= ~ MASK_EABI; \
+ rs6000_isa_flags &= ~ OPTION_MASK_EABI; \
} \
else if (!strcmp (rs6000_abi_name, "sysv-eabi") \
|| !strcmp (rs6000_abi_name, "eabi")) \
{ \
rs6000_current_abi = ABI_V4; \
- target_flags |= MASK_EABI; \
+ rs6000_isa_flags |= OPTION_MASK_EABI; \
} \
else if (!strcmp (rs6000_abi_name, "aixdesc")) \
rs6000_current_abi = ABI_AIX; \
@@ -102,8 +103,8 @@ do { \
else if (!strcmp (rs6000_abi_name, "i960-old")) \
{ \
rs6000_current_abi = ABI_V4; \
- target_flags |= (MASK_LITTLE_ENDIAN | MASK_EABI); \
- target_flags &= ~MASK_STRICT_ALIGN; \
+ rs6000_isa_flags |= (OPTION_MASK_LITTLE_ENDIAN | OPTION_MASK_EABI); \
+ rs6000_isa_flags &= ~OPTION_MASK_STRICT_ALIGN; \
TARGET_NO_BITFIELD_WORD = 1; \
} \
else \
@@ -168,13 +169,13 @@ do { \
\
if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \
{ \
- target_flags |= MASK_MINIMAL_TOC; \
+ rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; \
error ("-mrelocatable and -mno-minimal-toc are incompatible"); \
} \
\
if (TARGET_RELOCATABLE && rs6000_current_abi == ABI_AIX) \
{ \
- target_flags &= ~MASK_RELOCATABLE; \
+ rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \
error ("-mrelocatable and -mcall-%s are incompatible", \
rs6000_abi_name); \
} \
@@ -188,7 +189,7 @@ do { \
\
if (rs6000_current_abi == ABI_AIX && TARGET_LITTLE_ENDIAN) \
{ \
- target_flags &= ~MASK_LITTLE_ENDIAN; \
+ rs6000_isa_flags &= ~OPTION_MASK_LITTLE_ENDIAN; \
error ("-mcall-aixdesc must be big endian"); \
} \
\
@@ -200,7 +201,7 @@ do { \
/* Treat -fPIC the same as -mrelocatable. */ \
if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX) \
{ \
- target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; \
+ rs6000_isa_flags |= OPTION_MASK_RELOCATABLE | OPTION_MASK_MINIMAL_TOC; \
TARGET_NO_FP_IN_TOC = 1; \
} \
\
@@ -212,9 +213,9 @@ do { \
#ifndef RS6000_BI_ARCH
# define SUBSUBTARGET_OVERRIDE_OPTIONS \
do { \
- if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+ if ((TARGET_DEFAULT ^ rs6000_isa_flags) & OPTION_MASK_64BIT) \
error ("-m%s not supported in this configuration", \
- (target_flags & MASK_64BIT) ? "64" : "32"); \
+ (rs6000_isa_flags & OPTION_MASK_64BIT) ? "64" : "32"); \
} while (0)
#endif
@@ -500,8 +501,8 @@ extern int fixuplabelno;
#define TARGET_OS_SYSV_CPP_BUILTINS() \
do \
{ \
- if (target_flags_explicit \
- & MASK_RELOCATABLE) \
+ if (rs6000_isa_flags_explicit \
+ & OPTION_MASK_RELOCATABLE) \
builtin_define ("_RELOCATABLE"); \
} \
while (0)
diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt
index 474203d6a..60ca4fd86 100644
--- a/gcc/config/rs6000/sysv4.opt
+++ b/gcc/config/rs6000/sysv4.opt
@@ -49,12 +49,12 @@ Target Report Var(TARGET_NO_BITFIELD_TYPE) Save
Align to the base type of the bit-field
mstrict-align
-Target Report Mask(STRICT_ALIGN)
+Target Report Mask(STRICT_ALIGN) Var(rs6000_isa_flags)
Align to the base type of the bit-field
Don't assume that unaligned accesses are handled by the system
mrelocatable
-Target Report Mask(RELOCATABLE)
+Target Report Mask(RELOCATABLE) Var(rs6000_isa_flags)
Produce code relocatable at runtime
mrelocatable-lib
@@ -62,19 +62,19 @@ Target
Produce code relocatable at runtime
mlittle-endian
-Target Report RejectNegative Mask(LITTLE_ENDIAN)
+Target Report RejectNegative Mask(LITTLE_ENDIAN) Var(rs6000_isa_flags)
Produce little endian code
mlittle
-Target Report RejectNegative Mask(LITTLE_ENDIAN)
+Target Report RejectNegative Mask(LITTLE_ENDIAN) Var(rs6000_isa_flags)
Produce little endian code
mbig-endian
-Target Report RejectNegative InverseMask(LITTLE_ENDIAN)
+Target Report RejectNegative InverseMask(LITTLE_ENDIAN) Var(rs6000_isa_flags)
Produce big endian code
mbig
-Target Report RejectNegative InverseMask(LITTLE_ENDIAN)
+Target Report RejectNegative InverseMask(LITTLE_ENDIAN) Var(rs6000_isa_flags)
Produce big endian code
;; FIXME: This does nothing. What should be done?
@@ -96,7 +96,7 @@ Target RejectNegative
no description yet
meabi
-Target Report Mask(EABI)
+Target Report Mask(EABI) Var(rs6000_isa_flags)
Use EABI
mbit-word
@@ -138,11 +138,11 @@ Target RejectNegative
no description yet
m64
-Target Report RejectNegative Negative(m32) Mask(64BIT)
+Target Report RejectNegative Negative(m32) Mask(64BIT) Var(rs6000_isa_flags)
Generate 64-bit code
m32
-Target Report RejectNegative Negative(m64) InverseMask(64BIT)
+Target Report RejectNegative Negative(m64) InverseMask(64BIT) Var(rs6000_isa_flags)
Generate 32-bit code
mnewlib
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index a96c0d2a7..6135f52ae 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -26,7 +26,8 @@ rs6000.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \
output.h dbxout.h $(BASIC_BLOCK_H) toplev.h $(GGC_H) $(HASHTAB_H) \
$(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h \
- cfgloop.h $(OPTS_H) $(COMMON_TARGET_H) dumpfile.h
+ cfgloop.h $(OPTS_H) $(COMMON_TARGET_H) dumpfile.h \
+ $(srcdir)/config/rs6000/rs6000-cpus.def
rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
$(srcdir)/config/rs6000/rs6000-protos.h \
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index efe1a470e..9279a9876 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8166,7 +8166,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
- (use (match_operand 4 "" ""))] ; label
+ (use (match_operand 4 "" "")) ; label
+ (use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
""
{
if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
diff --git a/gcc/config/sh/iterators.md b/gcc/config/sh/iterators.md
index ec95013b2..e118c3ef1 100644
--- a/gcc/config/sh/iterators.md
+++ b/gcc/config/sh/iterators.md
@@ -18,6 +18,7 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
+(define_mode_iterator QIHISIDI [QI HI SI DI])
(define_mode_iterator QIHISI [QI HI SI])
(define_mode_iterator QIHI [QI HI])
(define_mode_iterator HISI [HI SI])
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index cd9805560..83508e895 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -1139,3 +1139,20 @@
return INTVAL (op) >= 0 && INTVAL (op) <= max_disp;
})
+
+;; A predicate that determines whether OP is a valid GBR addressing mode
+;; memory reference.
+(define_predicate "gbr_address_mem"
+ (match_code "mem")
+{
+ rtx addr = XEXP (op, 0);
+
+ if (REG_P (addr) && REGNO (addr) == GBR_REG)
+ return true;
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 0)) && REGNO (XEXP (addr, 0)) == GBR_REG
+ && gbr_displacement (XEXP (addr, 1), mode))
+ return true;
+
+ return false;
+})
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index f3c037cb6..d4e97db89 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -163,6 +163,25 @@ extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
enum machine_mode mode = VOIDmode);
extern rtx sh_find_equiv_gbr_addr (rtx cur_insn, rtx mem);
extern int sh_eval_treg_value (rtx op);
+
+/* Result value of sh_find_set_of_reg. */
+struct set_of_reg
+{
+ /* The insn where sh_find_set_of_reg stopped looking.
+ Can be NULL_RTX if the end of the insn list was reached. */
+ rtx insn;
+
+ /* The set rtx of the specified reg if found, NULL_RTX otherwise. */
+ const_rtx set_rtx;
+
+ /* The set source rtx of the specified reg if found, NULL_RTX otherwise.
+ Usually, this is the most interesting return value. */
+ rtx set_src;
+};
+
+extern set_of_reg sh_find_set_of_reg (rtx reg, rtx insn, rtx(*stepfunc)(rtx));
+extern bool sh_is_logical_t_store_expr (rtx op, rtx insn);
+extern rtx sh_try_omit_signzero_extend (rtx extended_op, rtx insn);
#endif /* RTX_CODE */
extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index b61735117..4d65685a8 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -9451,30 +9451,42 @@ sh_insert_attributes (tree node, tree *attributes)
return;
}
-/* Supported attributes:
+/*------------------------------------------------------------------------------
+ Target specific attributes
+ Supported attributes are:
+
+ * interrupt_handler
+ Specifies this function is an interrupt handler.
- interrupt_handler -- specifies this function is an interrupt handler.
+ * trapa_handler
+ Like interrupt_handler, but don't save all registers.
- trapa_handler - like above, but don't save all registers.
+ * sp_switch
+ Specifies an alternate stack for an interrupt handler to run on.
- sp_switch -- specifies an alternate stack for an interrupt handler
- to run on.
+ * trap_exit
+ Use a trapa to exit an interrupt function instead of rte.
- trap_exit -- use a trapa to exit an interrupt function instead of
- an rte instruction.
+ * nosave_low_regs
+ Don't save r0..r7 in an interrupt handler function.
+ This is useful on SH3* and SH4*, which have a separate set of low
+ regs for user and privileged modes.
+ This is mainly to be used for non-reentrant interrupt handlers (i.e.
+ those that run with interrupts disabled and thus can't be
+ interrupted thenselves).
- nosave_low_regs - don't save r0..r7 in an interrupt handler.
- This is useful on the SH3 and upwards,
- which has a separate set of low regs for User and Supervisor modes.
- This should only be used for the lowest level of interrupts. Higher levels
- of interrupts must save the registers in case they themselves are
- interrupted.
+ * renesas
+ Use Renesas calling/layout conventions (functions and structures).
- renesas -- use Renesas calling/layout conventions (functions and
- structures).
+ * resbank
+ In case of an interrupt handler function, use a register bank to
+ save registers R0-R14, MACH, MACL, GBR and PR.
+ This is available only on SH2A targets.
- resbank -- In case of an ISR, use a register bank to save registers
- R0-R14, MACH, MACL, GBR and PR. This is useful only on SH2A targets.
+ * function_vector
+ Declares a function to be called using the TBR relative addressing
+ mode. Takes an argument that specifies the slot number in the table
+ where this function can be looked up by the JSR/N @@(disp8,TBR) insn.
*/
/* Handle a 'resbank' attribute. */
@@ -10799,13 +10811,8 @@ sh_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED, rtx dep_insn, int cost)
function's address. */
if (CALL_P (insn))
{
- rtx call = PATTERN (insn);
-
- if (GET_CODE (call) == PARALLEL)
- call = XVECEXP (call, 0 ,0);
- if (GET_CODE (call) == SET)
- call = SET_SRC (call);
- if (GET_CODE (call) == CALL && MEM_P (XEXP (call, 0))
+ rtx call = get_call_rtx_from (insn);
+ if (call
/* sibcalli_thunk uses a symbol_ref in an unspec. */
&& (GET_CODE (XEXP (XEXP (call, 0), 0)) == UNSPEC
|| ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn)))
@@ -13383,6 +13390,10 @@ sh_find_base_reg_disp (rtx insn, rtx x, disp_t disp = 0, rtx base_reg = NULL)
for (rtx i = prev_nonnote_insn (insn); i != NULL;
i = prev_nonnote_insn (i))
{
+ if (REGNO_REG_SET_P (regs_invalidated_by_call_regset, GBR_REG)
+ && CALL_P (i))
+ break;
+
if (!NONJUMP_INSN_P (i))
continue;
@@ -13450,4 +13461,114 @@ sh_find_equiv_gbr_addr (rtx insn, rtx mem)
return NULL_RTX;
}
+/*------------------------------------------------------------------------------
+ Manual insn combine support code.
+*/
+
+/* Given a reg rtx and a start insn, try to find the insn that sets the
+ specified reg by using the specified insn stepping function, such as
+ 'prev_nonnote_insn_bb'. When the insn is found, try to extract the rtx
+ of the reg set. */
+set_of_reg
+sh_find_set_of_reg (rtx reg, rtx insn, rtx(*stepfunc)(rtx))
+{
+ set_of_reg result;
+ result.insn = insn;
+ result.set_rtx = NULL_RTX;
+ result.set_src = NULL_RTX;
+
+ if (!REG_P (reg) || insn == NULL_RTX)
+ return result;
+
+ for (result.insn = stepfunc (insn); result.insn != NULL_RTX;
+ result.insn = stepfunc (result.insn))
+ {
+ if (LABEL_P (result.insn) || BARRIER_P (result.insn))
+ return result;
+ if (!NONJUMP_INSN_P (result.insn))
+ continue;
+ if (reg_set_p (reg, result.insn))
+ {
+ result.set_rtx = set_of (reg, result.insn);
+
+ if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
+ return result;
+
+ result.set_src = XEXP (result.set_rtx, 1);
+ return result;
+ }
+ }
+
+ return result;
+}
+
+/* Given an op rtx and an insn, try to find out whether the result of the
+ specified op consists only of logical operations on T bit stores. */
+bool
+sh_is_logical_t_store_expr (rtx op, rtx insn)
+{
+ if (!logical_operator (op, SImode))
+ return false;
+
+ rtx ops[2] = { XEXP (op, 0), XEXP (op, 1) };
+ int op_is_t_count = 0;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (t_reg_operand (ops[i], VOIDmode)
+ || negt_reg_operand (ops[i], VOIDmode))
+ op_is_t_count++;
+
+ else
+ {
+ set_of_reg op_set = sh_find_set_of_reg (ops[i], insn,
+ prev_nonnote_insn_bb);
+ if (op_set.set_src == NULL_RTX)
+ continue;
+
+ if (t_reg_operand (op_set.set_src, VOIDmode)
+ || negt_reg_operand (op_set.set_src, VOIDmode)
+ || sh_is_logical_t_store_expr (op_set.set_src, op_set.insn))
+ op_is_t_count++;
+ }
+ }
+
+ return op_is_t_count == 2;
+}
+
+/* Given the operand that is extended in a sign/zero extend insn, and the
+ insn, try to figure out whether the sign/zero extension can be replaced
+ by a simple reg-reg copy. If so, the replacement reg rtx is returned,
+ NULL_RTX otherwise. */
+rtx
+sh_try_omit_signzero_extend (rtx extended_op, rtx insn)
+{
+ if (REG_P (extended_op))
+ extended_op = extended_op;
+ else if (GET_CODE (extended_op) == SUBREG && REG_P (SUBREG_REG (extended_op)))
+ extended_op = SUBREG_REG (extended_op);
+ else
+ return NULL_RTX;
+
+ /* Reg moves must be of the same mode. */
+ if (GET_MODE (extended_op) != SImode)
+ return NULL_RTX;
+
+ set_of_reg s = sh_find_set_of_reg (extended_op, insn, prev_nonnote_insn_bb);
+ if (s.set_src == NULL_RTX)
+ return NULL_RTX;
+
+ if (t_reg_operand (s.set_src, VOIDmode)
+ || negt_reg_operand (s.set_src, VOIDmode))
+ return extended_op;
+
+ /* If the zero extended reg was formed by a logical operation, check the
+ operands of the logical operation. If both originated from T bit
+ stores the zero extension can be eliminated. */
+ else if (sh_is_logical_t_store_expr (s.set_src, s.insn))
+ return extended_op;
+
+ return NULL_RTX;
+}
+
#include "gt-sh.h"
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 1b6c284e3..2ef4a1a4e 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3708,6 +3708,26 @@ label:
"xor %2,%0"
[(set_attr "type" "arith")])
+;; The *logical_op_t pattern helps combine eliminating sign/zero extensions
+;; of results where one of the inputs is a T bit store. Notice that this
+;; pattern must not match during reload. If reload picks this pattern it
+;; will be impossible to split it afterwards.
+(define_insn_and_split "*logical_op_t"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (match_operator:SI 3 "logical_operator"
+ [(match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "t_reg_operand")]))]
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 4) (reg:SI T_REG))
+ (set (match_dup 0) (match_dup 3))]
+{
+ operands[4] = gen_reg_rtx (SImode);
+ operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
+ operands[1], operands[4]);
+})
+
(define_insn "*xorsi3_media"
[(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
(xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
@@ -5590,39 +5610,7 @@ label:
eliminated. Notice that this also helps the *cbranch_t splitter when
it tries to post-combine tests and conditional branches, as it does not
check for zero extensions. */
- rtx ext_reg;
- if (REG_P (operands[1]))
- ext_reg = operands[1];
- else if (GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1])))
- ext_reg = SUBREG_REG (operands[1]);
- else
- FAIL;
-
- /* Reg moves must be of the same mode. */
- if (GET_MODE (ext_reg) != SImode)
- FAIL;
-
- operands[2] = NULL_RTX;
- for (rtx i = prev_nonnote_insn_bb (curr_insn); i != NULL_RTX;
- i = prev_nonnote_insn_bb (i))
- {
- if (LABEL_P (i) || BARRIER_P (i))
- break;
- if (!NONJUMP_INSN_P (i))
- continue;
-
- if (reg_set_p (ext_reg, i))
- {
- rtx set_op = XEXP (set_of (ext_reg, i), 1);
- if (set_op == NULL_RTX)
- break;
- if (t_reg_operand (set_op, VOIDmode)
- || negt_reg_operand (set_op, VOIDmode))
- operands[2] = ext_reg;
- break;
- }
- }
-
+ operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
if (operands[2] == NULL_RTX)
FAIL;
}
@@ -5850,11 +5838,23 @@ label:
subreg_lowpart_offset (SImode, GET_MODE (op1)));
})
-(define_insn "*extend<mode>si2_compact_reg"
+(define_insn_and_split "*extend<mode>si2_compact_reg"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"exts.<bw> %1,%0"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 0) (match_dup 2))]
+{
+ /* Sometimes combine fails to combine a T bit or negated T bit store to a
+ reg with a following sign extension. In the split pass after combine,
+ try to figure the extended reg was set. If it originated from the T
+ bit we can replace the sign extension with a reg move, which will be
+ eliminated. */
+ operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
+ if (operands[2] == NULL_RTX)
+ FAIL;
+}
[(set_attr "type" "arith")])
;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
@@ -6629,10 +6629,19 @@ label:
;; picked to load/store regs. If the regs regs are on the stack reload will
;; try other insns and not stick to movqi_reg_reg.
;; The same applies to the movhi variants.
+;;
+;; Notice, that T bit is not allowed as a mov src operand here. This is to
+;; avoid things like (set (reg:QI) (subreg:QI (reg:SI T_REG) 0)), which
+;; introduces zero extensions after T bit stores and redundant reg copies.
+;;
+;; FIXME: We can't use 'arith_reg_operand' (which disallows T_REG) as a
+;; predicate for the mov src operand because reload will have trouble
+;; reloading MAC subregs otherwise. For that probably special patterns
+;; would be required.
(define_insn "*mov<mode>_reg_reg"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=r")
(match_operand:QIHI 1 "register_operand" "r"))]
- "TARGET_SH1"
+ "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
"mov %1,%0"
[(set_attr "type" "move")])
@@ -8178,28 +8187,17 @@ label:
rtx testing_insn = NULL_RTX;
rtx tested_reg = NULL_RTX;
- for (rtx i = prev_nonnote_insn_bb (curr_insn); i != NULL_RTX;
- i = prev_nonnote_insn_bb (i))
+ set_of_reg s0 = sh_find_set_of_reg (get_t_reg_rtx (), curr_insn,
+ prev_nonnote_insn_bb);
+ if (s0.set_src != NULL_RTX
+ && GET_CODE (s0.set_src) == EQ
+ && REG_P (XEXP (s0.set_src, 0))
+ && satisfies_constraint_Z (XEXP (s0.set_src, 1)))
{
- if (LABEL_P (i) || BARRIER_P (i))
- break;
- if (!NONJUMP_INSN_P (i))
- continue;
-
- rtx p = PATTERN (i);
- if (p != NULL_RTX
- && GET_CODE (p) == SET && t_reg_operand (XEXP (p, 0), VOIDmode)
- && GET_CODE (XEXP (p, 1)) == EQ
- && REG_P (XEXP (XEXP (p, 1), 0))
- && satisfies_constraint_Z (XEXP (XEXP (p, 1), 1)))
- {
- testing_insn = i;
- tested_reg = XEXP (XEXP (p, 1), 0);
- break;
- }
+ testing_insn = s0.insn;
+ tested_reg = XEXP (s0.set_src, 0);
}
-
- if (testing_insn == NULL_RTX)
+ else
FAIL;
/* Continue scanning the insns backwards and try to find the insn that
@@ -8213,47 +8211,37 @@ label:
if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
FAIL;
- for (rtx i = prev_nonnote_insn_bb (testing_insn); i != NULL_RTX;
- i = prev_nonnote_insn_bb (i))
+ while (true)
{
- if (LABEL_P (i) || BARRIER_P (i))
+ set_of_reg s1 = sh_find_set_of_reg (tested_reg, s0.insn,
+ prev_nonnote_insn_bb);
+ if (s1.set_src == NULL_RTX)
break;
- if (!NONJUMP_INSN_P (i))
- continue;
- if (reg_set_p (tested_reg, i))
+ if (t_reg_operand (s1.set_src, VOIDmode))
+ operands[2] = GEN_INT (treg_value ^ 1);
+ else if (negt_reg_operand (s1.set_src, VOIDmode))
+ operands[2] = GEN_INT (treg_value);
+ else if (REG_P (s1.set_src))
{
- const_rtx tested_reg_set = set_of (tested_reg, i);
-
- /* It could also be a clobber... */
- if (tested_reg_set == NULL_RTX || GET_CODE (tested_reg_set) != SET)
- break;
-
- rtx set_op1 = XEXP (tested_reg_set, 1);
- if (t_reg_operand (set_op1, VOIDmode))
- operands[2] = GEN_INT (treg_value ^ 1);
- else if (negt_reg_operand (set_op1, VOIDmode))
- operands[2] = GEN_INT (treg_value);
- else if (REG_P (set_op1))
- {
- /* If it's a reg-reg copy follow the copied reg. This can
- happen e.g. when T bit store zero-extensions are
- eliminated. */
- tested_reg = set_op1;
- continue;
- }
+ /* If it's a reg-reg copy follow the copied reg. This can
+ happen e.g. when T bit store zero-extensions are
+ eliminated. */
+ tested_reg = s1.set_src;
+ s0.insn = s1.insn;
+ continue;
+ }
- /* It's only safe to remove the testing insn if the T bit is not
- modified between the testing insn and the insn that stores the
- T bit. Notice that some T bit stores such as negc also modify
- the T bit. */
- if (modified_between_p (get_t_reg_rtx (), i, testing_insn)
- || modified_in_p (get_t_reg_rtx (), i))
- operands[2] = NULL_RTX;
+ /* It's only safe to remove the testing insn if the T bit is not
+ modified between the testing insn and the insn that stores the
+ T bit. Notice that some T bit stores such as negc also modify
+ the T bit. */
+ if (modified_between_p (get_t_reg_rtx (), s1.insn, testing_insn)
+ || modified_in_p (get_t_reg_rtx (), s1.insn))
+ operands[2] = NULL_RTX;
- break;
- }
- }
+ break;
+ }
if (operands[2] == NULL_RTX)
FAIL;
@@ -8486,11 +8474,14 @@ label:
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))
- (clobber (reg:SI T_REG))])]
+ (clobber (reg:SI T_REG))])
+ (match_operand 5 "" "")]
"TARGET_SH2"
{
if (GET_MODE (operands[0]) != SImode)
FAIL;
+ emit_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
+ DONE;
})
(define_insn_and_split "doloop_end_split"
@@ -10277,6 +10268,47 @@ label:
"mov.<bwl> %0,@(0,gbr)"
[(set_attr "type" "store")])
+;; DImode memory accesses have to be split in two SImode accesses.
+;; Split them before reload, so that it gets a better chance to figure out
+;; how to deal with the R0 restriction for the individual SImode accesses.
+;; Do not match this insn during or after reload because it can't be split
+;; afterwards.
+(define_insn_and_split "*movdi_gbr_load"
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "gbr_address_mem"))]
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 3) (match_dup 5))
+ (set (match_dup 4) (match_dup 6))]
+{
+ /* Swap low/high part load order on little endian, so that the result reg
+ of the second load can be used better. */
+ int off = TARGET_LITTLE_ENDIAN ? 1 : 0;
+ operands[3 + off] = gen_lowpart (SImode, operands[0]);
+ operands[5 + off] = gen_lowpart (SImode, operands[1]);
+ operands[4 - off] = gen_highpart (SImode, operands[0]);
+ operands[6 - off] = gen_highpart (SImode, operands[1]);
+})
+
+(define_insn_and_split "*movdi_gbr_store"
+ [(set (match_operand:DI 0 "gbr_address_mem")
+ (match_operand:DI 1 "register_operand"))]
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 3) (match_dup 5))
+ (set (match_dup 4) (match_dup 6))]
+{
+ /* Swap low/high part store order on big endian, so that stores of function
+ call results can save a reg copy. */
+ int off = TARGET_LITTLE_ENDIAN ? 0 : 1;
+ operands[3 + off] = gen_lowpart (SImode, operands[0]);
+ operands[5 + off] = gen_lowpart (SImode, operands[1]);
+ operands[4 - off] = gen_highpart (SImode, operands[0]);
+ operands[6 - off] = gen_highpart (SImode, operands[1]);
+})
+
;; Sometimes memory accesses do not get combined with the store_gbr insn,
;; in particular when the displacements are in the range of the regular move
;; insns. Thus, in the first split pass after the combine pass we search
@@ -10287,15 +10319,15 @@ label:
;; other operand) and there's no point of doing it if the GBR is not
;; referenced in a function at all.
(define_split
- [(set (match_operand:QIHISI 0 "register_operand")
- (match_operand:QIHISI 1 "memory_operand"))]
+ [(set (match_operand:QIHISIDI 0 "register_operand")
+ (match_operand:QIHISIDI 1 "memory_operand"))]
"TARGET_SH1 && !reload_in_progress && !reload_completed
&& df_regs_ever_live_p (GBR_REG)"
[(set (match_dup 0) (match_dup 1))]
{
rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
if (gbr_mem != NULL_RTX)
- operands[1] = change_address (operands[1], GET_MODE (operands[1]), gbr_mem);
+ operands[1] = replace_equiv_address (operands[1], gbr_mem);
else
FAIL;
})
@@ -10309,7 +10341,7 @@ label:
{
rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[1]);
if (gbr_mem != NULL_RTX)
- operands[1] = change_address (operands[1], GET_MODE (operands[1]), gbr_mem);
+ operands[1] = replace_equiv_address (operands[1], gbr_mem);
else
FAIL;
})
@@ -10328,23 +10360,22 @@ label:
if (gbr_mem != NULL_RTX)
{
operands[2] = gen_reg_rtx (GET_MODE (operands[1]));
- operands[1] = change_address (operands[1], GET_MODE (operands[1]),
- gbr_mem);
+ operands[1] = replace_equiv_address (operands[1], gbr_mem);
}
else
FAIL;
})
(define_split
- [(set (match_operand:QIHISI 0 "memory_operand")
- (match_operand:QIHISI 1 "register_operand"))]
+ [(set (match_operand:QIHISIDI 0 "memory_operand")
+ (match_operand:QIHISIDI 1 "register_operand"))]
"TARGET_SH1 && !reload_in_progress && !reload_completed
&& df_regs_ever_live_p (GBR_REG)"
[(set (match_dup 0) (match_dup 1))]
{
rtx gbr_mem = sh_find_equiv_gbr_addr (curr_insn, operands[0]);
if (gbr_mem != NULL_RTX)
- operands[0] = change_address (operands[0], GET_MODE (operands[0]), gbr_mem);
+ operands[0] = replace_equiv_address (operands[0], gbr_mem);
else
FAIL;
})
diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md
index ee5fced66..3446e986f 100644
--- a/gcc/config/spu/spu.md
+++ b/gcc/config/spu/spu.md
@@ -4490,7 +4490,8 @@ selb\t%0,%4,%0,%3"
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
- (use (match_operand 4 "" ""))] ; label
+ (use (match_operand 4 "" "")) ; label
+ (match_operand 5 "" "")]
""
"
{
diff --git a/gcc/config/tilegx/tilegx.md b/gcc/config/tilegx/tilegx.md
index 92a6d651e..b5dc9c884 100644
--- a/gcc/config/tilegx/tilegx.md
+++ b/gcc/config/tilegx/tilegx.md
@@ -2316,7 +2316,8 @@
(use (match_operand 1 "" "")) ;; iterations; zero if unknown
(use (match_operand 2 "" "")) ;; max iterations
(use (match_operand 3 "" "")) ;; loop level
- (use (match_operand 4 "" ""))] ;; label
+ (use (match_operand 4 "" "")) ;; label
+ (use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
""
{
if (optimize > 0 && flag_modulo_sched)
diff --git a/gcc/config/tilepro/tilepro.md b/gcc/config/tilepro/tilepro.md
index 9d5d44e85..1d1838e6d 100644
--- a/gcc/config/tilepro/tilepro.md
+++ b/gcc/config/tilepro/tilepro.md
@@ -1322,7 +1322,8 @@
(use (match_operand 1 "" "")) ;; iterations; zero if unknown
(use (match_operand 2 "" "")) ;; max iterations
(use (match_operand 3 "" "")) ;; loop level
- (use (match_operand 4 "" ""))] ;; label
+ (use (match_operand 4 "" "")) ;; label
+ (use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
""
{
if (optimize > 0)
diff --git a/gcc/configure b/gcc/configure
index bef4ea36a..4c90e9b79 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -26283,7 +26283,9 @@ if test "${gcc_cv_ld_no_dot_syms+set}" = set; then :
$as_echo_n "(cached) " >&6
else
gcc_cv_ld_no_dot_syms=no
- if test $in_tree_ld = yes ; then
+ if test x"$ld_is_gold" = xyes; then
+ gcc_cv_ld_no_dot_syms=yes
+ elif test $in_tree_ld = yes ; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2; then
gcc_cv_ld_no_dot_syms=yes
fi
@@ -26327,7 +26329,9 @@ if test "${gcc_cv_ld_large_toc+set}" = set; then :
$as_echo_n "(cached) " >&6
else
gcc_cv_ld_large_toc=no
- if test $in_tree_ld = yes ; then
+ if test x"$ld_is_gold" = xyes; then
+ gcc_cv_ld_large_toc=yes
+ elif test $in_tree_ld = yes ; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then
gcc_cv_ld_large_toc=yes
fi
diff --git a/gcc/configure.ac b/gcc/configure.ac
index dee70dc20..f629d1561 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4407,7 +4407,9 @@ case "$target:$tm_file" in
AC_CACHE_CHECK(linker support for omitting dot symbols,
gcc_cv_ld_no_dot_syms,
[gcc_cv_ld_no_dot_syms=no
- if test $in_tree_ld = yes ; then
+ if test x"$ld_is_gold" = xyes; then
+ gcc_cv_ld_no_dot_syms=yes
+ elif test $in_tree_ld = yes ; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2; then
gcc_cv_ld_no_dot_syms=yes
fi
@@ -4444,7 +4446,9 @@ EOF
AC_CACHE_CHECK(linker large toc support,
gcc_cv_ld_large_toc,
[gcc_cv_ld_large_toc=no
- if test $in_tree_ld = yes ; then
+ if test x"$ld_is_gold" = xyes; then
+ gcc_cv_ld_large_toc=yes
+ elif test $in_tree_ld = yes ; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then
gcc_cv_ld_large_toc=yes
fi
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 27f0d55ac..73ab5a9b0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,58 @@
+2012-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54501
+ * decl.c (reshape_init_array_1): Avoid infinite loops.
+
+2012-10-15 Alexandre Oliva <aoliva@redhat.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/17805
+ * call.c (build_new_op_1): Filter out operator functions that don't
+ satisfy enum-conversion match requirements.
+
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080 (again)
+ * parser.c (cp_parser_optional_template_keyword): When -pedantic
+ and C++98 mode restore pre-Core/468 behavior.
+
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080
+ * parser.c (cp_parser_optional_template_keyword): Implement
+ Core/468, allow outside template.
+
+2012-10-14 Jason Merrill <jason@redhat.com>
+ Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement C++11 inheriting constructors.
+ * cp-tree.h (cpp0x_warn_str): Add CPP0X_INHERITING_CTORS.
+ (DECL_INHERITED_CTOR_BASE, SET_DECL_INHERITED_CTOR_BASE): New.
+ (special_function_kind): Add sfk_inheriting_constructor.
+ * class.c (add_method): An inheriting ctor is hidden by a
+ user-declared one.
+ (one_inheriting_sig, one_inherited_ctor): New.
+ (add_implicitly_declared_members): Handle inheriting ctors.
+ * error.c (maybe_warn_cpp0x): Handle CPP0X_INHERITING_CTORS.
+ * init.c (emit_mem_initializers): Don't set LOOKUP_DEFAULTED
+ for an inheriting constructor.
+ * method.c (type_has_trivial_fn): Handle sfk_inheriting_constructor.
+ (type_set_nontrivial_flag): Likewise.
+ (add_one_base_init): Split out from...
+ (do_build_copy_constructor): ...here. Handle inheriting constructors.
+ (locate_fn_flags): Handle a list of arg types.
+ (synthesized_method_walk): Handle inheriting constructors.
+ (maybe_explain_implicit_delete): Likewise.
+ (deduce_inheriting_ctor): New.
+ (implicitly_declare_fn): Handle inheriting constructors.
+ * name-lookup.c (push_class_level_binding_1): An inheriting constructor
+ does not declare the base's name.
+ (do_class_using_decl): Allow inheriting constructors.
+ * pt.c (template_parms_to_args): Split from current_template_args.
+ (add_inherited_template_parms): New.
+ (tsubst_decl): Handle inheriting constructors.
+ * tree.c (special_function_p): Handle inheriting constructors.
+
2012-10-12 Jakub Jelinek <jakub@redhat.com>
PR c/54381
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c94bbbe3c..e21049b8e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5043,6 +5043,11 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
NULL_TREE, arglist, NULL_TREE,
NULL_TREE, false, NULL_TREE, NULL_TREE,
flags, &candidates, complain);
+
+ args[0] = arg1;
+ args[1] = arg2;
+ args[2] = NULL_TREE;
+
/* Add class-member operators to the candidate set. */
if (CLASS_TYPE_P (TREE_TYPE (arg1)))
{
@@ -5062,10 +5067,49 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
BASELINK_ACCESS_BINFO (fns),
flags, &candidates, complain);
}
+ /* Per 13.3.1.2/3, 2nd bullet, if no operand has a class type, then
+ only non-member functions that have type T1 or reference to
+ cv-qualified-opt T1 for the first argument, if the first argument
+ has an enumeration type, or T2 or reference to cv-qualified-opt
+ T2 for the second argument, if the the second argument has an
+ enumeration type. Filter out those that don't match. */
+ else if (! arg2 || ! CLASS_TYPE_P (TREE_TYPE (arg2)))
+ {
+ struct z_candidate **candp, **next;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = NULL_TREE;
+ for (candp = &candidates; *candp; candp = next)
+ {
+ tree parmlist, parmtype;
+ int i, nargs = (arg2 ? 2 : 1);
+
+ cand = *candp;
+ next = &cand->next;
+
+ parmlist = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+
+ for (i = 0; i < nargs; ++i)
+ {
+ parmtype = TREE_VALUE (parmlist);
+
+ if (TREE_CODE (parmtype) == REFERENCE_TYPE)
+ parmtype = TREE_TYPE (parmtype);
+ if (TREE_CODE (TREE_TYPE (args[i])) == ENUMERAL_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (args[i]), parmtype)))
+ break;
+
+ parmlist = TREE_CHAIN (parmlist);
+ }
+
+ /* No argument has an appropriate type, so remove this
+ candidate function from the list. */
+ if (i == nargs)
+ {
+ *candp = cand->next;
+ next = candp;
+ }
+ }
+ }
add_builtin_candidates (&candidates, code, code2, fnname, args,
flags, complain);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0e77b81c8..a478de805 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -132,7 +132,7 @@ static void finish_struct_methods (tree);
static void maybe_warn_about_overly_private_class (tree);
static int method_name_cmp (const void *, const void *);
static int resort_method_name_cmp (const void *, const void *);
-static void add_implicitly_declared_members (tree, int, int);
+static void add_implicitly_declared_members (tree, tree*, int, int);
static tree fixed_type_or_null (tree, int *, int *);
static tree build_simple_base_path (tree expr, tree binfo);
static tree build_vtbl_ref_1 (tree, tree);
@@ -1087,6 +1087,20 @@ add_method (tree type, tree method, tree using_decl)
|| same_type_p (TREE_TYPE (fn_type),
TREE_TYPE (method_type))))
{
+ if (DECL_INHERITED_CTOR_BASE (method))
+ {
+ if (DECL_INHERITED_CTOR_BASE (fn))
+ {
+ error_at (DECL_SOURCE_LOCATION (method),
+ "%q#D inherited from %qT", method,
+ DECL_INHERITED_CTOR_BASE (method));
+ error_at (DECL_SOURCE_LOCATION (fn),
+ "conflicts with version inherited from %qT",
+ DECL_INHERITED_CTOR_BASE (fn));
+ }
+ /* Otherwise defer to the other function. */
+ return false;
+ }
if (using_decl)
{
if (DECL_CONTEXT (fn) == type)
@@ -2750,6 +2764,51 @@ declare_virt_assop_and_dtor (tree t)
NULL, t);
}
+/* Declare the inheriting constructor for class T inherited from base
+ constructor CTOR with the parameter array PARMS of size NPARMS. */
+
+static void
+one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
+{
+ /* We don't declare an inheriting ctor that would be a default,
+ copy or move ctor. */
+ if (nparms == 0
+ || (nparms == 1
+ && TREE_CODE (parms[0]) == REFERENCE_TYPE
+ && TYPE_MAIN_VARIANT (TREE_TYPE (parms[0])) == t))
+ return;
+ int i;
+ tree parmlist = void_list_node;
+ for (i = nparms - 1; i >= 0; i--)
+ parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
+ tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
+ t, false, ctor, parmlist);
+ if (add_method (t, fn, NULL_TREE))
+ {
+ DECL_CHAIN (fn) = TYPE_METHODS (t);
+ TYPE_METHODS (t) = fn;
+ }
+}
+
+/* Declare all the inheriting constructors for class T inherited from base
+ constructor CTOR. */
+
+static void
+one_inherited_ctor (tree ctor, tree t)
+{
+ tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor);
+
+ tree *new_parms = XALLOCAVEC (tree, list_length (parms));
+ int i = 0;
+ for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
+ {
+ if (TREE_PURPOSE (parms))
+ one_inheriting_sig (t, ctor, new_parms, i);
+ new_parms[i++] = TREE_VALUE (parms);
+ }
+ one_inheriting_sig (t, ctor, new_parms, i);
+}
+
/* Create default constructors, assignment operators, and so forth for
the type indicated by T, if they are needed. CANT_HAVE_CONST_CTOR,
and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
@@ -2758,7 +2817,7 @@ declare_virt_assop_and_dtor (tree t)
a const reference, respectively. */
static void
-add_implicitly_declared_members (tree t,
+add_implicitly_declared_members (tree t, tree* access_decls,
int cant_have_const_cctor,
int cant_have_const_assignment)
{
@@ -2826,6 +2885,26 @@ add_implicitly_declared_members (tree t,
/* We can't be lazy about declaring functions that might override
a virtual function from a base class. */
declare_virt_assop_and_dtor (t);
+
+ while (*access_decls)
+ {
+ tree using_decl = TREE_VALUE (*access_decls);
+ tree decl = USING_DECL_DECLS (using_decl);
+ if (DECL_SELF_REFERENCE_P (decl))
+ {
+ /* declare, then remove the decl */
+ tree ctor_list = CLASSTYPE_CONSTRUCTORS (TREE_TYPE (decl));
+ location_t loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (using_decl);
+ if (ctor_list)
+ for (; ctor_list; ctor_list = OVL_NEXT (ctor_list))
+ one_inherited_ctor (OVL_CURRENT (ctor_list), t);
+ *access_decls = TREE_CHAIN (*access_decls);
+ input_location = loc;
+ }
+ else
+ access_decls = &TREE_CHAIN (*access_decls);
+ }
}
/* Subroutine of insert_into_classtype_sorted_fields. Recursively
@@ -4342,7 +4421,8 @@ deduce_noexcept_on_destructor (tree dtor)
{
tree ctx = DECL_CONTEXT (dtor);
tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
- /*const_p=*/false);
+ /*const_p=*/false,
+ NULL, NULL);
tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec);
}
@@ -5135,14 +5215,14 @@ check_bases_and_members (tree t)
}
/* Synthesize any needed methods. */
- add_implicitly_declared_members (t,
+ add_implicitly_declared_members (t, &access_decls,
cant_have_const_ctor,
no_const_asn_ref);
/* Check defaulted declarations here so we have cant_have_const_ctor
and don't need to worry about clones. */
for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
- if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn))
{
int copy = copy_fn_p (fn);
if (copy > 0)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fdf122fe2..7b4277b05 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -420,6 +420,8 @@ typedef enum cpp0x_warn_str
CPP0X_USER_DEFINED_LITERALS,
/* delegating constructors */
CPP0X_DELEGATING_CTORS,
+ /* inheriting constructors */
+ CPP0X_INHERITING_CTORS,
/* C++11 attributes */
CPP0X_ATTRIBUTES
} cpp0x_warn_str;
@@ -2384,6 +2386,15 @@ struct GTY((variable_size)) lang_decl {
#define SET_DECL_THUNKS(NODE,THUNKS) \
(LANG_DECL_FN_CHECK (NODE)->context = (THUNKS))
+/* If NODE, a FUNCTION_DECL, is a C++11 inheriting constructor, then this
+ is the base it inherits from. */
+#define DECL_INHERITED_CTOR_BASE(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
+
+/* Set the inherited base. */
+#define SET_DECL_INHERITED_CTOR_BASE(NODE,INH) \
+ (LANG_DECL_FN_CHECK (NODE)->context = (INH))
+
/* Nonzero if NODE is a thunk, rather than an ordinary function. */
#define DECL_THUNK_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL \
@@ -4142,7 +4153,8 @@ typedef enum special_function_kind {
sfk_deleting_destructor, /* A destructor for complete objects that
deletes the object after it has been
destroyed. */
- sfk_conversion /* A conversion operator. */
+ sfk_conversion, /* A conversion operator. */
+ sfk_inheriting_constructor /* An inheriting constructor */
} special_function_kind;
/* The various kinds of linkage. From [basic.link],
@@ -5323,6 +5335,7 @@ extern void use_thunk (tree, bool);
extern bool trivial_fn_p (tree);
extern bool maybe_explain_implicit_delete (tree);
extern void explain_implicit_non_constexpr (tree);
+extern void deduce_inheriting_ctor (tree);
extern void synthesize_method (tree);
extern tree lazily_declare_fn (special_function_kind,
tree);
@@ -5335,7 +5348,7 @@ extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
extern tree locate_ctor (tree);
extern tree implicitly_declare_fn (special_function_kind, tree,
- bool);
+ bool, tree, tree);
/* In optimize.c */
extern bool maybe_clone_body (tree);
@@ -5370,6 +5383,7 @@ extern tree maybe_update_decl_type (tree, tree);
extern bool check_default_tmpl_args (tree, tree, bool, bool, int);
extern tree push_template_decl (tree);
extern tree push_template_decl_real (tree, bool);
+extern tree add_inherited_template_parms (tree, tree);
extern bool redeclare_class_template (tree, tree);
extern tree lookup_template_class (tree, tree, tree, tree,
int, tsubst_flags_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 468343f40..d25aa8049 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5040,6 +5040,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
++index)
{
tree elt_init;
+ constructor_elt *old_cur = d->cur;
check_array_designated_initializer (d->cur, index);
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
@@ -5050,6 +5051,10 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
size_int (index), elt_init);
if (!TREE_CONSTANT (elt_init))
TREE_CONSTANT (new_init) = false;
+
+ /* This can happen with an invalid initializer (c++/54501). */
+ if (d->cur == old_cur && !sized_array_p)
+ break;
}
return new_init;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 2934c9b10..76f939f10 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -3374,6 +3374,11 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
"delegating constructors "
"only available with -std=c++11 or -std=gnu++11");
break;
+ case CPP0X_INHERITING_CTORS:
+ pedwarn (input_location, 0,
+ "inheriting constructors "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
case CPP0X_ATTRIBUTES:
pedwarn (input_location, 0,
"c++11 attributes "
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 40d0ce325..044603887 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1036,7 +1036,8 @@ emit_mem_initializers (tree mem_inits)
return;
}
- if (DECL_DEFAULTED_FN (current_function_decl))
+ if (DECL_DEFAULTED_FN (current_function_decl)
+ && ! DECL_INHERITED_CTOR_BASE (current_function_decl))
flags |= LOOKUP_DEFAULTED;
/* Sort the mem-initializers into the order in which the
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4d44c7dd3..4da5cc9eb 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -429,6 +429,8 @@ type_has_trivial_fn (tree ctype, special_function_kind sfk)
return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
case sfk_destructor:
return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
+ case sfk_inheriting_constructor:
+ return false;
default:
gcc_unreachable ();
}
@@ -460,6 +462,7 @@ type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
case sfk_destructor:
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
return;
+ case sfk_inheriting_constructor:
default:
gcc_unreachable ();
}
@@ -478,7 +481,46 @@ trivial_fn_p (tree fn)
return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
}
-/* Generate code for default X(X&) or X(X&&) constructor. */
+/* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
+ given the parameter or parameters PARM, possibly inherited constructor
+ base INH, or move flag MOVE_P. */
+
+static tree
+add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
+ tree member_init_list)
+{
+ tree init;
+ if (inh)
+ {
+ /* An inheriting constructor only has a mem-initializer for
+ the base it inherits from. */
+ if (BINFO_TYPE (binfo) != inh)
+ return member_init_list;
+
+ tree *p = &init;
+ init = NULL_TREE;
+ for (; parm; parm = DECL_CHAIN (parm))
+ {
+ tree exp = convert_from_reference (parm);
+ if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE)
+ exp = move (exp);
+ *p = build_tree_list (NULL_TREE, exp);
+ p = &TREE_CHAIN (*p);
+ }
+ }
+ else
+ {
+ init = build_base_path (PLUS_EXPR, parm, binfo, 1,
+ tf_warning_or_error);
+ if (move_p)
+ init = move (init);
+ init = build_tree_list (NULL_TREE, init);
+ }
+ return tree_cons (binfo, init, member_init_list);
+}
+
+/* Generate code for default X(X&) or X(X&&) constructor or an inheriting
+ constructor. */
static void
do_build_copy_constructor (tree fndecl)
@@ -486,8 +528,10 @@ do_build_copy_constructor (tree fndecl)
tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
bool trivial = trivial_fn_p (fndecl);
+ tree inh = DECL_INHERITED_CTOR_BASE (fndecl);
- parm = convert_from_reference (parm);
+ if (!inh)
+ parm = convert_from_reference (parm);
if (trivial
&& is_empty_class (current_class_type))
@@ -516,14 +560,8 @@ do_build_copy_constructor (tree fndecl)
for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
VEC_iterate (tree, vbases, i, binfo); i++)
{
- init = build_base_path (PLUS_EXPR, parm, binfo, 1,
- tf_warning_or_error);
- if (move_p)
- init = move (init);
- member_init_list
- = tree_cons (binfo,
- build_tree_list (NULL_TREE, init),
- member_init_list);
+ member_init_list = add_one_base_init (binfo, parm, move_p, inh,
+ member_init_list);
}
for (binfo = TYPE_BINFO (current_class_type), i = 0;
@@ -531,15 +569,8 @@ do_build_copy_constructor (tree fndecl)
{
if (BINFO_VIRTUAL_P (base_binfo))
continue;
-
- init = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
- tf_warning_or_error);
- if (move_p)
- init = move (init);
- member_init_list
- = tree_cons (base_binfo,
- build_tree_list (NULL_TREE, init),
- member_init_list);
+ member_init_list = add_one_base_init (base_binfo, parm, move_p,
+ inh, member_init_list);
}
for (; fields; fields = DECL_CHAIN (fields))
@@ -549,6 +580,8 @@ do_build_copy_constructor (tree fndecl)
if (TREE_CODE (field) != FIELD_DECL)
continue;
+ if (inh)
+ continue;
expr_type = TREE_TYPE (field);
if (DECL_NAME (field))
@@ -833,8 +866,23 @@ locate_fn_flags (tree type, tree name, tree argtype, int flags,
args = make_tree_vector ();
if (argtype)
{
- tree arg = build_stub_object (argtype);
- VEC_quick_push (tree, args, arg);
+ if (TREE_CODE (argtype) == TREE_LIST)
+ {
+ for (tree elt = argtype; elt != void_list_node;
+ elt = TREE_CHAIN (elt))
+ {
+ tree type = TREE_VALUE (elt);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ type = cp_build_reference_type (type, /*rval*/true);
+ tree arg = build_stub_object (type);
+ VEC_safe_push (tree, gc, args, arg);
+ }
+ }
+ else
+ {
+ tree arg = build_stub_object (argtype);
+ VEC_quick_push (tree, args, arg);
+ }
}
fns = lookup_fnfields (binfo, name, 0);
@@ -1110,7 +1158,8 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
static void
synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
tree *spec_p, bool *trivial_p, bool *deleted_p,
- bool *constexpr_p, bool *no_implicit_p, bool diag)
+ bool *constexpr_p, bool *no_implicit_p, bool diag,
+ tree inherited_base, tree inherited_parms)
{
tree binfo, base_binfo, scope, fnname, rval, argtype;
bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor;
@@ -1162,6 +1211,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
case sfk_constructor:
case sfk_move_constructor:
case sfk_copy_constructor:
+ case sfk_inheriting_constructor:
ctor_p = true;
fnname = complete_ctor_identifier;
break;
@@ -1170,6 +1220,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
gcc_unreachable ();
}
+ gcc_assert ((sfk == sfk_inheriting_constructor)
+ == (inherited_base != NULL_TREE));
+
/* If that user-written default constructor would satisfy the
requirements of a constexpr constructor (7.1.5), the
implicitly-defined default constructor is constexpr. */
@@ -1181,6 +1234,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
{
case sfk_constructor:
case sfk_destructor:
+ case sfk_inheriting_constructor:
copy_arg_p = false;
break;
@@ -1231,7 +1285,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
scope = push_scope (ctype);
- flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
+ flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE;
+ if (!inherited_base)
+ flags |= LOOKUP_DEFAULTED;
complain = diag ? tf_warning_or_error : tf_none;
@@ -1252,7 +1308,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
if (copy_arg_p)
argtype = build_stub_type (basetype, quals, move_p);
+ else if (basetype == inherited_base)
+ argtype = inherited_parms;
rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
+ if (inherited_base)
+ argtype = NULL_TREE;
process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p,
constexpr_p, no_implicit_p, diag, basetype);
@@ -1405,14 +1465,16 @@ maybe_explain_implicit_delete (tree decl)
}
if (!informed)
{
- tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
+ tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
+ tree parm_type = TREE_VALUE (parms);
bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
tree scope = push_scope (ctype);
inform (0, "%q+#D is implicitly deleted because the default "
"definition would be ill-formed:", decl);
pop_scope (scope);
synthesized_method_walk (ctype, sfk, const_p,
- NULL, NULL, NULL, NULL, NULL, true);
+ NULL, NULL, NULL, NULL, NULL, true,
+ DECL_INHERITED_CTOR_BASE (decl), parms);
}
input_location = loc;
@@ -1432,7 +1494,27 @@ explain_implicit_non_constexpr (tree decl)
bool dummy;
synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
special_function_p (decl), const_p,
- NULL, NULL, NULL, &dummy, NULL, true);
+ NULL, NULL, NULL, &dummy, NULL, true,
+ NULL_TREE, NULL_TREE);
+}
+
+/* DECL is an instantiation of an inheriting constructor template. Deduce
+ the correct exception-specification and deletedness for this particular
+ specialization. */
+
+void
+deduce_inheriting_ctor (tree decl)
+{
+ gcc_assert (DECL_INHERITED_CTOR_BASE (decl));
+ tree spec;
+ bool trivial, constexpr_, deleted, no_implicit;
+ synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
+ false, &spec, &trivial, &deleted, &constexpr_,
+ &no_implicit, /*diag*/false,
+ DECL_INHERITED_CTOR_BASE (decl),
+ FUNCTION_FIRST_USER_PARMTYPE (decl));
+ DECL_DELETED_FN (decl) = deleted;
+ TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
}
/* Implicitly declare the special function indicated by KIND, as a
@@ -1442,7 +1524,9 @@ explain_implicit_non_constexpr (tree decl)
FUNCTION_DECL for the implicitly declared function. */
tree
-implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
+implicitly_declare_fn (special_function_kind kind, tree type,
+ bool const_p, tree inherited_ctor,
+ tree inherited_parms)
{
tree fn;
tree parameter_types = void_list_node;
@@ -1499,6 +1583,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
case sfk_copy_assignment:
case sfk_move_constructor:
case sfk_move_assignment:
+ case sfk_inheriting_constructor:
{
bool move_p;
if (kind == sfk_copy_assignment
@@ -1510,23 +1595,44 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
else
name = constructor_name (type);
- if (const_p)
- rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ if (kind == sfk_inheriting_constructor)
+ parameter_types = inherited_parms;
else
- rhs_parm_type = type;
- move_p = (kind == sfk_move_assignment
- || kind == sfk_move_constructor);
- rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
+ {
+ if (const_p)
+ rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ else
+ rhs_parm_type = type;
+ move_p = (kind == sfk_move_assignment
+ || kind == sfk_move_constructor);
+ rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
- parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
+ parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
+ }
break;
}
default:
gcc_unreachable ();
}
- synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
- &deleted_p, &constexpr_p, &no_implicit_p, false);
+ tree inherited_base = (inherited_ctor
+ ? DECL_CONTEXT (inherited_ctor)
+ : NULL_TREE);
+ if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ {
+ /* For an inheriting constructor template, just copy these flags from
+ the inherited constructor template for now. */
+ raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
+ trivial_p = false;
+ deleted_p = DECL_DELETED_FN (DECL_TEMPLATE_RESULT (inherited_ctor));
+ constexpr_p
+ = DECL_DECLARED_CONSTEXPR_P (DECL_TEMPLATE_RESULT (inherited_ctor));
+ no_implicit_p = false;
+ }
+ else
+ synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
+ &deleted_p, &constexpr_p, &no_implicit_p, false,
+ inherited_base, inherited_parms);
/* Don't bother marking a deleted constructor as constexpr. */
if (deleted_p)
constexpr_p = false;
@@ -1544,9 +1650,10 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
if (raises)
fn_type = build_exception_variant (fn_type, raises);
fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
- DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
+ if (kind != sfk_inheriting_constructor)
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
if (kind == sfk_constructor || kind == sfk_copy_constructor
- || kind == sfk_move_constructor)
+ || kind == sfk_move_constructor || kind == sfk_inheriting_constructor)
DECL_CONSTRUCTOR_P (fn) = 1;
else if (kind == sfk_destructor)
DECL_DESTRUCTOR_P (fn) = 1;
@@ -1575,6 +1682,27 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
DECL_ARGUMENTS (fn) = decl;
}
+ else if (kind == sfk_inheriting_constructor)
+ {
+ tree *p = &DECL_ARGUMENTS (fn);
+ for (tree parm = inherited_parms; parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ {
+ *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm));
+ DECL_CONTEXT (*p) = fn;
+ p = &DECL_CHAIN (*p);
+ }
+ SET_DECL_INHERITED_CTOR_BASE (fn, inherited_base);
+ DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
+ /* A constructor so declared has the same access as the corresponding
+ constructor in X. */
+ TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
+ TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
+ /* Copy constexpr from the inherited constructor even if the
+ inheriting constructor doesn't satisfy the requirements. */
+ constexpr_p
+ = DECL_DECLARED_CONSTEXPR_P (STRIP_TEMPLATE (inherited_ctor));
+ }
/* Add the "this" parameter. */
this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
@@ -1600,6 +1728,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
/* Restore PROCESSING_TEMPLATE_DECL. */
processing_template_decl = saved_processing_template_decl;
+ if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ fn = add_inherited_template_parms (fn, inherited_ctor);
+
return fn;
}
@@ -1613,7 +1744,8 @@ defaulted_late_check (tree fn)
tree ctx = DECL_CONTEXT (fn);
special_function_kind kind = special_function_p (fn);
bool fn_const_p = (copy_fn_p (fn) == 2);
- tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p);
+ tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
+ NULL, NULL);
if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
TREE_TYPE (TREE_TYPE (implicit_fn)))
@@ -1766,7 +1898,7 @@ lazily_declare_fn (special_function_kind sfk, tree type)
}
/* Declare the function. */
- fn = implicitly_declare_fn (sfk, type, const_p);
+ fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);
/* [class.copy]/8 If the class definition declares a move constructor or
move assignment operator, the implicitly declared copy constructor is
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index cd328b31c..f01056049 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3026,6 +3026,14 @@ push_class_level_binding_1 (tree name, tree x)
&& TREE_TYPE (decl) == error_mark_node)
decl = TREE_VALUE (decl);
+ if (TREE_CODE (decl) == USING_DECL
+ && TREE_CODE (USING_DECL_SCOPE (decl)) == TEMPLATE_TYPE_PARM
+ && DECL_NAME (decl) == TYPE_IDENTIFIER (USING_DECL_SCOPE (decl)))
+ /* This using-declaration declares constructors that inherit from the
+ constructors for the template parameter. It does not redeclare the
+ name of the template parameter. */
+ return true;
+
if (!check_template_shadow (decl))
return false;
@@ -3218,10 +3226,7 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
}
if (MAYBE_CLASS_TYPE_P (scope) && constructor_name_p (name, scope))
- {
- error ("%<%T::%D%> names constructor", scope, name);
- return NULL_TREE;
- }
+ maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
if (constructor_name_p (name, current_class_type))
{
error ("%<%T::%D%> names constructor in %qT",
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a7939c876..853d789f9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -23252,15 +23252,17 @@ cp_parser_optional_template_keyword (cp_parser *parser)
{
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
{
- /* The `template' keyword can only be used within templates;
+ /* In C++98 the `template' keyword can only be used within templates;
outside templates the parser can always figure out what is a
- template and what is not. */
- if (!processing_template_decl)
+ template and what is not. In C++11, per the resolution of DR 468,
+ `template' is allowed in cases where it is not strictly necessary. */
+ if (!processing_template_decl
+ && pedantic && cxx_dialect == cxx98)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
- error_at (token->location,
- "%<template%> (as a disambiguator) is only allowed "
- "within templates");
+ pedwarn (token->location, OPT_Wpedantic,
+ "in C++98 %<template%> (as a disambiguator) is only "
+ "allowed within templates");
/* If this part of the token stream is rescanned, the same
error message would be generated. So, we purge the token
from the stream. */
@@ -23274,7 +23276,6 @@ cp_parser_optional_template_keyword (cp_parser *parser)
return true;
}
}
-
return false;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d81626cb3..7e8d8b088 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3847,17 +3847,16 @@ arg_from_parm_pack_p (tree arg_pack, tree parm_pack)
return false;
}
-/* Within the declaration of a template, return all levels of template
- parameters that apply. The template parameters are represented as
- a TREE_VEC, in the form documented in cp-tree.h for template
- arguments. */
+/* Given a set of template parameters, return them as a set of template
+ arguments. The template parameters are represented as a TREE_VEC, in
+ the form documented in cp-tree.h for template arguments. */
static tree
-current_template_args (void)
+template_parms_to_args (tree parms)
{
tree header;
tree args = NULL_TREE;
- int length = TMPL_PARMS_DEPTH (current_template_parms);
+ int length = TMPL_PARMS_DEPTH (parms);
int l = length;
/* If there is only one level of template parameters, we do not
@@ -3866,7 +3865,7 @@ current_template_args (void)
if (length > 1)
args = make_tree_vec (length);
- for (header = current_template_parms; header; header = TREE_CHAIN (header))
+ for (header = parms; header; header = TREE_CHAIN (header))
{
tree a = copy_node (TREE_VALUE (header));
int i;
@@ -3903,6 +3902,15 @@ current_template_args (void)
return args;
}
+/* Within the declaration of a template, return the currently active
+ template parameters as an argument TREE_VEC. */
+
+static tree
+current_template_args (void)
+{
+ return template_parms_to_args (current_template_parms);
+}
+
/* Update the declared TYPE by doing any lookups which were thought to be
dependent, but are not now that we know the SCOPE of the declarator. */
@@ -4904,6 +4912,29 @@ push_template_decl (tree decl)
return push_template_decl_real (decl, false);
}
+/* FN is an inheriting constructor that inherits from the constructor
+ template INHERITED; turn FN into a constructor template with a matching
+ template header. */
+
+tree
+add_inherited_template_parms (tree fn, tree inherited)
+{
+ tree inner_parms
+ = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (inherited));
+ inner_parms = copy_node (inner_parms);
+ tree parms
+ = tree_cons (size_int (processing_template_decl + 1),
+ inner_parms, current_template_parms);
+ tree tmpl = build_template_decl (fn, parms, /*member*/true);
+ tree args = template_parms_to_args (parms);
+ DECL_TEMPLATE_INFO (fn) = build_template_info (tmpl, args);
+ TREE_TYPE (tmpl) = TREE_TYPE (fn);
+ DECL_TEMPLATE_RESULT (tmpl) = fn;
+ DECL_ARTIFICIAL (tmpl) = true;
+ DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
+ return tmpl;
+}
+
/* Called when a class template TYPE is redeclared with the indicated
template PARMS, e.g.:
@@ -10136,6 +10167,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
maybe_retrofit_in_chrg (r);
if (DECL_CONSTRUCTOR_P (r))
grok_ctor_properties (ctx, r);
+ if (DECL_INHERITED_CTOR_BASE (r))
+ deduce_inheriting_ctor (r);
/* If this is an instantiation of a member template, clone it.
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
@@ -10336,9 +10369,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (DECL_DEPENDENT_P (t)
|| uses_template_parms (USING_DECL_SCOPE (t)))
{
- r = do_class_using_decl
- (tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
- tsubst_copy (DECL_NAME (t), args, complain, in_decl));
+ tree scope = USING_DECL_SCOPE (t);
+ tree inst_scope = tsubst_copy (USING_DECL_SCOPE (t), args,
+ complain, in_decl);
+ tree name = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
+ if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM
+ && name == TYPE_IDENTIFIER (scope))
+ name = TYPE_IDENTIFIER (inst_scope);
+ r = do_class_using_decl (inst_scope, name);
if (!r)
r = error_mark_node;
else
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a41337c21..8d555c2e2 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3337,6 +3337,8 @@ special_function_p (const_tree decl)
/* Rather than doing all this stuff with magic names, we should
probably have a field of type `special_function_kind' in
DECL_LANG_SPECIFIC. */
+ if (DECL_INHERITED_CTOR_BASE (decl))
+ return sfk_inheriting_constructor;
if (DECL_COPY_CONSTRUCTOR_P (decl))
return sfk_copy_constructor;
if (DECL_MOVE_CONSTRUCTOR_P (decl))
diff --git a/gcc/cse.c b/gcc/cse.c
index 16255988f..b5631f363 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2096,24 +2096,22 @@ invalidate_for_call (void)
unsigned hash;
struct table_elt *p, *next;
int in_table = 0;
+ hard_reg_set_iterator hrsi;
/* Go through all the hard registers. For each that is clobbered in
a CALL_INSN, remove the register from quantity chains and update
reg_tick if defined. Also see if any of these registers is currently
in the table. */
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
- {
- delete_reg_equiv (regno);
- if (REG_TICK (regno) >= 0)
- {
- REG_TICK (regno)++;
- SUBREG_TICKED (regno) = -1;
- }
-
- in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
- }
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi)
+ {
+ delete_reg_equiv (regno);
+ if (REG_TICK (regno) >= 0)
+ {
+ REG_TICK (regno)++;
+ SUBREG_TICKED (regno) = -1;
+ }
+ in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);
+ }
/* In the case where we have no call-clobbered hard registers in the
table, we are done. Otherwise, scan the table and remove any
diff --git a/gcc/cselib.c b/gcc/cselib.c
index e7c4221df..1f9f97efc 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -210,6 +210,9 @@ void (*cselib_record_sets_hook) (rtx insn, struct cselib_set *sets,
#define PRESERVED_VALUE_P(RTX) \
(RTL_FLAG_CHECK1("PRESERVED_VALUE_P", (RTX), VALUE)->unchanging)
+#define SP_BASED_VALUE_P(RTX) \
+ (RTL_FLAG_CHECK1("SP_BASED_VALUE_P", (RTX), VALUE)->jump)
+
/* Allocate a struct elt_list and fill in its two elements with the
@@ -739,6 +742,24 @@ cselib_preserve_only_values (void)
gcc_assert (first_containing_mem == &dummy_val);
}
+/* Arrange for a value to be marked as based on stack pointer
+ for find_base_term purposes. */
+
+void
+cselib_set_value_sp_based (cselib_val *v)
+{
+ SP_BASED_VALUE_P (v->val_rtx) = 1;
+}
+
+/* Test whether a value is based on stack pointer for
+ find_base_term purposes. */
+
+bool
+cselib_sp_based_value_p (cselib_val *v)
+{
+ return SP_BASED_VALUE_P (v->val_rtx);
+}
+
/* Return the mode in which a register was last set. If X is not a
register, return its mode. If the mode in which the register was
set is not known, or the value was already clobbered, return
diff --git a/gcc/cselib.h b/gcc/cselib.h
index 96575f985..95fdbf7a5 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -99,6 +99,8 @@ extern void cselib_preserve_only_values (void);
extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int);
extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx);
extern bool cselib_have_permanent_equivalences (void);
+extern void cselib_set_value_sp_based (cselib_val *);
+extern bool cselib_sp_based_value_p (cselib_val *);
extern void dump_cselib_table (FILE *);
diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c
index 72fce0598..bcd6c08a6 100644
--- a/gcc/data-streamer-in.c
+++ b/gcc/data-streamer-in.c
@@ -86,6 +86,35 @@ streamer_read_string (struct data_in *data_in, struct lto_input_block *ib)
}
+/* Read a string from the string table in DATA_IN using the bitpack BP.
+ Write the length to RLEN. */
+
+const char *
+bp_unpack_indexed_string (struct data_in *data_in,
+ struct bitpack_d *bp, unsigned int *rlen)
+{
+ return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
+}
+
+
+/* Read a NULL terminated string from the string table in DATA_IN. */
+
+const char *
+bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp)
+{
+ unsigned int len;
+ const char *ptr;
+
+ ptr = bp_unpack_indexed_string (data_in, bp, &len);
+ if (!ptr)
+ return NULL;
+ if (ptr[len - 1] != '\0')
+ internal_error ("bytecode stream: found non-null terminated string");
+
+ return ptr;
+}
+
+
/* Read an unsigned HOST_WIDE_INT number from IB. */
unsigned HOST_WIDE_INT
diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c
index 98cbf2261..aae4d471f 100644
--- a/gcc/data-streamer-out.c
+++ b/gcc/data-streamer-out.c
@@ -115,6 +115,39 @@ streamer_write_string (struct output_block *ob,
}
+/* Output STRING of LEN characters to the string table in OB. Then
+ put the index into BP.
+ When PERSISTENT is set, the string S is supposed to not change during
+ duration of the OB and thus OB can keep pointer into it. */
+
+void
+bp_pack_string_with_length (struct output_block *ob, struct bitpack_d *bp,
+ const char *s, unsigned int len, bool persistent)
+{
+ unsigned index = 0;
+ if (s)
+ index = streamer_string_index (ob, s, len, persistent);
+ bp_pack_var_len_unsigned (bp, index);
+}
+
+
+/* Output the '\0' terminated STRING to the string
+ table in OB. Then put the index onto the bitpack BP.
+ When PERSISTENT is set, the string S is supposed to not change during
+ duration of the OB and thus OB can keep pointer into it. */
+
+void
+bp_pack_string (struct output_block *ob, struct bitpack_d *bp,
+ const char *s, bool persistent)
+{
+ unsigned index = 0;
+ if (s)
+ index = streamer_string_index (ob, s, strlen (s) + 1, persistent);
+ bp_pack_var_len_unsigned (bp, index);
+}
+
+
+
/* Write a zero to the output stream. */
void
diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h
index c413a7593..705713cd1 100644
--- a/gcc/data-streamer.h
+++ b/gcc/data-streamer.h
@@ -72,6 +72,10 @@ unsigned streamer_string_index (struct output_block *, const char *,
void streamer_write_string_with_length (struct output_block *,
struct lto_output_stream *,
const char *, unsigned int, bool);
+void bp_pack_string_with_length (struct output_block *, struct bitpack_d *,
+ const char *, unsigned int, bool);
+void bp_pack_string (struct output_block *, struct bitpack_d *,
+ const char *, bool);
void streamer_write_uhwi_stream (struct lto_output_stream *,
unsigned HOST_WIDE_INT);
void streamer_write_hwi_stream (struct lto_output_stream *, HOST_WIDE_INT);
@@ -82,6 +86,9 @@ const char *streamer_read_string (struct data_in *, struct lto_input_block *);
const char *streamer_read_indexed_string (struct data_in *,
struct lto_input_block *,
unsigned int *);
+const char *bp_unpack_indexed_string (struct data_in *, struct bitpack_d *,
+ unsigned int *);
+const char *bp_unpack_string (struct data_in *, struct bitpack_d *);
unsigned HOST_WIDE_INT streamer_read_uhwi (struct lto_input_block *);
HOST_WIDE_INT streamer_read_hwi (struct lto_input_block *);
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index b4df2ba2a..3f9228dc5 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -2822,13 +2822,10 @@ df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
#endif
-/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN and add
- them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. Remove also
- REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE
- as the bitmap of currently live registers. */
+/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN. */
static void
-df_kill_notes (rtx insn, bitmap live)
+df_remove_dead_and_unused_notes (rtx insn)
{
rtx *pprev = &REG_NOTES (insn);
rtx link = *pprev;
@@ -2873,6 +2870,27 @@ df_kill_notes (rtx insn, bitmap live)
}
break;
+ default:
+ pprev = &XEXP (link, 1);
+ link = *pprev;
+ break;
+ }
+ }
+}
+
+/* Remove REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE
+ as the bitmap of currently live registers. */
+
+static void
+df_remove_dead_eq_notes (rtx insn, bitmap live)
+{
+ rtx *pprev = &REG_NOTES (insn);
+ rtx link = *pprev;
+
+ while (link)
+ {
+ switch (REG_NOTE_KIND (link))
+ {
case REG_EQUAL:
case REG_EQUIV:
{
@@ -2913,6 +2931,7 @@ df_kill_notes (rtx insn, bitmap live)
}
break;
}
+
default:
pprev = &XEXP (link, 1);
link = *pprev;
@@ -2921,7 +2940,6 @@ df_kill_notes (rtx insn, bitmap live)
}
}
-
/* Set a NOTE_TYPE note for REG in INSN. */
static inline void
@@ -3195,7 +3213,7 @@ df_note_bb_compute (unsigned int bb_index,
debug_insn = DEBUG_INSN_P (insn);
bitmap_clear (do_not_gen);
- df_kill_notes (insn, live);
+ df_remove_dead_and_unused_notes (insn);
/* Process the defs. */
if (CALL_P (insn))
@@ -3336,6 +3354,8 @@ df_note_bb_compute (unsigned int bb_index,
}
}
+ df_remove_dead_eq_notes (insn, live);
+
if (debug_insn == -1)
{
/* ??? We could probably do better here, replacing dead
diff --git a/gcc/doc/arm-neon-intrinsics.texi b/gcc/doc/arm-neon-intrinsics.texi
index a75e5821e..14e6264ae 100644
--- a/gcc/doc/arm-neon-intrinsics.texi
+++ b/gcc/doc/arm-neon-intrinsics.texi
@@ -972,6 +972,38 @@
+@subsubsection Fused-multiply-accumulate
+
+@itemize @bullet
+@item float32x2_t vfma_f32 (float32x2_t, float32x2_t, float32x2_t)
+@*@emph{Form of expected instruction(s):} @code{vfma.f32 @var{d0}, @var{d0}, @var{d0}}
+@end itemize
+
+
+@itemize @bullet
+@item float32x4_t vfmaq_f32 (float32x4_t, float32x4_t, float32x4_t)
+@*@emph{Form of expected instruction(s):} @code{vfma.f32 @var{q0}, @var{q0}, @var{q0}}
+@end itemize
+
+
+
+
+@subsubsection Fused-multiply-subtract
+
+@itemize @bullet
+@item float32x2_t vfms_f32 (float32x2_t, float32x2_t, float32x2_t)
+@*@emph{Form of expected instruction(s):} @code{vfms.f32 @var{d0}, @var{d0}, @var{d0}}
+@end itemize
+
+
+@itemize @bullet
+@item float32x4_t vfmsq_f32 (float32x4_t, float32x4_t, float32x4_t)
+@*@emph{Form of expected instruction(s):} @code{vfms.f32 @var{q0}, @var{q0}, @var{q0}}
+@end itemize
+
+
+
+
@subsubsection Subtraction
@itemize @bullet
@@ -1497,24 +1529,6 @@
@subsubsection Comparison (greater-than-or-equal-to)
@itemize @bullet
-@item uint32x2_t vcge_u32 (uint32x2_t, uint32x2_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{d0}, @var{d0}, @var{d0}}
-@end itemize
-
-
-@itemize @bullet
-@item uint16x4_t vcge_u16 (uint16x4_t, uint16x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{d0}, @var{d0}, @var{d0}}
-@end itemize
-
-
-@itemize @bullet
-@item uint8x8_t vcge_u8 (uint8x8_t, uint8x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{d0}, @var{d0}, @var{d0}}
-@end itemize
-
-
-@itemize @bullet
@item uint32x2_t vcge_s32 (int32x2_t, int32x2_t)
@*@emph{Form of expected instruction(s):} @code{vcge.s32 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@@ -1539,20 +1553,20 @@
@itemize @bullet
-@item uint32x4_t vcgeq_u32 (uint32x4_t, uint32x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{q0}, @var{q0}, @var{q0}}
+@item uint32x2_t vcge_u32 (uint32x2_t, uint32x2_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint16x8_t vcgeq_u16 (uint16x8_t, uint16x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{q0}, @var{q0}, @var{q0}}
+@item uint16x4_t vcge_u16 (uint16x4_t, uint16x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint8x16_t vcgeq_u8 (uint8x16_t, uint8x16_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{q0}, @var{q0}, @var{q0}}
+@item uint8x8_t vcge_u8 (uint8x8_t, uint8x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@@ -1580,28 +1594,28 @@
@end itemize
-
-
-@subsubsection Comparison (less-than-or-equal-to)
-
@itemize @bullet
-@item uint32x2_t vcle_u32 (uint32x2_t, uint32x2_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{d0}, @var{d0}, @var{d0}}
+@item uint32x4_t vcgeq_u32 (uint32x4_t, uint32x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{q0}, @var{q0}, @var{q0}}
@end itemize
@itemize @bullet
-@item uint16x4_t vcle_u16 (uint16x4_t, uint16x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{d0}, @var{d0}, @var{d0}}
+@item uint16x8_t vcgeq_u16 (uint16x8_t, uint16x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{q0}, @var{q0}, @var{q0}}
@end itemize
@itemize @bullet
-@item uint8x8_t vcle_u8 (uint8x8_t, uint8x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{d0}, @var{d0}, @var{d0}}
+@item uint8x16_t vcgeq_u8 (uint8x16_t, uint8x16_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{q0}, @var{q0}, @var{q0}}
@end itemize
+
+
+@subsubsection Comparison (less-than-or-equal-to)
+
@itemize @bullet
@item uint32x2_t vcle_s32 (int32x2_t, int32x2_t)
@*@emph{Form of expected instruction(s):} @code{vcge.s32 @var{d0}, @var{d0}, @var{d0}}
@@ -1627,20 +1641,20 @@
@itemize @bullet
-@item uint32x4_t vcleq_u32 (uint32x4_t, uint32x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{q0}, @var{q0}, @var{q0}}
+@item uint32x2_t vcle_u32 (uint32x2_t, uint32x2_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint16x8_t vcleq_u16 (uint16x8_t, uint16x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{q0}, @var{q0}, @var{q0}}
+@item uint16x4_t vcle_u16 (uint16x4_t, uint16x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint8x16_t vcleq_u8 (uint8x16_t, uint8x16_t)
-@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{q0}, @var{q0}, @var{q0}}
+@item uint8x8_t vcle_u8 (uint8x8_t, uint8x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@@ -1668,28 +1682,28 @@
@end itemize
-
-
-@subsubsection Comparison (greater-than)
-
@itemize @bullet
-@item uint32x2_t vcgt_u32 (uint32x2_t, uint32x2_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{d0}, @var{d0}, @var{d0}}
+@item uint32x4_t vcleq_u32 (uint32x4_t, uint32x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u32 @var{q0}, @var{q0}, @var{q0}}
@end itemize
@itemize @bullet
-@item uint16x4_t vcgt_u16 (uint16x4_t, uint16x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{d0}, @var{d0}, @var{d0}}
+@item uint16x8_t vcleq_u16 (uint16x8_t, uint16x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u16 @var{q0}, @var{q0}, @var{q0}}
@end itemize
@itemize @bullet
-@item uint8x8_t vcgt_u8 (uint8x8_t, uint8x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{d0}, @var{d0}, @var{d0}}
+@item uint8x16_t vcleq_u8 (uint8x16_t, uint8x16_t)
+@*@emph{Form of expected instruction(s):} @code{vcge.u8 @var{q0}, @var{q0}, @var{q0}}
@end itemize
+
+
+@subsubsection Comparison (greater-than)
+
@itemize @bullet
@item uint32x2_t vcgt_s32 (int32x2_t, int32x2_t)
@*@emph{Form of expected instruction(s):} @code{vcgt.s32 @var{d0}, @var{d0}, @var{d0}}
@@ -1715,20 +1729,20 @@
@itemize @bullet
-@item uint32x4_t vcgtq_u32 (uint32x4_t, uint32x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{q0}, @var{q0}, @var{q0}}
+@item uint32x2_t vcgt_u32 (uint32x2_t, uint32x2_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint16x8_t vcgtq_u16 (uint16x8_t, uint16x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{q0}, @var{q0}, @var{q0}}
+@item uint16x4_t vcgt_u16 (uint16x4_t, uint16x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint8x16_t vcgtq_u8 (uint8x16_t, uint8x16_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{q0}, @var{q0}, @var{q0}}
+@item uint8x8_t vcgt_u8 (uint8x8_t, uint8x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@@ -1756,28 +1770,28 @@
@end itemize
-
-
-@subsubsection Comparison (less-than)
-
@itemize @bullet
-@item uint32x2_t vclt_u32 (uint32x2_t, uint32x2_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{d0}, @var{d0}, @var{d0}}
+@item uint32x4_t vcgtq_u32 (uint32x4_t, uint32x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{q0}, @var{q0}, @var{q0}}
@end itemize
@itemize @bullet
-@item uint16x4_t vclt_u16 (uint16x4_t, uint16x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{d0}, @var{d0}, @var{d0}}
+@item uint16x8_t vcgtq_u16 (uint16x8_t, uint16x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{q0}, @var{q0}, @var{q0}}
@end itemize
@itemize @bullet
-@item uint8x8_t vclt_u8 (uint8x8_t, uint8x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{d0}, @var{d0}, @var{d0}}
+@item uint8x16_t vcgtq_u8 (uint8x16_t, uint8x16_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{q0}, @var{q0}, @var{q0}}
@end itemize
+
+
+@subsubsection Comparison (less-than)
+
@itemize @bullet
@item uint32x2_t vclt_s32 (int32x2_t, int32x2_t)
@*@emph{Form of expected instruction(s):} @code{vcgt.s32 @var{d0}, @var{d0}, @var{d0}}
@@ -1803,20 +1817,20 @@
@itemize @bullet
-@item uint32x4_t vcltq_u32 (uint32x4_t, uint32x4_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{q0}, @var{q0}, @var{q0}}
+@item uint32x2_t vclt_u32 (uint32x2_t, uint32x2_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint16x8_t vcltq_u16 (uint16x8_t, uint16x8_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{q0}, @var{q0}, @var{q0}}
+@item uint16x4_t vclt_u16 (uint16x4_t, uint16x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@itemize @bullet
-@item uint8x16_t vcltq_u8 (uint8x16_t, uint8x16_t)
-@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{q0}, @var{q0}, @var{q0}}
+@item uint8x8_t vclt_u8 (uint8x8_t, uint8x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{d0}, @var{d0}, @var{d0}}
@end itemize
@@ -1844,6 +1858,24 @@
@end itemize
+@itemize @bullet
+@item uint32x4_t vcltq_u32 (uint32x4_t, uint32x4_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u32 @var{q0}, @var{q0}, @var{q0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint16x8_t vcltq_u16 (uint16x8_t, uint16x8_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u16 @var{q0}, @var{q0}, @var{q0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint8x16_t vcltq_u8 (uint8x16_t, uint8x16_t)
+@*@emph{Form of expected instruction(s):} @code{vcgt.u8 @var{q0}, @var{q0}, @var{q0}}
+@end itemize
+
+
@subsubsection Comparison (absolute greater-than-or-equal-to)
@@ -4810,13 +4842,13 @@
@itemize @bullet
@item uint64_t vgetq_lane_u64 (uint64x2_t, const int)
-@*@emph{Form of expected instruction(s):} @code{vmov @var{r0}, @var{r0}, @var{d0}}
+@*@emph{Form of expected instruction(s):} @code{vmov @var{r0}, @var{r0}, @var{d0}} @emph{or} @code{fmrrd @var{r0}, @var{r0}, @var{d0}}
@end itemize
@itemize @bullet
@item int64_t vgetq_lane_s64 (int64x2_t, const int)
-@*@emph{Form of expected instruction(s):} @code{vmov @var{r0}, @var{r0}, @var{d0}}
+@*@emph{Form of expected instruction(s):} @code{vmov @var{r0}, @var{r0}, @var{d0}} @emph{or} @code{fmrrd @var{r0}, @var{r0}, @var{d0}}
@end itemize
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a07539a4a..6bf929a5c 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2682,17 +2682,16 @@ function through the function vector will reduce code size, however;
the function vector has a limited size (maximum 128 entries on the H8/300
and 64 entries on the H8/300H and H8S) and shares space with the interrupt vector.
-In SH2A target, this attribute declares a function to be called using the
+On SH2A targets, this attribute declares a function to be called using the
TBR relative addressing mode. The argument to this attribute is the entry
number of the same function in a vector table containing all the TBR
-relative addressable functions. For the successful jump, register TBR
-should contain the start address of this TBR relative vector table.
-In the startup routine of the user application, user needs to care of this
-TBR register initialization. The TBR relative vector table can have at
-max 256 function entries. The jumps to these functions will be generated
-using a SH2A specific, non delayed branch instruction JSR/N @@(disp8,TBR).
-You must use GAS and GLD from GNU binutils version 2.7 or later for
-this attribute to work correctly.
+relative addressable functions. For correct operation the TBR must be setup
+accordingly to point to the start of the vector table before any functions with
+this attribute are invoked. Usually a good place to do the initialization is
+the startup routine. The TBR relative vector table can have at max 256 function
+entries. The jumps to these functions will be generated using a SH2A specific,
+non delayed branch instruction JSR/N @@(disp8,TBR). You must use GAS and GLD
+from GNU binutils version 2.7 or later for this attribute to work correctly.
Please refer the example of M16C target, to see the use of this
attribute while declaring a function,
@@ -3251,6 +3250,13 @@ with the notable exceptions of @code{qsort} and @code{bsearch} that
take function pointer arguments. The @code{nothrow} attribute is not
implemented in GCC versions earlier than 3.3.
+@item nosave_low_regs
+@cindex @code{nosave_low_regs} attribute
+Use this attribute on SH targets to indicate that an @code{interrupt_handler}
+function should not save and restore registers R0..R7. This can be used on SH3*
+and SH4* targets which have a second R0..R7 register bank for non-reentrant
+interrupt handlers.
+
@item optimize
@cindex @code{optimize} function attribute
The @code{optimize} attribute is used to specify that a function is to
@@ -3428,6 +3434,11 @@ prologue and epilogue that realigns the runtime stack if necessary.
This supports mixing legacy codes that run with a 4-byte aligned stack
with modern codes that keep a 16-byte stack for SSE compatibility.
+@item renesas
+@cindex @code{renesas} attribute
+On SH targets this attribute specifies that the function or struct follows the
+Renesas ABI.
+
@item resbank
@cindex @code{resbank} attribute
On the SH2A target, this attribute enables the high-speed register
@@ -3538,6 +3549,7 @@ If both @code{signal} and @code{interrupt} are specified for the same
function, @code{signal} will be silently ignored.
@item sp_switch
+@cindex @code{sp_switch} attribute
Use this attribute on the SH to indicate an @code{interrupt_handler}
function should switch to an alternate stack. It expects a string
argument that names a global variable holding the address of the
@@ -3929,10 +3941,16 @@ on data in the tiny data section. Note the tiny data area is limited to
slightly under 32kbytes of data.
@item trap_exit
+@cindex @code{trap_exit} attribute
Use this attribute on the SH for an @code{interrupt_handler} to return using
@code{trapa} instead of @code{rte}. This attribute expects an integer
argument specifying the trap number to be used.
+@item trapa_handler
+@cindex @code{trapa_handler} attribute
+On SH targets this function attribute is similar to @code{interrupt_handler}
+but it does not save and restore all registers.
+
@item unused
@cindex @code{unused} attribute.
This attribute, attached to a function, means that the function is meant
@@ -6751,13 +6769,13 @@ random value. In addition, @code{__builtin_frame_address} may be used
to determine if the top of the stack has been reached.
Additional post-processing of the returned value may be needed, see
-@code{__builtin_extract_return_address}.
+@code{__builtin_extract_return_addr}.
This function should only be used with a nonzero argument for debugging
purposes.
@end deftypefn
-@deftypefn {Built-in Function} {void *} __builtin_extract_return_address (void *@var{addr})
+@deftypefn {Built-in Function} {void *} __builtin_extract_return_addr (void *@var{addr})
The address as returned by @code{__builtin_return_address} may have to be fed
through this function to get the actual encoded address. For example, on the
31-bit S/390 platform the highest bit has to be masked out, or on SPARC
@@ -6768,7 +6786,7 @@ If no fixup is needed, this function simply passes through @var{addr}.
@end deftypefn
@deftypefn {Built-in Function} {void *} __builtin_frob_return_address (void *@var{addr})
-This function does the reverse of @code{__builtin_extract_return_address}.
+This function does the reverse of @code{__builtin_extract_return_addr}.
@end deftypefn
@deftypefn {Built-in Function} {void *} __builtin_frame_address (unsigned int @var{level})
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index cbd49f50d..e7d5e1005 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -3151,7 +3151,7 @@ This is a synonym for @samp{x86_64-*-solaris2.1[0-9]*}.
@heading @anchor{arm-x-eabi}arm-*-eabi
ARM-family processors. Subtargets that use the ELF object format
require GNU binutils 2.13 or newer. Such subtargets include:
-@code{arm-*-netbsdelf}, @code{arm-*-*linux-gnueabi}
+@code{arm-*-netbsdelf}, @code{arm-*-*linux-*}
and @code{arm-*-rtemseabi}.
@html
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index cb5de9e19..fbab2935b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11133,6 +11133,7 @@ of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
@samp{armv6}, @samp{armv6j},
@samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m},
@samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m},
+@samp{armv8-a},
@samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}.
@option{-march=native} causes the compiler to auto-detect the architecture
@@ -11146,7 +11147,8 @@ This specifies what floating-point hardware (or hardware emulation) is
available on the target. Permissible names are: @samp{vfp}, @samp{vfpv3},
@samp{vfpv3-fp16}, @samp{vfpv3-d16}, @samp{vfpv3-d16-fp16}, @samp{vfpv3xd},
@samp{vfpv3xd-fp16}, @samp{neon}, @samp{neon-fp16}, @samp{vfpv4},
-@samp{vfpv4-d16}, @samp{fpv4-sp-d16} and @samp{neon-vfpv4}.
+@samp{vfpv4-d16}, @samp{fpv4-sp-d16}, @samp{neon-vfpv4},
+@samp{fp-armv8}, @samp{neon-fp-armv8}, and @samp{crypto-neon-fp-armv8}.
If @option{-msoft-float} is specified this specifies the format of
floating-point values.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 02ee623a1..57d0be8c7 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -665,6 +665,22 @@ as follows, having the output control string start with a @samp{@@}:
@end group
@end smallexample
+If you just need a little bit of C code in one (or a few) alternatives,
+you can use @samp{*} inside of a @samp{@@} multi-alternative template:
+
+@smallexample
+@group
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=r,<,m")
+ (const_int 0))]
+ ""
+ "@@
+ clrreg %0
+ * return stack_mem_p (operands[0]) ? \"push 0\" : \"clrmem %0\";
+ clrmem %0")
+@end group
+@end smallexample
+
@node Predicates
@section Predicates
@cindex predicates
@@ -5561,7 +5577,9 @@ iterations as a @code{const_int} or @code{const0_rtx} if this cannot be
determined until run-time; operand 2 is the actual or estimated maximum
number of iterations as a @code{const_int}; operand 3 is the number of
enclosed loops as a @code{const_int} (an innermost loop has a value of
-1); operand 4 is the label to jump to if the register is nonzero.
+1); operand 4 is the label to jump to if the register is nonzero;
+operand 5 is const1_rtx if the loop in entered at its top, const0_rtx
+otherwise.
@xref{Looping Patterns}.
This optional instruction pattern should be defined for machines with
diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi
index 9c004c8cd..f6a31f8d4 100644
--- a/gcc/doc/options.texi
+++ b/gcc/doc/options.texi
@@ -343,8 +343,8 @@ for the option. If the option is attached to @samp{target_flags},
the script will set the macro @code{MASK_@var{name}} to the appropriate
bitmask. It will also declare a @code{TARGET_@var{name}} macro that has
the value 1 when the option is active and 0 otherwise. If you use @code{Var}
-to attach the option to a different variable, the associated macros are
-called @code{OPTION_MASK_@var{name}} and @code{OPTION_@var{name}} respectively.
+to attach the option to a different variable, the bitmask macro with be
+called @code{OPTION_MASK_@var{name}}.
@item InverseMask(@var{othername})
@itemx InverseMask(@var{othername}, @var{thisname})
@@ -460,14 +460,21 @@ value of @option{-fmath-errno} for languages that do not use
@code{errno}.
@item EnabledBy(@var{opt})
-If not explicitly set, the option is set to the value of @option{-@var{opt}}.
+@itemx EnabledBy(@var{opt} && @var{opt2})
+If not explicitly set, the option is set to the value of
+@option{-@var{opt}}. The second form specifies that the option is
+only set if both @var{opt} and @var{opt2} are set.
@item LangEnabledBy(@var{language}, @var{opt})
+@itemx LangEnabledBy(@var{language}, @var{opt}, @var{posarg}, @var{negarg})
When compiling for the given language, the option is set to the value
-of @option{-@var{opt}}, if not explicitly set. It is possible to
-specify several different languages. Each @var{language} must have
-been declared by an earlier @code{Language} record. @xref{Option file
-format}.
+of @option{-@var{opt}}, if not explicitly set. In the second form, if
+@var{opt} is used in the positive form then @var{posarg} is considered
+to be passed to the option, and if @var{opt} is used in the negative
+form then @var{negarg} is considered to be passed to the option. It
+is possible to specify several different languages. Each
+@var{language} must have been declared by an earlier @code{Language}
+record. @xref{Option file format}.
@item NoDWARFRecord
The option is omitted from the producer string written by
diff --git a/gcc/dojump.c b/gcc/dojump.c
index 66d3b04bd..35cb2cf62 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -886,7 +886,6 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
{
rtx tem;
rtx dummy_label = NULL_RTX;
- rtx last;
/* Reverse the comparison if that is safe and we want to jump if it is
false. Also convert to the reverse comparison if the target can
@@ -1069,25 +1068,8 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
}
}
- last = get_last_insn ();
emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
- if_true_label);
- if (prob != -1 && profile_status != PROFILE_ABSENT)
- {
- for (last = NEXT_INSN (last);
- last && NEXT_INSN (last);
- last = NEXT_INSN (last))
- if (JUMP_P (last))
- break;
- if (last
- && JUMP_P (last)
- && ! NEXT_INSN (last)
- && any_condjump_p (last))
- {
- gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
- add_reg_note (last, REG_BR_PROB, GEN_INT (prob));
- }
- }
+ if_true_label, prob);
}
if (if_false_label)
diff --git a/gcc/dse.c b/gcc/dse.c
index eff4a3909..631a1f20a 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -989,7 +989,32 @@ delete_dead_store_insn (insn_info_t insn_info)
insn_info->wild_read = false;
}
-/* Check if EXPR can possibly escape the current function scope. */
+/* Return whether DECL, a local variable, can possibly escape the current
+ function scope. */
+
+static bool
+local_variable_can_escape (tree decl)
+{
+ if (TREE_ADDRESSABLE (decl))
+ return true;
+
+ /* If this is a partitioned variable, we need to consider all the variables
+ in the partition. This is necessary because a store into one of them can
+ be replaced with a store into another and this may not change the outcome
+ of the escape analysis. */
+ if (cfun->gimple_df->decls_to_pointers != NULL)
+ {
+ void *namep
+ = pointer_map_contains (cfun->gimple_df->decls_to_pointers, decl);
+ if (namep)
+ return TREE_ADDRESSABLE (*(tree *)namep);
+ }
+
+ return false;
+}
+
+/* Return whether EXPR can possibly escape the current function scope. */
+
static bool
can_escape (tree expr)
{
@@ -998,7 +1023,11 @@ can_escape (tree expr)
return true;
base = get_base_address (expr);
if (DECL_P (base)
- && !may_be_aliased (base))
+ && !may_be_aliased (base)
+ && !(TREE_CODE (base) == VAR_DECL
+ && !DECL_EXTERNAL (base)
+ && !TREE_STATIC (base)
+ && local_variable_can_escape (base)))
return false;
return true;
}
@@ -2518,14 +2547,8 @@ scan_insn (bb_info_t bb_info, rtx insn)
const_call = RTL_CONST_CALL_P (insn);
if (!const_call)
{
- rtx call = PATTERN (insn);
- if (GET_CODE (call) == PARALLEL)
- call = XVECEXP (call, 0, 0);
- if (GET_CODE (call) == SET)
- call = SET_SRC (call);
- if (GET_CODE (call) == CALL
- && MEM_P (XEXP (call, 0))
- && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
+ rtx call = get_call_rtx_from (insn);
+ if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
{
rtx symbol = XEXP (XEXP (call, 0), 0);
if (SYMBOL_REF_DECL (symbol)
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 95fc130c3..fcdb1b119 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20100,12 +20100,8 @@ dwarf2out_var_location (rtx loc_note)
if (!CALL_P (prev))
prev = XVECEXP (PATTERN (prev), 0, 0);
ca_loc->tail_call_p = SIBLING_CALL_P (prev);
- x = PATTERN (prev);
- if (GET_CODE (x) == PARALLEL)
- x = XVECEXP (x, 0, 0);
- if (GET_CODE (x) == SET)
- x = SET_SRC (x);
- if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
+ x = get_call_rtx_from (PATTERN (prev));
+ if (x)
{
x = XEXP (XEXP (x, 0), 0);
if (GET_CODE (x) == SYMBOL_REF
diff --git a/gcc/except.c b/gcc/except.c
index 88cac856d..a46735319 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1153,7 +1153,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
if (dispatch_label)
{
#ifdef DONT_USE_BUILTIN_SETJMP
- rtx x, last;
+ rtx x;
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
TYPE_MODE (integer_type_node), 1,
plus_constant (Pmode, XEXP (fc, 0),
@@ -1161,13 +1161,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
TYPE_MODE (integer_type_node), 0,
- dispatch_label);
- last = get_last_insn ();
- if (JUMP_P (last) && any_condjump_p (last))
- {
- gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
- add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100));
- }
+ dispatch_label, REG_BR_PROB_BASE / 100);
#else
expand_builtin_setjmp_setup (plus_constant (Pmode, XEXP (fc, 0),
sjlj_fc_jbuf_ofs),
diff --git a/gcc/expr.c b/gcc/expr.c
index 1adea93c3..8fa19fd5c 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -154,7 +154,7 @@ static rtx do_store_flag (sepops, rtx, enum machine_mode);
#ifdef PUSH_ROUNDING
static void emit_single_push_insn (enum machine_mode, rtx, tree);
#endif
-static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
+static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx, int);
static rtx const_vector_from_tree (tree);
static void write_complex_part (rtx, rtx, bool);
@@ -966,7 +966,7 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
/* First move what we can in the largest integer mode, then go to
successively smaller modes. */
- while (max_size > 1)
+ while (max_size > 1 && data.len > 0)
{
enum machine_mode mode = widest_int_mode_for_size (max_size);
@@ -1026,7 +1026,7 @@ move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
- while (max_size > 1)
+ while (max_size > 1 && l > 0)
{
enum machine_mode mode;
enum insn_code icode;
@@ -1483,7 +1483,7 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
emit_label (cmp_label);
emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
- true, top_label);
+ true, top_label, REG_BR_PROB_BASE * 90 / 100);
}
/* Copy all or part of a value X into registers starting at REGNO.
@@ -2417,7 +2417,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
{
l = len;
max_size = STORE_MAX_PIECES + 1;
- while (max_size > 1)
+ while (max_size > 1 && l > 0)
{
mode = widest_int_mode_for_size (max_size);
@@ -2612,7 +2612,7 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
/* First store what we can in the largest integer mode, then go to
successively smaller modes. */
- while (max_size > 1)
+ while (max_size > 1 && data->len > 0)
{
enum machine_mode mode = widest_int_mode_for_size (max_size);
@@ -10270,10 +10270,15 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
enum insn_code icode;
- op0 = copy_rtx (op0);
-
if (TYPE_ALIGN_OK (type))
- set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+ {
+ /* ??? Copying the MEM without substantially changing it might
+ run afoul of the code handling volatile memory references in
+ store_expr, which assumes that TARGET is returned unmodified
+ if it has been used. */
+ op0 = copy_rtx (op0);
+ set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+ }
else if (mode != BLKmode
&& MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode)
/* If the target does have special handling for unaligned
@@ -10819,10 +10824,14 @@ do_store_flag (sepops ops, rtx target, enum machine_mode mode)
#endif
/* Attempt to generate a casesi instruction. Returns 1 if successful,
- 0 otherwise (i.e. if there is no casesi instruction). */
+ 0 otherwise (i.e. if there is no casesi instruction).
+
+ DEFAULT_PROBABILITY is the probability of jumping to the default
+ label. */
int
try_casesi (tree index_type, tree index_expr, tree minval, tree range,
- rtx table_label, rtx default_label, rtx fallback_label)
+ rtx table_label, rtx default_label, rtx fallback_label,
+ int default_probability)
{
struct expand_operand ops[5];
enum machine_mode index_mode = SImode;
@@ -10844,7 +10853,8 @@ try_casesi (tree index_type, tree index_expr, tree minval, tree range,
index = expand_normal (index_expr);
if (default_label)
emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
- omode, 1, default_label);
+ omode, 1, default_label,
+ default_probability);
/* Now we can safely truncate. */
index = convert_to_mode (index_mode, index, 0);
}
@@ -10890,11 +10900,13 @@ try_casesi (tree index_type, tree index_expr, tree minval, tree range,
TABLE_LABEL is a CODE_LABEL rtx for the table itself.
DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
- index value is out of range. */
+ index value is out of range.
+ DEFAULT_PROBABILITY is the probability of jumping to
+ the default label. */
static void
do_tablejump (rtx index, enum machine_mode mode, rtx range, rtx table_label,
- rtx default_label)
+ rtx default_label, int default_probability)
{
rtx temp, vector;
@@ -10911,7 +10923,8 @@ do_tablejump (rtx index, enum machine_mode mode, rtx range, rtx table_label,
if (default_label)
emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
- default_label);
+ default_label, default_probability);
+
/* If index is in range, it must fit in Pmode.
Convert to Pmode so we can index with it. */
@@ -10954,7 +10967,7 @@ do_tablejump (rtx index, enum machine_mode mode, rtx range, rtx table_label,
int
try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
- rtx table_label, rtx default_label)
+ rtx table_label, rtx default_label, int default_probability)
{
rtx index;
@@ -10972,7 +10985,7 @@ try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
TYPE_MODE (TREE_TYPE (range)),
expand_normal (range),
TYPE_UNSIGNED (TREE_TYPE (range))),
- table_label, default_label);
+ table_label, default_label, default_probability);
return 1;
}
diff --git a/gcc/expr.h b/gcc/expr.h
index 154648e7b..562ffe03a 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -190,7 +190,7 @@ extern int have_sub2_insn (rtx, rtx);
/* Emit a pair of rtl insns to compare two rtx's and to jump
to a label if the comparison is true. */
extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int, rtx);
+ enum machine_mode, int, rtx, int prob=-1);
/* Generate code to indirectly jump to a location given in the rtx LOC. */
extern void emit_indirect_jump (rtx);
@@ -485,8 +485,8 @@ extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
enum machine_mode, rtx, rtx, rtx, int);
/* Two different ways of generating switch statements. */
-extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx);
-extern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
+extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx, int);
+extern int try_tablejump (tree, tree, tree, tree, rtx, rtx, int);
/* Functions from alias.c */
#include "alias.h"
diff --git a/gcc/flags.h b/gcc/flags.h
index 141185bef..d56d5411e 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -37,14 +37,6 @@ extern int base_of_path (const char *path, const char **base_out);
extern bool fast_math_flags_set_p (const struct gcc_options *);
extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
-/* Used to set the level of -Wstrict-aliasing in OPTS, when no level
- is specified. The external way to set the default level is to use
- -Wstrict-aliasing=level.
- ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
- and 0 otherwise. After calling this function, wstrict_aliasing will be
- set to the default value of -Wstrict_aliasing=level. */
-
-extern void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
/* Now the symbols that are set with `-f' switches. */
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index ad7018659..37afedeae 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,27 @@
+2012-10-18 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/54884
+ * resolve.c (specification_expr): Change to bool.
+ (resolve_formal_arglist, resolve_symbol): Set
+ specification_expr to true before resolving the array spec.
+ (resolve_variable, resolve_charlen, resolve_fl_variable):
+ Properly reset specification_expr.
+ (resolve_function): Set public_use when used in
+ a specification expr.
+
+2012-10-16 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/50981
+ PR fortran/54618
+ * trans.h (gfc_conv_derived_to_class, gfc_conv_class_to_class):
+ Update prototype.
+ * trans-stmt.c (trans_associate_var,gfc_trans_allocate): Update
+ calls to those functions.
+ * trans-expr.c (gfc_conv_derived_to_class, gfc_conv_class_to_class,
+ gfc_conv_expr_present): Handle absent polymorphic arguments.
+ (class_scalar_coarray_to_class): New function.
+ (gfc_conv_procedure_call): Update calls.
+
2012-10-12 Janus Weil <janus@gcc.gnu.org>
PR fortran/40453
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 722e03651..ac3021ea7 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -81,7 +81,7 @@ static int omp_workshare_flag;
static int formal_arg_flag = 0;
/* True if we are resolving a specification expression. */
-static int specification_expr = 0;
+static bool specification_expr = false;
/* The id of the last entry seen. */
static int current_entry_id;
@@ -278,6 +278,7 @@ resolve_formal_arglist (gfc_symbol *proc)
{
gfc_formal_arglist *f;
gfc_symbol *sym;
+ bool saved_specification_expr;
int i;
if (proc->result != NULL)
@@ -336,7 +337,10 @@ resolve_formal_arglist (gfc_symbol *proc)
as = sym->ts.type == BT_CLASS && sym->attr.class_ok
? CLASS_DATA (sym)->as : sym->as;
+ saved_specification_expr = specification_expr;
+ specification_expr = true;
gfc_resolve_array_spec (as, 0);
+ specification_expr = saved_specification_expr;
/* We can't tell if an array with dimension (:) is assumed or deferred
shape until we know if it has the pointer or allocatable attributes.
@@ -3119,6 +3123,12 @@ resolve_function (gfc_expr *expr)
return FAILURE;
}
+ if (sym && specification_expr && sym->attr.function
+ && gfc_current_ns->proc_name
+ && gfc_current_ns->proc_name->attr.flavor == FL_MODULE)
+ sym->attr.public_used = 1;
+
+
/* Switch off assumed size checking and do this again for certain kinds
of procedure, once the procedure itself is resolved. */
need_full_assumed_size++;
@@ -5368,7 +5378,7 @@ resolve_variable (gfc_expr *e)
gfc_entry_list *entry;
gfc_formal_arglist *formal;
int n;
- bool seen;
+ bool seen, saved_specification_expr;
/* If the symbol is a dummy... */
if (sym->attr.dummy && sym->ns == gfc_current_ns)
@@ -5401,7 +5411,8 @@ resolve_variable (gfc_expr *e)
}
/* Now do the same check on the specification expressions. */
- specification_expr = 1;
+ saved_specification_expr = specification_expr;
+ specification_expr = true;
if (sym->ts.type == BT_CHARACTER
&& gfc_resolve_expr (sym->ts.u.cl->length) == FAILURE)
t = FAILURE;
@@ -5409,14 +5420,12 @@ resolve_variable (gfc_expr *e)
if (sym->as)
for (n = 0; n < sym->as->rank; n++)
{
- specification_expr = 1;
if (gfc_resolve_expr (sym->as->lower[n]) == FAILURE)
t = FAILURE;
- specification_expr = 1;
if (gfc_resolve_expr (sym->as->upper[n]) == FAILURE)
t = FAILURE;
}
- specification_expr = 0;
+ specification_expr = saved_specification_expr;
if (t == SUCCESS)
/* Update the symbol's entry level. */
@@ -10175,28 +10184,35 @@ static gfc_try
resolve_charlen (gfc_charlen *cl)
{
int i, k;
+ bool saved_specification_expr;
if (cl->resolved)
return SUCCESS;
cl->resolved = 1;
-
+ saved_specification_expr = specification_expr;
+ specification_expr = true;
if (cl->length_from_typespec)
{
if (gfc_resolve_expr (cl->length) == FAILURE)
- return FAILURE;
+ {
+ specification_expr = saved_specification_expr;
+ return FAILURE;
+ }
if (gfc_simplify_expr (cl->length, 0) == FAILURE)
- return FAILURE;
+ {
+ specification_expr = saved_specification_expr;
+ return FAILURE;
+ }
}
else
{
- specification_expr = 1;
if (resolve_index_expr (cl->length) == FAILURE)
{
- specification_expr = 0;
+ specification_expr = saved_specification_expr;
return FAILURE;
}
}
@@ -10220,9 +10236,11 @@ resolve_charlen (gfc_charlen *cl)
&& mpz_cmp (cl->length->value.integer, gfc_integer_kinds[k].huge) > 0)
{
gfc_error ("String length at %L is too large", &cl->length->where);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
+ specification_expr = saved_specification_expr;
return SUCCESS;
}
@@ -10682,6 +10700,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
int no_init_flag, automatic_flag;
gfc_expr *e;
const char *auto_save_msg;
+ bool saved_specification_expr;
auto_save_msg = "Automatic object '%s' at %L cannot have the "
"SAVE attribute";
@@ -10692,7 +10711,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
/* Set this flag to check that variables are parameters of all entries.
This check is effected by the call to gfc_resolve_expr through
is_non_constant_shape_array. */
- specification_expr = 1;
+ saved_specification_expr = specification_expr;
+ specification_expr = true;
if (sym->ns->proc_name
&& (sym->ns->proc_name->attr.flavor == FL_MODULE
@@ -10706,7 +10726,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
constant. */
gfc_error ("The module or main program array '%s' at %L must "
"have constant shape", sym->name, &sym->declared_at);
- specification_expr = 0;
+ specification_expr = saved_specification_expr;
return FAILURE;
}
@@ -10716,6 +10736,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
gfc_error ("Entity '%s' at %L has a deferred type parameter and "
"requires either the pointer or allocatable attribute",
sym->name, &sym->declared_at);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
@@ -10729,12 +10750,14 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
{
gfc_error ("Entity with assumed character length at %L must be a "
"dummy argument or a PARAMETER", &sym->declared_at);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
if (e && sym->attr.save == SAVE_EXPLICIT && !gfc_is_constant_expr (e))
{
gfc_error (auto_save_msg, sym->name, &sym->declared_at);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
@@ -10748,12 +10771,14 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
{
gfc_error ("'%s' at %L must have constant character length "
"in this context", sym->name, &sym->declared_at);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
if (sym->attr.in_common)
{
gfc_error ("COMMON variable '%s' at %L must have constant "
"character length", sym->name, &sym->declared_at);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
}
@@ -10784,6 +10809,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
if (automatic_flag && sym->attr.save == SAVE_EXPLICIT)
{
gfc_error (auto_save_msg, sym->name, &sym->declared_at);
+ specification_expr = saved_specification_expr;
return FAILURE;
}
}
@@ -10817,13 +10843,19 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
sym->name, &sym->declared_at);
else
goto no_init_error;
+ specification_expr = saved_specification_expr;
return FAILURE;
}
no_init_error:
if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
- return resolve_fl_variable_derived (sym, no_init_flag);
+ {
+ gfc_try res = resolve_fl_variable_derived (sym, no_init_flag);
+ specification_expr = saved_specification_expr;
+ return res;
+ }
+ specification_expr = saved_specification_expr;
return SUCCESS;
}
@@ -12569,6 +12601,7 @@ resolve_symbol (gfc_symbol *sym)
gfc_component *c;
symbol_attribute class_attr;
gfc_array_spec *as;
+ bool saved_specification_expr;
if (sym->attr.artificial)
return;
@@ -12689,7 +12722,12 @@ resolve_symbol (gfc_symbol *sym)
}
}
else if (mp_flag && sym->attr.flavor == FL_PROCEDURE && sym->attr.function)
- gfc_resolve_array_spec (sym->result->as, false);
+ {
+ bool saved_specification_expr = specification_expr;
+ specification_expr = true;
+ gfc_resolve_array_spec (sym->result->as, false);
+ specification_expr = saved_specification_expr;
+ }
if (sym->ts.type == BT_CLASS && sym->attr.class_ok)
{
@@ -13105,7 +13143,10 @@ resolve_symbol (gfc_symbol *sym)
if (sym->attr.function && sym->as)
formal_arg_flag = 1;
+ saved_specification_expr = specification_expr;
+ specification_expr = true;
gfc_resolve_array_spec (sym->as, check_constant);
+ specification_expr = saved_specification_expr;
formal_arg_flag = 0;
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 1178e3d3c..cf9f34672 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -231,12 +231,16 @@ class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
/* Takes a derived type expression and returns the address of a temporary
class object of the 'declared' type. If vptr is not NULL, this is
- used for the temporary class object. */
+ used for the temporary class object.
+ optional_alloc_ptr is false when the dummy is neither allocatable
+ nor a pointer; that's only relevant for the optional handling. */
void
gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
- gfc_typespec class_ts, tree vptr)
+ gfc_typespec class_ts, tree vptr, bool optional,
+ bool optional_alloc_ptr)
{
gfc_symbol *vtab;
+ tree cond_optional = NULL_TREE;
gfc_ss *ss;
tree ctree;
tree var;
@@ -269,13 +273,21 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
/* Now set the data field. */
ctree = gfc_class_data_get (var);
+ if (optional)
+ cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
+
if (parmse->ss && parmse->ss->info->useflags)
{
/* For an array reference in an elemental procedure call we need
to retain the ss to provide the scalarized array reference. */
gfc_conv_expr_reference (parmse, e);
tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
+ if (optional)
+ tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
+ cond_optional, tmp,
+ fold_convert (TREE_TYPE (tmp), null_pointer_node));
gfc_add_modify (&parmse->pre, ctree, tmp);
+
}
else
{
@@ -293,28 +305,145 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
gfc_expr_attr (e));
gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
gfc_get_dtype (type));
+ if (optional)
+ parmse->expr = build3_loc (input_location, COND_EXPR,
+ TREE_TYPE (parmse->expr),
+ cond_optional, parmse->expr,
+ fold_convert (TREE_TYPE (parmse->expr),
+ null_pointer_node));
gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
}
else
{
tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
+ if (optional)
+ tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
+ cond_optional, tmp,
+ fold_convert (TREE_TYPE (tmp),
+ null_pointer_node));
gfc_add_modify (&parmse->pre, ctree, tmp);
}
}
else
{
+ stmtblock_t block;
+ gfc_init_block (&block);
+
parmse->ss = ss;
gfc_conv_expr_descriptor (parmse, e);
if (e->rank != class_ts.u.derived->components->as->rank)
- class_array_data_assign (&parmse->pre, ctree, parmse->expr, true);
+ class_array_data_assign (&block, ctree, parmse->expr, true);
+ else
+ {
+ if (gfc_expr_attr (e).codimension)
+ parmse->expr = fold_build1_loc (input_location,
+ VIEW_CONVERT_EXPR,
+ TREE_TYPE (ctree),
+ parmse->expr);
+ gfc_add_modify (&block, ctree, parmse->expr);
+ }
+
+ if (optional)
+ {
+ tmp = gfc_finish_block (&block);
+
+ gfc_init_block (&block);
+ gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
+
+ tmp = build3_v (COND_EXPR, cond_optional, tmp,
+ gfc_finish_block (&block));
+ gfc_add_expr_to_block (&parmse->pre, tmp);
+ }
else
- gfc_add_modify (&parmse->pre, ctree, parmse->expr);
+ gfc_add_block_to_block (&parmse->pre, &block);
}
}
/* Pass the address of the class object. */
parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
+
+ if (optional && optional_alloc_ptr)
+ parmse->expr = build3_loc (input_location, COND_EXPR,
+ TREE_TYPE (parmse->expr),
+ cond_optional, parmse->expr,
+ fold_convert (TREE_TYPE (parmse->expr),
+ null_pointer_node));
+}
+
+
+/* Create a new class container, which is required as scalar coarrays
+ have an array descriptor while normal scalars haven't. Optionally,
+ NULL pointer checks are added if the argument is OPTIONAL. */
+
+static void
+class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
+ gfc_typespec class_ts, bool optional)
+{
+ tree var, ctree, tmp;
+ stmtblock_t block;
+ gfc_ref *ref;
+ gfc_ref *class_ref;
+
+ gfc_init_block (&block);
+
+ class_ref = NULL;
+ for (ref = e->ref; ref; ref = ref->next)
+ {
+ if (ref->type == REF_COMPONENT
+ && ref->u.c.component->ts.type == BT_CLASS)
+ class_ref = ref;
+ }
+
+ if (class_ref == NULL
+ && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
+ tmp = e->symtree->n.sym->backend_decl;
+ else
+ {
+ /* Remove everything after the last class reference, convert the
+ expression and then recover its tailend once more. */
+ gfc_se tmpse;
+ ref = class_ref->next;
+ class_ref->next = NULL;
+ gfc_init_se (&tmpse, NULL);
+ gfc_conv_expr (&tmpse, e);
+ class_ref->next = ref;
+ tmp = tmpse.expr;
+ }
+
+ var = gfc_typenode_for_spec (&class_ts);
+ var = gfc_create_var (var, "class");
+
+ ctree = gfc_class_vptr_get (var);
+ gfc_add_modify (&block, ctree,
+ fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
+
+ ctree = gfc_class_data_get (var);
+ tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
+ gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
+
+ /* Pass the address of the class object. */
+ parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
+
+ if (optional)
+ {
+ tree cond = gfc_conv_expr_present (e->symtree->n.sym);
+ tree tmp2;
+
+ tmp = gfc_finish_block (&block);
+
+ gfc_init_block (&block);
+ tmp2 = gfc_class_data_get (var);
+ gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
+ null_pointer_node));
+ tmp2 = gfc_finish_block (&block);
+
+ tmp = build3_loc (input_location, COND_EXPR, void_type_node,
+ cond, tmp, tmp2);
+ gfc_add_expr_to_block (&parmse->pre, tmp);
+ }
+ else
+ gfc_add_block_to_block (&parmse->pre, &block);
}
@@ -323,19 +452,29 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
type.
OOP-TODO: This could be improved by adding code that branched on
the dynamic type being the same as the declared type. In this case
- the original class expression can be passed directly. */
+ the original class expression can be passed directly.
+ optional_alloc_ptr is false when the dummy is neither allocatable
+ nor a pointer; that's relevant for the optional handling.
+ Set copyback to true if class container's _data and _vtab pointers
+ might get modified. */
+
void
-gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
- gfc_typespec class_ts, bool elemental)
+gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
+ bool elemental, bool copyback, bool optional,
+ bool optional_alloc_ptr)
{
tree ctree;
tree var;
tree tmp;
tree vptr;
+ tree cond = NULL_TREE;
gfc_ref *ref;
gfc_ref *class_ref;
+ stmtblock_t block;
bool full_array = false;
+ gfc_init_block (&block);
+
class_ref = NULL;
for (ref = e->ref; ref; ref = ref->next)
{
@@ -353,7 +492,11 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
return;
/* Test for FULL_ARRAY. */
- gfc_is_class_array_ref (e, &full_array);
+ if (e->rank == 0 && gfc_expr_attr (e).codimension
+ && gfc_expr_attr (e).dimension)
+ full_array = true;
+ else
+ gfc_is_class_array_ref (e, &full_array);
/* The derived type needs to be converted to a temporary
CLASS object. */
@@ -369,22 +512,30 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
{
tree type = get_scalar_to_descriptor_type (parmse->expr,
gfc_expr_attr (e));
- gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
+ gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
gfc_get_dtype (type));
- gfc_conv_descriptor_data_set (&parmse->pre, ctree,
- gfc_class_data_get (parmse->expr));
+ tmp = gfc_class_data_get (parmse->expr);
+ if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
+ tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+
+ gfc_conv_descriptor_data_set (&block, ctree, tmp);
}
else
- class_array_data_assign (&parmse->pre, ctree, parmse->expr, false);
+ class_array_data_assign (&block, ctree, parmse->expr, false);
}
else
- gfc_add_modify (&parmse->pre, ctree, parmse->expr);
+ {
+ if (CLASS_DATA (e)->attr.codimension)
+ parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
+ TREE_TYPE (ctree), parmse->expr);
+ gfc_add_modify (&block, ctree, parmse->expr);
+ }
/* Return the data component, except in the case of scalarized array
references, where nullification of the cannot occur and so there
is no need. */
- if (!elemental && full_array)
+ if (!elemental && full_array && copyback)
{
if (class_ts.u.derived->components->as
&& e->rank != class_ts.u.derived->components->as->rank)
@@ -429,17 +580,51 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
tmp = build_fold_indirect_ref_loc (input_location, tmp);
vptr = gfc_class_vptr_get (tmp);
- gfc_add_modify (&parmse->pre, ctree,
+ gfc_add_modify (&block, ctree,
fold_convert (TREE_TYPE (ctree), vptr));
/* Return the vptr component, except in the case of scalarized array
references, where the dynamic type cannot change. */
- if (!elemental && full_array)
+ if (!elemental && full_array && copyback)
gfc_add_modify (&parmse->post, vptr,
fold_convert (TREE_TYPE (vptr), ctree));
+ gcc_assert (!optional || (optional && !copyback));
+ if (optional)
+ {
+ tree tmp2;
+
+ cond = gfc_conv_expr_present (e->symtree->n.sym);
+ tmp = gfc_finish_block (&block);
+
+ if (optional_alloc_ptr)
+ tmp2 = build_empty_stmt (input_location);
+ else
+ {
+ gfc_init_block (&block);
+
+ tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
+ gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
+ null_pointer_node));
+ tmp2 = gfc_finish_block (&block);
+ }
+
+ tmp = build3_loc (input_location, COND_EXPR, void_type_node,
+ cond, tmp, tmp2);
+ gfc_add_expr_to_block (&parmse->pre, tmp);
+ }
+ else
+ gfc_add_block_to_block (&parmse->pre, &block);
+
/* Pass the address of the class object. */
parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
+
+ if (optional && optional_alloc_ptr)
+ parmse->expr = build3_loc (input_location, COND_EXPR,
+ TREE_TYPE (parmse->expr),
+ cond, parmse->expr,
+ fold_convert (TREE_TYPE (parmse->expr),
+ null_pointer_node));
}
@@ -857,19 +1042,43 @@ gfc_conv_expr_present (gfc_symbol * sym)
/* Fortran 2008 allows to pass null pointers and non-associated pointers
as actual argument to denote absent dummies. For array descriptors,
- we thus also need to check the array descriptor. */
- if (!sym->attr.pointer && !sym->attr.allocatable
- && sym->as && (sym->as->type == AS_ASSUMED_SHAPE
- || sym->as->type == AS_ASSUMED_RANK)
- && (gfc_option.allow_std & GFC_STD_F2008) != 0)
+ we thus also need to check the array descriptor. For BT_CLASS, it
+ can also occur for scalars and F2003 due to type->class wrapping and
+ class->class wrapping. Note futher that BT_CLASS always uses an
+ array descriptor for arrays, also for explicit-shape/assumed-size. */
+
+ if (!sym->attr.allocatable
+ && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
+ || (sym->ts.type == BT_CLASS
+ && !CLASS_DATA (sym)->attr.allocatable
+ && !CLASS_DATA (sym)->attr.class_pointer))
+ && ((gfc_option.allow_std & GFC_STD_F2008) != 0
+ || sym->ts.type == BT_CLASS))
{
tree tmp;
- tmp = build_fold_indirect_ref_loc (input_location, decl);
- tmp = gfc_conv_array_data (tmp);
- tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
- fold_convert (TREE_TYPE (tmp), null_pointer_node));
- cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
- boolean_type_node, cond, tmp);
+
+ if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
+ || sym->as->type == AS_ASSUMED_RANK
+ || sym->attr.codimension))
+ || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
+ {
+ tmp = build_fold_indirect_ref_loc (input_location, decl);
+ if (sym->ts.type == BT_CLASS)
+ tmp = gfc_class_data_get (tmp);
+ tmp = gfc_conv_array_data (tmp);
+ }
+ else if (sym->ts.type == BT_CLASS)
+ tmp = gfc_class_data_get (decl);
+ else
+ tmp = NULL_TREE;
+
+ if (tmp != NULL_TREE)
+ {
+ tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
+ fold_convert (TREE_TYPE (tmp), null_pointer_node));
+ cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
+ boolean_type_node, cond, tmp);
+ }
}
return cond;
@@ -3714,7 +3923,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
if (e && e->expr_type == EXPR_VARIABLE
&& !e->ref
&& e->ts.type == BT_CLASS
- && CLASS_DATA (e)->attr.dimension)
+ && (CLASS_DATA (e)->attr.codimension
+ || CLASS_DATA (e)->attr.dimension))
{
gfc_typespec temp_ts = e->ts;
gfc_add_class_array_ref (e);
@@ -3763,7 +3973,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* The derived type needs to be converted to a temporary
CLASS object. */
gfc_init_se (&parmse, se);
- gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL);
+ gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
+ fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.optional,
+ CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable);
}
else if (se->ss && se->ss->info->useflags)
{
@@ -3789,7 +4004,20 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
if (fsym && fsym->ts.type == BT_DERIVED
&& gfc_is_class_container_ref (e))
- parmse.expr = gfc_class_data_get (parmse.expr);
+ {
+ parmse.expr = gfc_class_data_get (parmse.expr);
+
+ if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.optional)
+ {
+ tree cond = gfc_conv_expr_present (e->symtree->n.sym);
+ parmse.expr = build3_loc (input_location, COND_EXPR,
+ TREE_TYPE (parmse.expr),
+ cond, parmse.expr,
+ fold_convert (TREE_TYPE (parmse.expr),
+ null_pointer_node));
+ }
+ }
/* If we are passing an absent array as optional dummy to an
elemental procedure, make sure that we pass NULL when the data
@@ -3817,13 +4045,23 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* The scalarizer does not repackage the reference to a class
array - instead it returns a pointer to the data element. */
if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
- gfc_conv_class_to_class (&parmse, e, fsym->ts, true);
+ gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
+ fsym->attr.intent != INTENT_IN
+ && (CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable),
+ fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.optional,
+ CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable);
}
else
{
bool scalar;
gfc_ss *argss;
+ gfc_init_se (&parmse, NULL);
+
/* Check whether the expression is a scalar or not; we cannot use
e->rank as it can be nonzero for functions arguments. */
argss = gfc_walk_expr (e);
@@ -3831,9 +4069,19 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
if (!scalar)
gfc_free_ss_chain (argss);
+ /* Special handling for passing scalar polymorphic coarrays;
+ otherwise one passes "class->_data.data" instead of "&class". */
+ if (e->rank == 0 && e->ts.type == BT_CLASS
+ && fsym && fsym->ts.type == BT_CLASS
+ && CLASS_DATA (fsym)->attr.codimension
+ && !CLASS_DATA (fsym)->attr.dimension)
+ {
+ gfc_add_class_array_ref (e);
+ parmse.want_coarray = 1;
+ scalar = false;
+ }
+
/* A scalar or transformational function. */
- gfc_init_se (&parmse, NULL);
-
if (scalar)
{
if (e->expr_type == EXPR_VARIABLE
@@ -3888,7 +4136,23 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
else
{
- gfc_conv_expr_reference (&parmse, e);
+ if (e->ts.type == BT_CLASS && fsym
+ && fsym->ts.type == BT_CLASS
+ && (!CLASS_DATA (fsym)->as
+ || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
+ && CLASS_DATA (e)->attr.codimension)
+ {
+ gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
+ gcc_assert (!CLASS_DATA (fsym)->as);
+ gfc_add_class_array_ref (e);
+ parmse.want_coarray = 1;
+ gfc_conv_expr_reference (&parmse, e);
+ class_scalar_coarray_to_class (&parmse, e, fsym->ts,
+ fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE);
+ }
+ else
+ gfc_conv_expr_reference (&parmse, e);
/* Catch base objects that are not variables. */
if (e->ts.type == BT_CLASS
@@ -3904,7 +4168,15 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
&& ((CLASS_DATA (fsym)->as
&& CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
|| CLASS_DATA (e)->attr.dimension))
- gfc_conv_class_to_class (&parmse, e, fsym->ts, false);
+ gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
+ fsym->attr.intent != INTENT_IN
+ && (CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable),
+ fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.optional,
+ CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable);
if (fsym && (fsym->ts.type == BT_DERIVED
|| fsym->ts.type == BT_ASSUMED)
@@ -4005,14 +4277,22 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
else if (e->ts.type == BT_CLASS
&& fsym && fsym->ts.type == BT_CLASS
- && CLASS_DATA (fsym)->attr.dimension)
+ && (CLASS_DATA (fsym)->attr.dimension
+ || CLASS_DATA (fsym)->attr.codimension))
{
/* Pass a class array. */
- gfc_init_se (&parmse, se);
gfc_conv_expr_descriptor (&parmse, e);
/* The conversion does not repackage the reference to a class
array - _data descriptor. */
- gfc_conv_class_to_class (&parmse, e, fsym->ts, false);
+ gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
+ fsym->attr.intent != INTENT_IN
+ && (CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable),
+ fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.optional,
+ CLASS_DATA (fsym)->attr.class_pointer
+ || CLASS_DATA (fsym)->attr.allocatable);
}
else
{
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index bfcb6869b..b95c8dae7 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1228,7 +1228,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
gfc_conv_expr_descriptor (&se, e);
/* Obtain a temporary class container for the result. */
- gfc_conv_class_to_class (&se, e, sym->ts, false);
+ gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
/* Set the offset. */
@@ -1255,7 +1255,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
/* Get the _vptr component of the class object. */
tmp = gfc_get_vptr_from_expr (se.expr);
/* Obtain a temporary class container for the result. */
- gfc_conv_derived_to_class (&se, e, sym->ts, tmp);
+ gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
}
else
@@ -4874,7 +4874,7 @@ gfc_trans_allocate (gfc_code * code)
gfc_init_se (&se_sz, NULL);
gfc_conv_expr_reference (&se_sz, code->expr3);
gfc_conv_class_to_class (&se_sz, code->expr3,
- code->expr3->ts, false);
+ code->expr3->ts, false, true, false, false);
gfc_add_block_to_block (&se.pre, &se_sz.pre);
gfc_add_block_to_block (&se.post, &se_sz.post);
classexpr = build_fold_indirect_ref_loc (input_location,
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 9818ceb1f..7e6d58c1b 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -351,8 +351,10 @@ tree gfc_vtable_copy_get (tree);
tree gfc_get_vptr_from_expr (tree);
tree gfc_get_class_array_ref (tree, tree);
tree gfc_copy_class_to_class (tree, tree, tree);
-void gfc_conv_derived_to_class (gfc_se *, gfc_expr *, gfc_typespec, tree);
-void gfc_conv_class_to_class (gfc_se *, gfc_expr *, gfc_typespec, bool);
+void gfc_conv_derived_to_class (gfc_se *, gfc_expr *, gfc_typespec, tree, bool,
+ bool);
+void gfc_conv_class_to_class (gfc_se *, gfc_expr *, gfc_typespec, bool, bool,
+ bool, bool);
/* Initialize an init/cleanup block. */
void gfc_start_wrapped_block (gfc_wrapped_block* block, tree code);
diff --git a/gcc/gcse.c b/gcc/gcse.c
index a066b36c6..138150b19 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1519,9 +1519,10 @@ compute_hash_table_work (struct hash_table_d *table)
if (CALL_P (insn))
{
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
- record_last_reg_set_info (insn, regno);
+ hard_reg_set_iterator hrsi;
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call,
+ 0, regno, hrsi)
+ record_last_reg_set_info (insn, regno);
if (! RTL_CONST_OR_PURE_CALL_P (insn))
record_last_mem_set_info (insn);
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 2c6104cb2..d736d2c02 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -1,6 +1,6 @@
/* Generate code from to output assembler insns as recognized from rtl.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
- 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2012
+ 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -662,19 +662,55 @@ process_template (struct data *d, const char *template_code)
list of assembler code templates, one for each alternative. */
else if (template_code[0] == '@')
{
- d->template_code = 0;
- d->output_format = INSN_OUTPUT_FORMAT_MULTI;
+ int found_star = 0;
- printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
+ for (cp = &template_code[1]; *cp; )
+ {
+ while (ISSPACE (*cp))
+ cp++;
+ if (*cp == '*')
+ found_star = 1;
+ while (!IS_VSPACE (*cp) && *cp != '\0')
+ ++cp;
+ }
+ d->template_code = 0;
+ if (found_star)
+ {
+ d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
+ puts ("\nstatic const char *");
+ printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
+ "rtx insn ATTRIBUTE_UNUSED)\n", d->code_number);
+ puts ("{");
+ puts (" switch (which_alternative)\n {");
+ }
+ else
+ {
+ d->output_format = INSN_OUTPUT_FORMAT_MULTI;
+ printf ("\nstatic const char * const output_%d[] = {\n",
+ d->code_number);
+ }
for (i = 0, cp = &template_code[1]; *cp; )
{
- const char *ep, *sp;
+ const char *ep, *sp, *bp;
while (ISSPACE (*cp))
cp++;
- printf (" \"");
+ bp = cp;
+ if (found_star)
+ {
+ printf (" case %d:", i);
+ if (*cp == '*')
+ {
+ printf ("\n ");
+ cp++;
+ }
+ else
+ printf (" return \"");
+ }
+ else
+ printf (" \"");
for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
if (!ISSPACE (*ep))
@@ -690,7 +726,18 @@ process_template (struct data *d, const char *template_code)
cp++;
}
- printf ("\",\n");
+ if (!found_star)
+ puts ("\",");
+ else if (*bp != '*')
+ puts ("\";");
+ else
+ {
+ /* The usual action will end with a return.
+ If there is neither break or return at the end, this is
+ assumed to be intentional; this allows to have multiple
+ consecutive alternatives share some code. */
+ puts ("");
+ }
i++;
}
if (i == 1)
@@ -700,7 +747,10 @@ process_template (struct data *d, const char *template_code)
error_with_line (d->lineno,
"wrong number of alternatives in the output template");
- printf ("};\n");
+ if (found_star)
+ puts (" default: gcc_unreachable ();\n }\n}");
+ else
+ printf ("};\n");
}
else
{
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index b83a6346e..14e7007e5 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -116,6 +116,19 @@ mark_addressable (tree x)
&& TREE_CODE (x) != RESULT_DECL)
return;
TREE_ADDRESSABLE (x) = 1;
+
+ /* Also mark the artificial SSA_NAME that points to the partition of X. */
+ if (TREE_CODE (x) == VAR_DECL
+ && !DECL_EXTERNAL (x)
+ && !TREE_STATIC (x)
+ && cfun->gimple_df != NULL
+ && cfun->gimple_df->decls_to_pointers != NULL)
+ {
+ void *namep
+ = pointer_map_contains (cfun->gimple_df->decls_to_pointers, x);
+ if (namep)
+ TREE_ADDRESSABLE (*(tree *)namep) = 1;
+ }
}
/* Return a hash value for a formal temporary table entry. */
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 2f486a231..5654c6675 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2415,7 +2415,7 @@ noce_can_store_speculate_p (basic_block top_bb, const_rtx mem)
|| (CALL_P (insn) && (!RTL_CONST_CALL_P (insn)))))
return false;
- if (memory_modified_in_insn_p (mem, insn))
+ if (memory_must_be_modified_in_insn_p (mem, insn))
return true;
if (modified_in_p (XEXP (mem, 0), insn))
return false;
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 8dcfea5bb..3ab19cae9 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -1,5 +1,5 @@
/* Perform doloop optimizations
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012
Free Software Foundation, Inc.
Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
@@ -561,7 +561,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
init = gen_doloop_begin (counter_reg,
desc->const_iter ? desc->niter_expr : const0_rtx,
iter_rtx,
- GEN_INT (level));
+ GEN_INT (level),
+ doloop_seq);
if (init)
{
start_sequence ();
@@ -619,6 +620,7 @@ doloop_optimize (struct loop *loop)
unsigned word_mode_size;
unsigned HOST_WIDE_INT word_mode_max;
double_int iter;
+ int entered_at_top;
if (dump_file)
fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
@@ -681,8 +683,11 @@ doloop_optimize (struct loop *loop)
not like. */
start_label = block_label (desc->in_edge->dest);
doloop_reg = gen_reg_rtx (mode);
+ entered_at_top = (loop->latch == desc->in_edge->dest
+ && contains_no_active_insn_p (loop->latch));
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
- GEN_INT (level), start_label);
+ GEN_INT (level), start_label,
+ GEN_INT (entered_at_top));
word_mode_size = GET_MODE_PRECISION (word_mode);
word_mode_max
@@ -712,7 +717,8 @@ doloop_optimize (struct loop *loop)
}
PUT_MODE (doloop_reg, word_mode);
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
- GEN_INT (level), start_label);
+ GEN_INT (level), start_label,
+ GEN_INT (entered_at_top));
}
if (! doloop_seq)
{
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index a420569fd..854b41c2e 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "expr.h"
#include "recog.h"
+#include "target.h"
#include "function.h"
#include "flags.h"
#include "df.h"
@@ -784,7 +785,22 @@ check_dependency (basic_block bb, df_ref use, bitmap depends_on)
defs = DF_REF_CHAIN (use);
if (!defs)
- return true;
+ {
+ unsigned int regno = DF_REF_REGNO (use);
+
+ /* If this is the use of an uninitialized argument register that is
+ likely to be spilled, do not move it lest this might extend its
+ lifetime and cause reload to die. This can occur for a call to
+ a function taking complex number arguments and moving the insns
+ preparing the arguments without moving the call itself wouldn't
+ gain much in practice. */
+ if ((DF_REF_FLAGS (use) & DF_HARD_REG_LIVE)
+ && FUNCTION_ARG_REGNO_P (regno)
+ && targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno)))
+ return false;
+
+ return true;
+ }
if (defs->next)
return false;
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 4619c626b..43d3c4e3e 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -1964,12 +1964,12 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
note_stores (PATTERN (insn), mark_altered, this_altered);
if (CALL_P (insn))
{
- int i;
-
/* Kill all call clobbered registers. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
- SET_REGNO_REG_SET (this_altered, i);
+ unsigned int i;
+ hard_reg_set_iterator hrsi;
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call,
+ 0, i, hrsi)
+ SET_REGNO_REG_SET (this_altered, i);
}
if (suitable_set_for_replacement (insn, &dest, &src))
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index 4107048de..25d77dab2 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -454,6 +454,7 @@ unswitch_loop (struct loop *loop, basic_block unswitch_on, rtx cond, rtx cinsn)
BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true,
prob, REG_BR_PROB_BASE - prob);
+ copy_loop_info (loop, nloop);
/* Remove branches that are now unreachable in new loops. */
remove_path (true_edge);
remove_path (false_edge);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index a5d13eec5..15905f859 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1086,9 +1086,9 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
the code and class. */
result = streamer_get_builtin_tree (ib, data_in);
}
- else if (tag == lto_tree_code_to_tag (INTEGER_CST))
+ else if (tag == LTO_integer_cst)
{
- /* For integer constants we only need the type and its hi/low
+ /* For shared integer constants we only need the type and its hi/low
words. */
result = streamer_read_integer_cst (ib, data_in);
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 55a20dd13..806045b52 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -372,9 +372,10 @@ lto_output_tree (struct output_block *ob, tree expr,
return;
}
- /* INTEGER_CST nodes are special because they need their original type
+ /* Shared INTEGER_CST nodes are special because they need their original type
to be materialized by the reader (to implement TYPE_CACHED_VALUES). */
- if (TREE_CODE (expr) == INTEGER_CST)
+ if (TREE_CODE (expr) == INTEGER_CST
+ && !TREE_OVERFLOW (expr))
{
streamer_write_integer_cst (ob, expr, ref_p);
return;
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index c7b7ef948..c9d13aea4 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -175,6 +175,9 @@ enum LTO_tags
/* An MD or NORMAL builtin. Only the code and class are streamed out. */
LTO_builtin_decl,
+ /* Shared INTEGER_CST node. */
+ LTO_integer_cst,
+
/* Function body. */
LTO_function,
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
index 8b025b2cf..13de5e48e 100644
--- a/gcc/opt-functions.awk
+++ b/gcc/opt-functions.awk
@@ -297,3 +297,19 @@ function lang_sanitized_name(name)
gsub( "[^" alnum "_]", "X", name )
return name
}
+
+# Search for a valid var_name among all OPTS equal to option NAME.
+# If not found, return "".
+function search_var_name(name, opt_numbers, opts, flags, n_opts)
+{
+ opt_var_name = var_name(flags[opt_numbers[name]]);
+ if (opt_var_name != "") {
+ return opt_var_name;
+ }
+ for (k = 0; k < n_opts; k++) {
+ if (opts[k] == name && var_name(flags[k]) != "") {
+ return var_name(flags[k]);
+ }
+ }
+ return ""
+}
diff --git a/gcc/optabs.c b/gcc/optabs.c
index a63394d13..e22031615 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4249,11 +4249,12 @@ prepare_operand (enum insn_code icode, rtx x, int opnum, enum machine_mode mode,
we can do the branch. */
static void
-emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label)
+emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label, int prob)
{
enum machine_mode optab_mode;
enum mode_class mclass;
enum insn_code icode;
+ rtx insn;
mclass = GET_MODE_CLASS (mode);
optab_mode = (mclass == MODE_CC) ? CCmode : mode;
@@ -4261,7 +4262,17 @@ emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label)
gcc_assert (icode != CODE_FOR_nothing);
gcc_assert (insn_operand_matches (icode, 0, test));
- emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0), XEXP (test, 1), label));
+ insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
+ XEXP (test, 1), label));
+ if (prob != -1
+ && profile_status != PROFILE_ABSENT
+ && insn
+ && JUMP_P (insn)
+ && any_condjump_p (insn))
+ {
+ gcc_assert (!find_reg_note (insn, REG_BR_PROB, 0));
+ add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
+ }
}
/* Generate code to compare X with Y so that the condition codes are
@@ -4279,11 +4290,14 @@ emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label)
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
It will be potentially converted into an unsigned variant based on
- UNSIGNEDP to select a proper jump instruction. */
+ UNSIGNEDP to select a proper jump instruction.
+
+ PROB is the probability of jumping to LABEL. */
void
emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
- enum machine_mode mode, int unsignedp, rtx label)
+ enum machine_mode mode, int unsignedp, rtx label,
+ int prob)
{
rtx op0 = x, op1 = y;
rtx test;
@@ -4307,7 +4321,7 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
&test, &mode);
- emit_cmp_and_jump_insn_1 (test, mode, label);
+ emit_cmp_and_jump_insn_1 (test, mode, label, prob);
}
@@ -6952,9 +6966,9 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
if (oldval != cmp_reg)
emit_move_insn (cmp_reg, oldval);
- /* ??? Mark this jump predicted not taken? */
+ /* Mark this jump predicted not taken. */
emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
- GET_MODE (success), 1, label);
+ GET_MODE (success), 1, label, 0);
return true;
}
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 0abe6bcf2..87575c22a 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -39,16 +39,35 @@ for (i = 0; i < n_langs; i++) {
for (i = 0; i < n_opts; i++) {
enabledby_arg = opt_args("EnabledBy", flags[i]);
if (enabledby_arg != "") {
- enabledby_name = enabledby_arg;
- enabledby_index = opt_numbers[enabledby_name];
- if (enabledby_index == "") {
- print "#error Enabledby: " enabledby_name
- } else {
- if (enables[enabledby_name] == "") {
- enabledby[n_enabledby] = enabledby_name;
- n_enabledby++;
+ n_enabledby_names = split(enabledby_arg, enabledby_names, " && ");
+ if (n_enabledby_names > 2) {
+ print "#error EnabledBy (Wfoo && Wbar && Wbaz) not currently supported"
+ }
+ for (j = 1; j <= n_enabledby_names; j++) {
+ enabledby_name = enabledby_names[j];
+ enabledby_index = opt_numbers[enabledby_name];
+ if (enabledby_index == "") {
+ print "#error Enabledby: " enabledby_name
+ } else {
+ condition = "";
+ if (n_enabledby_names == 2) {
+ opt_var_name_1 = search_var_name(enabledby_names[1], opt_numbers, opts, flags, n_opts);
+ opt_var_name_2 = search_var_name(enabledby_names[2], opt_numbers, opts, flags, n_opts);
+ if (opt_var_name_1 == "") {
+ print "#error " enabledby_names[1] " does not have a Var() flag"
+ }
+ if (opt_var_name_2 == "") {
+ print "#error " enabledby_names[2] " does not have a Var() flag"
+ }
+ condition = "opts->x_" opt_var_name_1 " && opts->x_" opt_var_name_2;
+ }
+ if (enables[enabledby_name] == "") {
+ enabledby[n_enabledby] = enabledby_name;
+ n_enabledby++;
+ }
+ enables[enabledby_name] = enables[enabledby_name] opts[i] ";";
+ enablesif[enabledby_name] = enablesif[enabledby_name] condition ";";
}
- enables[enabledby_name] = enables[enabledby_name] opts[i] ",";
}
}
@@ -56,10 +75,20 @@ for (i = 0; i < n_opts; i++) {
if (enabledby_arg != "") {
n_enabledby_arg_langs = split(nth_arg(0, enabledby_arg), enabledby_arg_langs, " ");
enabledby_name = nth_arg(1, enabledby_arg);
+ enabledby_posarg = nth_arg(2, enabledby_arg)
+ enabledby_negarg = nth_arg(3, enabledby_arg)
enabledby_index = opt_numbers[enabledby_name];
if (enabledby_index == "") {
- print "#error Enabledby: " enabledby_name
+ print "#error LangEnabledby: " enabledby_name
} else {
+ if (enabledby_posarg != "" && enabledby_negarg != "") {
+ with_args = "," enabledby_posarg "," enabledby_negarg
+ } else if (enabledby_posarg == "" && enabledby_negarg == "") {
+ with_args = ""
+ } else {
+ print "#error LangEnabledBy with three arguments, it should have either 2 or 4"
+ }
+
for (j = 1; j <= n_enabledby_arg_langs; j++) {
lang_name = lang_sanitized_name(enabledby_arg_langs[j]);
lang_index = lang_numbers[enabledby_arg_langs[j]];
@@ -67,7 +96,7 @@ for (i = 0; i < n_opts; i++) {
enabledby[lang_name,n_enabledby_lang[lang_index]] = enabledby_name;
n_enabledby_lang[lang_index]++;
}
- enables[lang_name,enabledby_name] = enables[lang_name,enabledby_name] opts[i] ",";
+ enables[lang_name,enabledby_name] = enables[lang_name,enabledby_name] opts[i] with_args ";";
}
}
}
@@ -385,14 +414,23 @@ print " gcc_assert (decoded->canonical_option_num_elements <= 2); "
print " "
print " switch (code) "
print " { "
+# Handle EnabledBy
for (i = 0; i < n_enabledby; i++) {
enabledby_name = enabledby[i];
print " case " opt_enum(enabledby_name) ":"
- n_enables = split(enables[enabledby_name], thisenable, ",");
+ n_enables = split(enables[enabledby_name], thisenable, ";");
+ n_enablesif = split(enablesif[enabledby_name], thisenableif, ";");
+ if (n_enables != n_enablesif) {
+ print "#error n_enables != n_enablesif: Something went wrong!"
+ }
for (j = 1; j < n_enables; j++) {
opt_var_name = var_name(flags[opt_numbers[thisenable[j]]]);
if (opt_var_name != "") {
- print " if (!opts_set->x_" opt_var_name ")"
+ condition = "!opts_set->x_" opt_var_name
+ if (thisenableif[j] != "") {
+ condition = condition " && (" thisenableif[j] ")"
+ }
+ print " if (" condition ")"
print " handle_generated_option (opts, opts_set,"
print " " opt_enum(thisenable[j]) ", NULL, value,"
print " lang_mask, kind, loc, handlers, dc);"
@@ -431,16 +469,26 @@ for (i = 0; i < n_langs; i++) {
for (k = 0; k < n_enabledby_lang[i]; k++) {
enabledby_name = enabledby[lang_name,k];
print " case " opt_enum(enabledby_name) ":"
- n_enables = split(enables[lang_name,enabledby_name], thisenable, ",");
- for (j = 1; j < n_enables; j++) {
- opt_var_name = var_name(flags[opt_numbers[thisenable[j]]]);
+ n_thisenable = split(enables[lang_name,enabledby_name], thisenable, ";");
+ for (j = 1; j < n_thisenable; j++) {
+ n_thisenable_args = split(thisenable[j], thisenable_args, ",");
+ if (n_thisenable_args == 1) {
+ thisenable_opt = thisenable[j];
+ value = "value";
+ } else {
+ thisenable_opt = thisenable_args[1];
+ with_posarg = thisenable_args[2];
+ with_negarg = thisenable_args[3];
+ value = "value ? " with_posarg " : " with_negarg;
+ }
+ opt_var_name = var_name(flags[opt_numbers[thisenable_opt]]);
if (opt_var_name != "") {
print " if (!opts_set->x_" opt_var_name ")"
print " handle_generated_option (opts, opts_set,"
- print " " opt_enum(thisenable[j]) ", arg, value,"
+ print " " opt_enum(thisenable_opt) ", NULL, " value ","
print " lang_mask, kind, loc, handlers, dc);"
} else {
- print "#error " thisenable[j] " does not have a Var() flag"
+ print "#error " thisenable_opt " does not have a Var() flag"
}
}
print " break;\n"
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index 8e583f030..e98a66f5b 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -375,15 +375,13 @@ for (i = 0; i < n_opts; i++) {
if (name != "" && mask_macros[name] == 0) {
mask_macros[name] = 1
vname = var_name(flags[i])
- macro = "OPTION_"
mask = "OPTION_MASK_"
if (vname == "") {
vname = "target_flags"
- macro = "TARGET_"
mask = "MASK_"
extra_mask_macros[name] = 1
}
- print "#define " macro name \
+ print "#define TARGET_" name \
" ((" vname " & " mask name ") != 0)"
}
}
@@ -398,14 +396,12 @@ for (i = 0; i < n_opts; i++) {
opt = opt_args("InverseMask", flags[i])
if (opt ~ ",") {
vname = var_name(flags[i])
- macro = "OPTION_"
mask = "OPTION_MASK_"
if (vname == "") {
vname = "target_flags"
- macro = "TARGET_"
mask = "MASK_"
}
- print "#define " macro nth_arg(1, opt) \
+ print "#define TARGET_" nth_arg(1, opt) \
" ((" vname " & " mask nth_arg(0, opt) ") == 0)"
}
}
diff --git a/gcc/opts.c b/gcc/opts.c
index ccfe3c70a..98bbd302c 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
#include "insn-attr-common.h"
#include "common/common-target.h"
+static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
+
/* Indexed by enum debug_info_type. */
const char *const debug_type_names[] =
{
@@ -828,15 +830,6 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
opts->x_param_values, opts_set->x_param_values);
/* This replaces set_Wunused. */
- /* Wunused-parameter is enabled if both -Wunused -Wextra are enabled. */
- if (opts->x_warn_unused_parameter == -1)
- opts->x_warn_unused_parameter = (opts->x_warn_unused
- && opts->x_extra_warnings);
- /* Wunused-but-set-parameter is enabled if both -Wunused -Wextra are
- enabled. */
- if (opts->x_warn_unused_but_set_parameter == -1)
- opts->x_warn_unused_but_set_parameter = (opts->x_warn_unused
- && opts->x_extra_warnings);
/* Wunused-local-typedefs is enabled by -Wunused or -Wall. */
if (opts->x_warn_unused_local_typedefs == -1)
opts->x_warn_unused_local_typedefs = opts->x_warn_unused;
@@ -1801,7 +1794,7 @@ handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
and 0 otherwise. After calling this function, wstrict_aliasing will be
set to the default value of -Wstrict_aliasing=level, currently 3. */
-void
+static void
set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
{
gcc_assert (onoff == 0 || onoff == 1);
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index b464d1fdc..ab4f851b7 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -736,10 +736,9 @@ record_opr_changes (rtx insn)
{
unsigned int regno;
rtx link, x;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
- record_last_reg_set_info_regno (insn, regno);
+ hard_reg_set_iterator hrsi;
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi)
+ record_last_reg_set_info_regno (insn, regno);
for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
if (GET_CODE (XEXP (link, 0)) == CLOBBER)
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index 744878d8e..3cda1a7c2 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -990,9 +990,12 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
/* Clobber call-clobbered registers. */
if (CALL_P (insn))
{
- int set_regno = INVALID_REGNUM;
- int set_nregs = 0;
+ unsigned int set_regno = INVALID_REGNUM;
+ unsigned int set_nregs = 0;
+ unsigned int regno;
rtx exp;
+ hard_reg_set_iterator hrsi;
+
for (exp = CALL_INSN_FUNCTION_USAGE (insn); exp; exp = XEXP (exp, 1))
{
rtx x = XEXP (exp, 0);
@@ -1009,10 +1012,10 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
break;
}
}
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
- && (i < set_regno || i >= set_regno + set_nregs))
- kill_value_regno (i, 1, vd);
+
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi)
+ if (regno < set_regno || regno >= set_regno + set_nregs)
+ kill_value_regno (regno, 1, vd);
}
/* Notice stores. */
diff --git a/gcc/reload.c b/gcc/reload.c
index 2e41ed649..91521b163 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -282,7 +282,7 @@ static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int,
static void find_reloads_address_part (rtx, rtx *, enum reg_class,
enum machine_mode, int,
enum reload_type, int);
-static rtx find_reloads_subreg_address (rtx, int, int, enum reload_type,
+static rtx find_reloads_subreg_address (rtx, int, enum reload_type,
int, rtx, int *);
static void copy_replacements_1 (rtx *, rtx *, int);
static int find_inc_amount (rtx, rtx);
@@ -4810,31 +4810,19 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
}
/* If the subreg contains a reg that will be converted to a mem,
- convert the subreg to a narrower memref now.
- Otherwise, we would get (subreg (mem ...) ...),
- which would force reload of the mem.
-
- We also need to do this if there is an equivalent MEM that is
- not offsettable. In that case, alter_subreg would produce an
- invalid address on big-endian machines.
-
- For machines that extend byte loads, we must not reload using
- a wider mode if we have a paradoxical SUBREG. find_reloads will
- force a reload in that case. So we should not do anything here. */
+ attempt to convert the whole subreg to a (narrower or wider)
+ memory reference instead. If this succeeds, we're done --
+ otherwise fall through to check whether the inner reg still
+ needs address reloads anyway. */
if (regno >= FIRST_PSEUDO_REGISTER
-#ifdef LOAD_EXTEND_OP
- && !paradoxical_subreg_p (x)
-#endif
- && (reg_equiv_address (regno) != 0
- || (reg_equiv_mem (regno) != 0
- && (! strict_memory_address_addr_space_p
- (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
- MEM_ADDR_SPACE (reg_equiv_mem (regno)))
- || ! offsettable_memref_p (reg_equiv_mem (regno))
- || num_not_at_initial_offset))))
- x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
- insn, address_reloaded);
+ && reg_equiv_memory_loc (regno) != 0)
+ {
+ tem = find_reloads_subreg_address (x, opnum, type, ind_levels,
+ insn, address_reloaded);
+ if (tem)
+ return tem;
+ }
}
for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@@ -6070,12 +6058,31 @@ find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
if (ira_reg_class_max_nregs [rclass][GET_MODE (SUBREG_REG (x))]
> reg_class_size[(int) rclass])
{
- x = find_reloads_subreg_address (x, 0, opnum,
- ADDR_TYPE (type),
- ind_levels, insn, NULL);
- push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
- GET_MODE (x), VOIDmode, 0, 0, opnum, type);
- return 1;
+ /* If the inner register will be replaced by a memory
+ reference, we can do this only if we can replace the
+ whole subreg by a (narrower) memory reference. If
+ this is not possible, fall through and reload just
+ the inner register (including address reloads). */
+ if (reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
+ {
+ rtx tem = find_reloads_subreg_address (x, opnum,
+ ADDR_TYPE (type),
+ ind_levels, insn,
+ NULL);
+ if (tem)
+ {
+ push_reload (tem, NULL_RTX, loc, (rtx*) 0, rclass,
+ GET_MODE (tem), VOIDmode, 0, 0,
+ opnum, type);
+ return 1;
+ }
+ }
+ else
+ {
+ push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
+ GET_MODE (x), VOIDmode, 0, 0, opnum, type);
+ return 1;
+ }
}
}
}
@@ -6152,17 +6159,12 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
}
/* X, a subreg of a pseudo, is a part of an address that needs to be
- reloaded.
-
- If the pseudo is equivalent to a memory location that cannot be directly
- addressed, make the necessary address reloads.
+ reloaded, and the pseusdo is equivalent to a memory location.
- If address reloads have been necessary, or if the address is changed
- by register elimination, return the rtx of the memory location;
- otherwise, return X.
-
- If FORCE_REPLACE is nonzero, unconditionally replace the subreg with the
- memory location.
+ Attempt to replace the whole subreg by a (possibly narrower or wider)
+ memory reference. If this is possible, return this new memory
+ reference, and push all required address reloads. Otherwise,
+ return NULL.
OPNUM and TYPE identify the purpose of the reload.
@@ -6174,131 +6176,106 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
stack slots. */
static rtx
-find_reloads_subreg_address (rtx x, int force_replace, int opnum,
- enum reload_type type, int ind_levels, rtx insn,
- int *address_reloaded)
+find_reloads_subreg_address (rtx x, int opnum, enum reload_type type,
+ int ind_levels, rtx insn, int *address_reloaded)
{
+ enum machine_mode outer_mode = GET_MODE (x);
+ enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
int regno = REGNO (SUBREG_REG (x));
int reloaded = 0;
+ rtx tem, orig;
+ int offset;
- if (reg_equiv_memory_loc (regno))
- {
- /* If the address is not directly addressable, or if the address is not
- offsettable, then it must be replaced. */
- if (! force_replace
- && (reg_equiv_address (regno)
- || ! offsettable_memref_p (reg_equiv_mem (regno))))
- force_replace = 1;
-
- if (force_replace || num_not_at_initial_offset)
- {
- rtx tem = make_memloc (SUBREG_REG (x), regno);
+ gcc_assert (reg_equiv_memory_loc (regno) != 0);
- /* If the address changes because of register elimination, then
- it must be replaced. */
- if (force_replace
- || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
- {
- unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
- unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
- int offset;
- rtx orig = tem;
-
- /* For big-endian paradoxical subregs, SUBREG_BYTE does not
- hold the correct (negative) byte offset. */
- if (BYTES_BIG_ENDIAN && outer_size > inner_size)
- offset = inner_size - outer_size;
- else
- offset = SUBREG_BYTE (x);
-
- XEXP (tem, 0) = plus_constant (GET_MODE (XEXP (tem, 0)),
- XEXP (tem, 0), offset);
- PUT_MODE (tem, GET_MODE (x));
- if (MEM_OFFSET_KNOWN_P (tem))
- set_mem_offset (tem, MEM_OFFSET (tem) + offset);
- if (MEM_SIZE_KNOWN_P (tem)
- && MEM_SIZE (tem) != (HOST_WIDE_INT) outer_size)
- set_mem_size (tem, outer_size);
-
- /* If this was a paradoxical subreg that we replaced, the
- resulting memory must be sufficiently aligned to allow
- us to widen the mode of the memory. */
- if (outer_size > inner_size)
- {
- rtx base;
+ /* We cannot replace the subreg with a modified memory reference if:
- base = XEXP (tem, 0);
- if (GET_CODE (base) == PLUS)
- {
- if (CONST_INT_P (XEXP (base, 1))
- && INTVAL (XEXP (base, 1)) % outer_size != 0)
- return x;
- base = XEXP (base, 0);
- }
- if (!REG_P (base)
- || (REGNO_POINTER_ALIGN (REGNO (base))
- < outer_size * BITS_PER_UNIT))
- return x;
- }
+ - we have a paradoxical subreg that implicitly acts as a zero or
+ sign extension operation due to LOAD_EXTEND_OP;
- reloaded = find_reloads_address (GET_MODE (tem), &tem,
- XEXP (tem, 0), &XEXP (tem, 0),
- opnum, type, ind_levels, insn);
- /* ??? Do we need to handle nonzero offsets somehow? */
- if (!offset && !rtx_equal_p (tem, orig))
- push_reg_equiv_alt_mem (regno, tem);
-
- /* For some processors an address may be valid in the
- original mode but not in a smaller mode. For
- example, ARM accepts a scaled index register in
- SImode but not in HImode. Note that this is only
- a problem if the address in reg_equiv_mem is already
- invalid in the new mode; other cases would be fixed
- by find_reloads_address as usual.
-
- ??? We attempt to handle such cases here by doing an
- additional reload of the full address after the
- usual processing by find_reloads_address. Note that
- this may not work in the general case, but it seems
- to cover the cases where this situation currently
- occurs. A more general fix might be to reload the
- *value* instead of the address, but this would not
- be expected by the callers of this routine as-is.
-
- If find_reloads_address already completed replaced
- the address, there is nothing further to do. */
- if (reloaded == 0
- && reg_equiv_mem (regno) != 0
- && !strict_memory_address_addr_space_p
- (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
- MEM_ADDR_SPACE (reg_equiv_mem (regno))))
- {
- push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
- base_reg_class (GET_MODE (tem),
- MEM_ADDR_SPACE (tem),
- MEM, SCRATCH),
- GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
- opnum, type);
- reloaded = 1;
- }
- /* If this is not a toplevel operand, find_reloads doesn't see
- this substitution. We have to emit a USE of the pseudo so
- that delete_output_reload can see it. */
- if (replace_reloads && recog_data.operand[opnum] != x)
- /* We mark the USE with QImode so that we recognize it
- as one that can be safely deleted at the end of
- reload. */
- PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode,
- SUBREG_REG (x)),
- insn), QImode);
- x = tem;
- }
- }
+ - we have a subreg that is implicitly supposed to act on the full
+ register due to WORD_REGISTER_OPERATIONS (see also eliminate_regs);
+
+ - the address of the equivalent memory location is mode-dependent; or
+
+ - we have a paradoxical subreg and the resulting memory is not
+ sufficiently aligned to allow access in the wider mode.
+
+ In addition, we choose not to perform the replacement for *any*
+ paradoxical subreg, even if it were possible in principle. This
+ is to avoid generating wider memory references than necessary.
+
+ This corresponds to how previous versions of reload used to handle
+ paradoxical subregs where no address reload was required. */
+
+ if (paradoxical_subreg_p (x))
+ return NULL;
+
+#ifdef WORD_REGISTER_OPERATIONS
+ if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode)
+ && ((GET_MODE_SIZE (outer_mode) - 1) / UNITS_PER_WORD
+ == (GET_MODE_SIZE (inner_mode) - 1) / UNITS_PER_WORD))
+ return NULL;
+#endif
+
+ /* Since we don't attempt to handle paradoxical subregs, we can just
+ call into simplify_subreg, which will handle all remaining checks
+ for us. */
+ orig = make_memloc (SUBREG_REG (x), regno);
+ offset = SUBREG_BYTE (x);
+ tem = simplify_subreg (outer_mode, orig, inner_mode, offset);
+ if (!tem || !MEM_P (tem))
+ return NULL;
+
+ /* Now push all required address reloads, if any. */
+ reloaded = find_reloads_address (GET_MODE (tem), &tem,
+ XEXP (tem, 0), &XEXP (tem, 0),
+ opnum, type, ind_levels, insn);
+ /* ??? Do we need to handle nonzero offsets somehow? */
+ if (!offset && !rtx_equal_p (tem, orig))
+ push_reg_equiv_alt_mem (regno, tem);
+
+ /* For some processors an address may be valid in the original mode but
+ not in a smaller mode. For example, ARM accepts a scaled index register
+ in SImode but not in HImode. Note that this is only a problem if the
+ address in reg_equiv_mem is already invalid in the new mode; other
+ cases would be fixed by find_reloads_address as usual.
+
+ ??? We attempt to handle such cases here by doing an additional reload
+ of the full address after the usual processing by find_reloads_address.
+ Note that this may not work in the general case, but it seems to cover
+ the cases where this situation currently occurs. A more general fix
+ might be to reload the *value* instead of the address, but this would
+ not be expected by the callers of this routine as-is.
+
+ If find_reloads_address already completed replaced the address, there
+ is nothing further to do. */
+ if (reloaded == 0
+ && reg_equiv_mem (regno) != 0
+ && !strict_memory_address_addr_space_p
+ (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
+ MEM_ADDR_SPACE (reg_equiv_mem (regno))))
+ {
+ push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
+ base_reg_class (GET_MODE (tem), MEM_ADDR_SPACE (tem),
+ MEM, SCRATCH),
+ GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0, opnum, type);
+ reloaded = 1;
}
+
+ /* If this is not a toplevel operand, find_reloads doesn't see this
+ substitution. We have to emit a USE of the pseudo so that
+ delete_output_reload can see it. */
+ if (replace_reloads && recog_data.operand[opnum] != x)
+ /* We mark the USE with QImode so that we recognize it as one that
+ can be safely deleted at the end of reload. */
+ PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, SUBREG_REG (x)), insn),
+ QImode);
+
if (address_reloaded)
*address_reloaded = reloaded;
- return x;
+ return tem;
}
/* Substitute into the current INSN the registers into which we have reloaded
diff --git a/gcc/rtl.h b/gcc/rtl.h
index cd5d4352b..09f1e7738 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -267,7 +267,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"),
1 in a CALL_INSN if it is a sibling call.
1 in a SET that is for a return.
In a CODE_LABEL, part of the two-bit alternate entry field.
- 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c. */
+ 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c.
+ 1 in a VALUE is SP_BASED_VALUE_P in cselib.c. */
unsigned int jump : 1;
/* In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a MEM if it cannot trap.
@@ -1929,6 +1930,7 @@ extern bool nonzero_address_p (const_rtx);
extern int rtx_unstable_p (const_rtx);
extern bool rtx_varies_p (const_rtx, bool);
extern bool rtx_addr_varies_p (const_rtx, bool);
+extern rtx get_call_rtx_from (rtx);
extern HOST_WIDE_INT get_integer_term (const_rtx);
extern rtx get_related_value (const_rtx);
extern bool offset_within_block_p (const_rtx, HOST_WIDE_INT);
@@ -2614,6 +2616,7 @@ extern void init_alias_analysis (void);
extern void end_alias_analysis (void);
extern void vt_equate_reg_base_value (const_rtx, const_rtx);
extern bool memory_modified_in_insn_p (const_rtx, const_rtx);
+extern bool memory_must_be_modified_in_insn_p (const_rtx, const_rtx);
extern bool may_be_sp_based_p (rtx);
extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int);
extern rtx get_reg_known_value (unsigned int);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index fb7d45cfb..a19bdfdc0 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -466,6 +466,22 @@ rtx_addr_varies_p (const_rtx x, bool for_alias)
return 0;
}
+/* Return the CALL in X if there is one. */
+
+rtx
+get_call_rtx_from (rtx x)
+{
+ if (INSN_P (x))
+ x = PATTERN (x);
+ if (GET_CODE (x) == PARALLEL)
+ x = XVECEXP (x, 0, 0);
+ if (GET_CODE (x) == SET)
+ x = SET_SRC (x);
+ if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
+ return x;
+ return NULL_RTX;
+}
+
/* Return the value of the integer term in X, if one is apparent;
otherwise return 0.
Only obvious integer terms are detected.
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 936a1317b..b9ffb2d61 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -3425,14 +3425,8 @@ call_may_noreturn_p (rtx insn)
&& !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
return false;
- call = PATTERN (insn);
- if (GET_CODE (call) == PARALLEL)
- call = XVECEXP (call, 0, 0);
- if (GET_CODE (call) == SET)
- call = SET_SRC (call);
- if (GET_CODE (call) == CALL
- && MEM_P (XEXP (call, 0))
- && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
+ call = get_call_rtx_from (insn);
+ if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
{
rtx symbol = XEXP (XEXP (call, 0), 0);
if (SYMBOL_REF_DECL (symbol)
diff --git a/gcc/stmt.c b/gcc/stmt.c
index fb3323e19..14a28abcc 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -94,11 +94,15 @@ struct case_node
tree low; /* Lowest index value for this label */
tree high; /* Highest index value for this label */
tree code_label; /* Label to jump to when node matches */
+ int prob; /* Probability of taking this case. */
+ /* Probability of reaching subtree rooted at this node */
+ int subtree_prob;
};
typedef struct case_node case_node;
typedef struct case_node *case_node_ptr;
+extern basic_block label_to_block_fn (struct function *, tree);
static int n_occurrences (int, const char *);
static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
@@ -112,7 +116,7 @@ static void balance_case_nodes (case_node_ptr *, case_node_ptr);
static int node_has_low_bound (case_node_ptr, tree);
static int node_has_high_bound (case_node_ptr, tree);
static int node_is_bounded (case_node_ptr, tree);
-static void emit_case_nodes (rtx, case_node_ptr, rtx, tree);
+static void emit_case_nodes (rtx, case_node_ptr, rtx, int, tree);
/* Return the rtx-label that corresponds to a LABEL_DECL,
creating it if necessary. */
@@ -1648,23 +1652,29 @@ expand_stack_restore (tree var)
fixup_args_size_notes (prev, get_last_insn (), 0);
}
-/* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. */
+/* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
+ is the probability of jumping to LABEL. */
static void
do_jump_if_equal (enum machine_mode mode, rtx op0, rtx op1, rtx label,
- int unsignedp)
+ int unsignedp, int prob)
{
+ gcc_assert (prob <= REG_BR_PROB_BASE);
do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
- NULL_RTX, NULL_RTX, label, -1);
+ NULL_RTX, NULL_RTX, label, prob);
}
/* Do the insertion of a case label into case_list. The labels are
fed to us in descending order from the sorted vector of case labels used
in the tree part of the middle end. So the list we construct is
- sorted in ascending order. */
+ sorted in ascending order.
+
+ LABEL is the case label to be inserted. LOW and HIGH are the bounds
+ against which the index is compared to jump to LABEL and PROB is the
+ estimated probability LABEL is reached from the switch statement. */
static struct case_node *
add_case_node (struct case_node *head, tree low, tree high,
- tree label, alloc_pool case_node_pool)
+ tree label, int prob, alloc_pool case_node_pool)
{
struct case_node *r;
@@ -1677,6 +1687,8 @@ add_case_node (struct case_node *head, tree low, tree high,
r->high = high;
r->code_label = label;
r->parent = r->left = NULL;
+ r->prob = prob;
+ r->subtree_prob = prob;
r->right = head;
return r;
}
@@ -1778,6 +1790,8 @@ expand_switch_as_decision_tree_p (tree range,
/* Generate a decision tree, switching on INDEX_EXPR and jumping to
one of the labels in CASE_LIST or to the DEFAULT_LABEL.
+ DEFAULT_PROB is the estimated probability that it jumps to
+ DEFAULT_LABEL.
We generate a binary decision tree to select the appropriate target
code. This is done as follows:
@@ -1803,7 +1817,8 @@ expand_switch_as_decision_tree_p (tree range,
static void
emit_case_decision_tree (tree index_expr, tree index_type,
- struct case_node *case_list, rtx default_label)
+ struct case_node *case_list, rtx default_label,
+ int default_prob)
{
rtx index = expand_normal (index_expr);
@@ -1839,15 +1854,47 @@ emit_case_decision_tree (tree index_expr, tree index_type,
dump_case_nodes (dump_file, case_list, indent_step, 0);
}
- emit_case_nodes (index, case_list, default_label, index_type);
+ emit_case_nodes (index, case_list, default_label, default_prob, index_type);
if (default_label)
emit_jump (default_label);
}
+/* Return the sum of probabilities of outgoing edges of basic block BB. */
+
+static int
+get_outgoing_edge_probs (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ int prob_sum = 0;
+ FOR_EACH_EDGE(e, ei, bb->succs)
+ prob_sum += e->probability;
+ return prob_sum;
+}
+
+/* Computes the conditional probability of jumping to a target if the branch
+ instruction is executed.
+ TARGET_PROB is the estimated probability of jumping to a target relative
+ to some basic block BB.
+ BASE_PROB is the probability of reaching the branch instruction relative
+ to the same basic block BB. */
+
+static inline int
+conditional_probability (int target_prob, int base_prob)
+{
+ if (base_prob > 0)
+ {
+ gcc_assert (target_prob >= 0);
+ gcc_assert (target_prob <= base_prob);
+ return RDIV (target_prob * REG_BR_PROB_BASE, base_prob);
+ }
+ return -1;
+}
+
/* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
one of the labels in CASE_LIST or to the DEFAULT_LABEL.
MINVAL, MAXVAL, and RANGE are the extrema and range of the case
- labels in CASE_LIST.
+ labels in CASE_LIST. STMT_BB is the basic block containing the statement.
First, a jump insn is emitted. First we try "casesi". If that
fails, try "tablejump". A target *must* have one of them (or both).
@@ -1860,19 +1907,27 @@ emit_case_decision_tree (tree index_expr, tree index_type,
static void
emit_case_dispatch_table (tree index_expr, tree index_type,
struct case_node *case_list, rtx default_label,
- tree minval, tree maxval, tree range)
+ tree minval, tree maxval, tree range,
+ basic_block stmt_bb)
{
int i, ncases;
struct case_node *n;
rtx *labelvec;
rtx fallback_label = label_rtx (case_list->code_label);
rtx table_label = gen_label_rtx ();
+ bool has_gaps = false;
+ edge default_edge = EDGE_SUCC(stmt_bb, 0);
+ int default_prob = default_edge->probability;
+ int base = get_outgoing_edge_probs (stmt_bb);
+ bool try_with_tablejump = false;
+
+ int new_default_prob = conditional_probability (default_prob,
+ base);
if (! try_casesi (index_type, index_expr, minval, range,
- table_label, default_label, fallback_label))
+ table_label, default_label, fallback_label,
+ new_default_prob))
{
- bool ok;
-
/* Index jumptables from zero for suitable values of minval to avoid
a subtraction. For the rationale see:
"http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html". */
@@ -1882,11 +1937,9 @@ emit_case_dispatch_table (tree index_expr, tree index_type,
{
minval = build_int_cst (index_type, 0);
range = maxval;
+ has_gaps = true;
}
-
- ok = try_tablejump (index_type, index_expr, minval, range,
- table_label, default_label);
- gcc_assert (ok);
+ try_with_tablejump = true;
}
/* Get table of labels to jump to, in order of case index. */
@@ -1921,8 +1974,48 @@ emit_case_dispatch_table (tree index_expr, tree index_type,
default_label = fallback_label;
for (i = 0; i < ncases; i++)
if (labelvec[i] == 0)
- labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label);
+ {
+ has_gaps = true;
+ labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label);
+ }
+
+ if (has_gaps)
+ {
+ /* There is at least one entry in the jump table that jumps
+ to default label. The default label can either be reached
+ through the indirect jump or the direct conditional jump
+ before that. Split the probability of reaching the
+ default label among these two jumps. */
+ new_default_prob = conditional_probability (default_prob/2,
+ base);
+ default_prob /= 2;
+ base -= default_prob;
+ }
+ else
+ {
+ base -= default_prob;
+ default_prob = 0;
+ }
+
+ default_edge->probability = default_prob;
+
+ /* We have altered the probability of the default edge. So the probabilities
+ of all other edges need to be adjusted so that it sums up to
+ REG_BR_PROB_BASE. */
+ if (base)
+ {
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, stmt_bb->succs)
+ e->probability = RDIV (e->probability * REG_BR_PROB_BASE, base);
+ }
+ if (try_with_tablejump)
+ {
+ bool ok = try_tablejump (index_type, index_expr, minval, range,
+ table_label, default_label, new_default_prob);
+ gcc_assert (ok);
+ }
/* Output the table. */
emit_label (table_label);
@@ -1939,6 +2032,36 @@ emit_case_dispatch_table (tree index_expr, tree index_type,
emit_barrier ();
}
+/* Reset the aux field of all outgoing edges of basic block BB. */
+
+static inline void
+reset_out_edges_aux (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE(e, ei, bb->succs)
+ e->aux = (void *)0;
+}
+
+/* Compute the number of case labels that correspond to each outgoing edge of
+ STMT. Record this information in the aux field of the edge. */
+
+static inline void
+compute_cases_per_edge (gimple stmt)
+{
+ basic_block bb = gimple_bb (stmt);
+ reset_out_edges_aux (bb);
+ int ncases = gimple_switch_num_labels (stmt);
+ for (int i = ncases - 1; i >= 1; --i)
+ {
+ tree elt = gimple_switch_label (stmt, i);
+ tree lab = CASE_LABEL (elt);
+ basic_block case_bb = label_to_block_fn (cfun, lab);
+ edge case_edge = find_edge (bb, case_bb);
+ case_edge->aux = (void *)((long)(case_edge->aux) + 1);
+ }
+}
+
/* Terminate a case (Pascal/Ada) or switch (C) statement
in which ORIG_INDEX is the expression to be tested.
If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
@@ -1956,6 +2079,7 @@ expand_case (gimple stmt)
tree index_expr = gimple_switch_index (stmt);
tree index_type = TREE_TYPE (index_expr);
tree elt;
+ basic_block bb = gimple_bb (stmt);
/* A list of case labels; it is first built as a list and it may then
be rearranged into a nearly balanced binary tree. */
@@ -1981,6 +2105,8 @@ expand_case (gimple stmt)
/* Find the default case target label. */
default_label = label_rtx (CASE_LABEL (gimple_switch_default_label (stmt)));
+ edge default_edge = EDGE_SUCC(bb, 0);
+ int default_prob = default_edge->probability;
/* Get upper and lower bounds of case values. */
elt = gimple_switch_label (stmt, 1);
@@ -1999,7 +2125,9 @@ expand_case (gimple stmt)
uniq = 0;
count = 0;
struct pointer_set_t *seen_labels = pointer_set_create ();
- for (i = gimple_switch_num_labels (stmt) - 1; i >= 1; --i)
+ compute_cases_per_edge (stmt);
+
+ for (i = ncases - 1; i >= 1; --i)
{
elt = gimple_switch_label (stmt, i);
tree low = CASE_LOW (elt);
@@ -2041,10 +2169,15 @@ expand_case (gimple stmt)
TREE_INT_CST_LOW (high),
TREE_INT_CST_HIGH (high));
- case_list = add_case_node (case_list, low, high, lab,
- case_node_pool);
+ basic_block case_bb = label_to_block_fn (cfun, lab);
+ edge case_edge = find_edge (bb, case_bb);
+ case_list = add_case_node (
+ case_list, low, high, lab,
+ case_edge->probability / (long)(case_edge->aux),
+ case_node_pool);
}
pointer_set_destroy (seen_labels);
+ reset_out_edges_aux (bb);
/* cleanup_tree_cfg removes all SWITCH_EXPR with a single
destination, such as one with a default case only.
@@ -2060,11 +2193,12 @@ expand_case (gimple stmt)
if (expand_switch_as_decision_tree_p (range, uniq, count))
emit_case_decision_tree (index_expr, index_type,
- case_list, default_label);
+ case_list, default_label,
+ default_prob);
else
emit_case_dispatch_table (index_expr, index_type,
case_list, default_label,
- minval, maxval, range);
+ minval, maxval, range, bb);
reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
@@ -2126,7 +2260,7 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
{
tree elt = VEC_index (tree, dispatch_table, i);
rtx lab = label_rtx (CASE_LABEL (elt));
- do_jump_if_equal (index_mode, index, zero, lab, 0);
+ do_jump_if_equal (index_mode, index, zero, lab, 0, -1);
force_expand_binop (index_mode, sub_optab,
index, CONST1_RTX (index_mode),
index, 0, OPTAB_DIRECT);
@@ -2150,12 +2284,12 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
tree elt = VEC_index (tree, dispatch_table, i);
tree low = CASE_LOW (elt);
tree lab = CASE_LABEL (elt);
- case_list = add_case_node (case_list, low, low, lab, case_node_pool);
+ case_list = add_case_node (case_list, low, low, lab, 0, case_node_pool);
}
emit_case_dispatch_table (index_expr, index_type,
case_list, default_label,
- minval, maxval, range);
+ minval, maxval, range, NULL);
emit_label (default_label);
free_alloc_pool (case_node_pool);
}
@@ -2237,6 +2371,9 @@ balance_case_nodes (case_node_ptr *head, case_node_ptr parent)
/* Optimize each of the two split parts. */
balance_case_nodes (&np->left, np);
balance_case_nodes (&np->right, np);
+ np->subtree_prob = np->prob;
+ np->subtree_prob += np->left->subtree_prob;
+ np->subtree_prob += np->right->subtree_prob;
}
else
{
@@ -2244,8 +2381,12 @@ balance_case_nodes (case_node_ptr *head, case_node_ptr parent)
but fill in `parent' fields. */
np = *head;
np->parent = parent;
+ np->subtree_prob = np->prob;
for (; np->right; np = np->right)
- np->right->parent = np;
+ {
+ np->right->parent = np;
+ (*head)->subtree_prob += np->right->subtree_prob;
+ }
}
}
}
@@ -2358,6 +2499,7 @@ node_is_bounded (case_node_ptr node, tree index_type)
&& node_has_high_bound (node, index_type));
}
+
/* Emit step-by-step code to select a case for the value of INDEX.
The thus generated decision tree follows the form of the
case-node binary tree NODE, whose nodes represent test conditions.
@@ -2386,10 +2528,12 @@ node_is_bounded (case_node_ptr node, tree index_type)
static void
emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
- tree index_type)
+ int default_prob, tree index_type)
{
/* If INDEX has an unsigned type, we must make unsigned branches. */
int unsignedp = TYPE_UNSIGNED (index_type);
+ int probability;
+ int prob = node->prob, subtree_prob = node->subtree_prob;
enum machine_mode mode = GET_MODE (index);
enum machine_mode imode = TYPE_MODE (index_type);
@@ -2404,15 +2548,17 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
else if (tree_int_cst_equal (node->low, node->high))
{
+ probability = conditional_probability (prob, subtree_prob + default_prob);
/* Node is single valued. First see if the index expression matches
this node and then check our children, if any. */
-
do_jump_if_equal (mode, index,
convert_modes (mode, imode,
expand_normal (node->low),
unsignedp),
- label_rtx (node->code_label), unsignedp);
-
+ label_rtx (node->code_label), unsignedp, probability);
+ /* Since this case is taken at this point, reduce its weight from
+ subtree_weight. */
+ subtree_prob -= prob;
if (node->right != 0 && node->left != 0)
{
/* This node has children on both sides.
@@ -2423,26 +2569,35 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
if (node_is_bounded (node->right, index_type))
{
+ probability = conditional_probability (
+ node->right->prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
GT, NULL_RTX, mode, unsignedp,
- label_rtx (node->right->code_label));
- emit_case_nodes (index, node->left, default_label, index_type);
+ label_rtx (node->right->code_label),
+ probability);
+ emit_case_nodes (index, node->left, default_label, default_prob,
+ index_type);
}
else if (node_is_bounded (node->left, index_type))
{
+ probability = conditional_probability (
+ node->left->prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
LT, NULL_RTX, mode, unsignedp,
- label_rtx (node->left->code_label));
- emit_case_nodes (index, node->right, default_label, index_type);
+ label_rtx (node->left->code_label),
+ probability);
+ emit_case_nodes (index, node->right, default_label, default_prob, index_type);
}
/* If both children are single-valued cases with no
@@ -2460,21 +2615,27 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
/* See if the value matches what the right hand side
wants. */
+ probability = conditional_probability (
+ node->right->prob,
+ subtree_prob + default_prob);
do_jump_if_equal (mode, index,
convert_modes (mode, imode,
expand_normal (node->right->low),
unsignedp),
label_rtx (node->right->code_label),
- unsignedp);
+ unsignedp, probability);
/* See if the value matches what the left hand side
wants. */
+ probability = conditional_probability (
+ node->left->prob,
+ subtree_prob + default_prob);
do_jump_if_equal (mode, index,
convert_modes (mode, imode,
expand_normal (node->left->low),
unsignedp),
label_rtx (node->left->code_label),
- unsignedp);
+ unsignedp, probability);
}
else
@@ -2486,6 +2647,12 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
= build_decl (curr_insn_location (),
LABEL_DECL, NULL_TREE, NULL_TREE);
+ /* The default label could be reached either through the right
+ subtree or the left subtree. Divide the probability
+ equally. */
+ probability = conditional_probability (
+ node->right->subtree_prob + default_prob/2,
+ subtree_prob + default_prob);
/* See if the value is on the right. */
emit_cmp_and_jump_insns (index,
convert_modes
@@ -2493,11 +2660,13 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
expand_normal (node->high),
unsignedp),
GT, NULL_RTX, mode, unsignedp,
- label_rtx (test_label));
+ label_rtx (test_label),
+ probability);
+ default_prob /= 2;
/* Value must be on the left.
Handle the left-hand subtree. */
- emit_case_nodes (index, node->left, default_label, index_type);
+ emit_case_nodes (index, node->left, default_label, default_prob, index_type);
/* If left-hand subtree does nothing,
go to default. */
if (default_label)
@@ -2505,7 +2674,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
/* Code branches here for the right-hand subtree. */
expand_label (test_label);
- emit_case_nodes (index, node->right, default_label, index_type);
+ emit_case_nodes (index, node->right, default_label, default_prob, index_type);
}
}
@@ -2523,28 +2692,38 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
{
if (!node_has_low_bound (node, index_type))
{
+ probability = conditional_probability (
+ default_prob/2,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
LT, NULL_RTX, mode, unsignedp,
- default_label);
+ default_label,
+ probability);
+ default_prob /= 2;
}
- emit_case_nodes (index, node->right, default_label, index_type);
+ emit_case_nodes (index, node->right, default_label, default_prob, index_type);
}
else
- /* We cannot process node->right normally
- since we haven't ruled out the numbers less than
- this node's value. So handle node->right explicitly. */
- do_jump_if_equal (mode, index,
- convert_modes
- (mode, imode,
- expand_normal (node->right->low),
- unsignedp),
- label_rtx (node->right->code_label), unsignedp);
- }
+ {
+ probability = conditional_probability (
+ node->right->subtree_prob,
+ subtree_prob + default_prob);
+ /* We cannot process node->right normally
+ since we haven't ruled out the numbers less than
+ this node's value. So handle node->right explicitly. */
+ do_jump_if_equal (mode, index,
+ convert_modes
+ (mode, imode,
+ expand_normal (node->right->low),
+ unsignedp),
+ label_rtx (node->right->code_label), unsignedp, probability);
+ }
+ }
else if (node->right == 0 && node->left != 0)
{
@@ -2554,27 +2733,38 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
{
if (!node_has_high_bound (node, index_type))
{
+ probability = conditional_probability (
+ default_prob/2,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
GT, NULL_RTX, mode, unsignedp,
- default_label);
+ default_label,
+ probability);
+ default_prob /= 2;
}
- emit_case_nodes (index, node->left, default_label, index_type);
+ emit_case_nodes (index, node->left, default_label,
+ default_prob, index_type);
}
else
- /* We cannot process node->left normally
- since we haven't ruled out the numbers less than
- this node's value. So handle node->left explicitly. */
- do_jump_if_equal (mode, index,
- convert_modes
- (mode, imode,
- expand_normal (node->left->low),
- unsignedp),
- label_rtx (node->left->code_label), unsignedp);
+ {
+ probability = conditional_probability (
+ node->left->subtree_prob,
+ subtree_prob + default_prob);
+ /* We cannot process node->left normally
+ since we haven't ruled out the numbers less than
+ this node's value. So handle node->left explicitly. */
+ do_jump_if_equal (mode, index,
+ convert_modes
+ (mode, imode,
+ expand_normal (node->left->low),
+ unsignedp),
+ label_rtx (node->left->code_label), unsignedp, probability);
+ }
}
}
else
@@ -2593,15 +2783,21 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
tree test_label = 0;
if (node_is_bounded (node->right, index_type))
- /* Right hand node is fully bounded so we can eliminate any
- testing and branch directly to the target code. */
- emit_cmp_and_jump_insns (index,
- convert_modes
- (mode, imode,
- expand_normal (node->high),
- unsignedp),
- GT, NULL_RTX, mode, unsignedp,
- label_rtx (node->right->code_label));
+ {
+ /* Right hand node is fully bounded so we can eliminate any
+ testing and branch directly to the target code. */
+ probability = conditional_probability (
+ node->right->subtree_prob,
+ subtree_prob + default_prob);
+ emit_cmp_and_jump_insns (index,
+ convert_modes
+ (mode, imode,
+ expand_normal (node->high),
+ unsignedp),
+ GT, NULL_RTX, mode, unsignedp,
+ label_rtx (node->right->code_label),
+ probability);
+ }
else
{
/* Right hand node requires testing.
@@ -2609,27 +2805,36 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
test_label = build_decl (curr_insn_location (),
LABEL_DECL, NULL_TREE, NULL_TREE);
+ probability = conditional_probability (
+ node->right->subtree_prob + default_prob/2,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
GT, NULL_RTX, mode, unsignedp,
- label_rtx (test_label));
+ label_rtx (test_label),
+ probability);
+ default_prob /= 2;
}
/* Value belongs to this node or to the left-hand subtree. */
+ probability = conditional_probability (
+ prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->low),
unsignedp),
GE, NULL_RTX, mode, unsignedp,
- label_rtx (node->code_label));
+ label_rtx (node->code_label),
+ probability);
/* Handle the left-hand subtree. */
- emit_case_nodes (index, node->left, default_label, index_type);
+ emit_case_nodes (index, node->left, default_label, default_prob, index_type);
/* If right node had to be handled later, do that now. */
@@ -2641,7 +2846,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
emit_jump (default_label);
expand_label (test_label);
- emit_case_nodes (index, node->right, default_label, index_type);
+ emit_case_nodes (index, node->right, default_label, default_prob, index_type);
}
}
@@ -2651,26 +2856,35 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
if they are possible. */
if (!node_has_low_bound (node, index_type))
{
+ probability = conditional_probability (
+ default_prob/2,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->low),
unsignedp),
LT, NULL_RTX, mode, unsignedp,
- default_label);
+ default_label,
+ probability);
+ default_prob /= 2;
}
/* Value belongs to this node or to the right-hand subtree. */
+ probability = conditional_probability (
+ prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
LE, NULL_RTX, mode, unsignedp,
- label_rtx (node->code_label));
+ label_rtx (node->code_label),
+ probability);
- emit_case_nodes (index, node->right, default_label, index_type);
+ emit_case_nodes (index, node->right, default_label, default_prob, index_type);
}
else if (node->right == 0 && node->left != 0)
@@ -2679,26 +2893,35 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
if they are possible. */
if (!node_has_high_bound (node, index_type))
{
+ probability = conditional_probability (
+ default_prob/2,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
GT, NULL_RTX, mode, unsignedp,
- default_label);
+ default_label,
+ probability);
+ default_prob /= 2;
}
/* Value belongs to this node or to the left-hand subtree. */
+ probability = conditional_probability (
+ prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->low),
unsignedp),
GE, NULL_RTX, mode, unsignedp,
- label_rtx (node->code_label));
+ label_rtx (node->code_label),
+ probability);
- emit_case_nodes (index, node->left, default_label, index_type);
+ emit_case_nodes (index, node->left, default_label, default_prob, index_type);
}
else
@@ -2711,24 +2934,32 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
if (!high_bound && low_bound)
{
+ probability = conditional_probability (
+ default_prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->high),
unsignedp),
GT, NULL_RTX, mode, unsignedp,
- default_label);
+ default_label,
+ probability);
}
else if (!low_bound && high_bound)
{
+ probability = conditional_probability (
+ default_prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
expand_normal (node->low),
unsignedp),
LT, NULL_RTX, mode, unsignedp,
- default_label);
+ default_label,
+ probability);
}
else if (!low_bound && !high_bound)
{
@@ -2748,8 +2979,11 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
high, low),
NULL_RTX, mode, EXPAND_NORMAL);
+ probability = conditional_probability (
+ default_prob,
+ subtree_prob + default_prob);
emit_cmp_and_jump_insns (new_index, new_bound, GT, NULL_RTX,
- mode, 1, default_label);
+ mode, 1, default_label, probability);
}
emit_jump (label_rtx (node->code_label));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6a61bb969..31f487ed1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,199 @@
+2012-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54501
+ * g++.dg/init/array30.C: New.
+ * g++.dg/init/array31.C: Likewise.
+
+2012-10-18 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/54884
+ * gfortran.dg/public_private_module_7.f90: New.
+
+2012-10-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/29633
+ * g++.dg/template/pr29633.C: New.
+
+2012-10-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_optimization13.ad[sb]: New test.
+ * gnat.dg/loop_optimization13_pkg.ads: New helper.
+
+2012-10-18 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * gcc.target/arm/neon/vfmaQf32.c: New testcase.
+ * gcc.target/arm/neon/vfmaf32.c: Likewise.
+ * gcc.target/arm/neon/vfmsQf32.c: Likewise.
+ * gcc.target/arm/neon/vfmsf32.c: Likewise.
+
+2012-10-18 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * gcc.target/arm/ftest-armv8a-arm.c: New testcase.
+ * gcc.target/arm/ftest-armv8a-thumb.c: Likewise.
+ * gcc.target/arm/ftest-support-arm.h (feature_matrix): Add
+ ARMv8-A row.
+ * gcc.target/arm/ftest-support-thumb.h (feature_matrix):
+ Likewise.
+ * gcc.target/arm/ftest-support.h (architecture): Add ARMv8-A.
+ * lib/target-supports.exp: Add ARMv8-A architecture expectation.
+
+2012-10-16 Jan Hubicka <jh@suse.cz>
+
+ * gcc.target/i386/l_fma_float_?.c: Update.
+ * gcc.target/i386/l_fma_double_?.c: Update.
+ * gfortran.dg/do_1.f90: XFAIL
+ * gcc.dg/tree-ssa/cunroll-1.c: New testcase.
+ * gcc.dg/tree-ssa/cunroll-2.c: New testcase.
+ * gcc.dg/tree-ssa/cunroll-3.c: New testcase.
+ * gcc.dg/tree-ssa/cunroll-4.c: New testcase.
+ * gcc.dg/tree-ssa/cunroll-5.c: New testcase.
+ * gcc.dg/tree-ssa/ldist-17.c: Block cunroll to make testcase still
+ valid.
+
+2012-10-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/53063
+ PR c/40989
+ * gcc.dg/Wstrict-overflow-24.c: New.
+
+2012-10-16 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/50981
+ PR fortran/54618
+ * gfortran.dg/class_optional_1.f90: New.
+ * gfortran.dg/class_optional_2.f90: New.
+
+2012-10-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/54796
+ * gcc.dg/guality/pr54796.c: New test.
+
+ PR tree-optimization/54889
+ * gfortran.dg/pr54889.f90: New test.
+
+2012-10-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * g++.dg/other/dump-ada-spec-2.C: New test.
+
+2012-10-16 Easwaran Raman <eraman@google.com>
+
+ * gcc.dg/tree-prof/switch-case-1.c: New test case.
+ * gcc.dg/tree-prof/switch-case-2.c: New test case.
+
+2012-10-16 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * gcc.dg/torture/stackalign/builtin-apply-2.c,
+ gcc.dg/builtin-apply2.c: Correct STACK_ARGUMENTS_SIZE for MMIX.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54925
+ * gcc.c-torture/compile/pr54925.c: New.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * gcc.target/sh/pr51244-17.c: New.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54760
+ * gcc.target/sh/pr54760-2.c: Add long long and unsigned long long test
+ functions.
+ * gcc.target/sh/pr54760-4.c: New.
+
+2012-10-15 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/34777
+ * gcc.target/sh/torture/sh-torture.exp: New.
+ * gcc.target/sh/torture/pr34777.c: New.
+
+2012-10-15 Matthias Klose <doko@ubuntu.com>
+
+ * lib/target-supports.exp (check_profiling_available): Match
+ arm*-*-linux-* for ARM Linux/GNU.
+ * g++.dg/torture/predcom-1.C: Match arm*-*-linux-* for ARM Linux/GNU.
+ * gfortran.dg/enum_10.f90: Likewise.
+ * gfortran.dg/enum_9.f90: Likewise.
+ * gcc.target/arm/synchronize.c: Likewise.
+ * g++.old-deja/g++.jason/enum6.C: Likewise.
+ * g++.old-deja/g++.other/enum4.C: Likewise.
+ * g++.old-deja/g++.law/enum9.C: Likewise.
+
+2012-10-15 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * g++.dg/tls/thread_local-cse.C: Move dg-do line.
+ * g++.dg/tls/thread_local-wrap4.C: Require fpic.
+
+2012-10-15 Alexandre Oliva <aoliva@redhat.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/17805
+ * g++.dg/overload/operator6.C: New.
+
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080 (again)
+ * g++.dg/parse/tmpl-outside2.C: Tweak, error in C++98.
+ * g++.dg/parse/tmpl-outside1.C: Likewise.
+ * g++.dg/template/qualttp18.C: Likewise.
+ * g++.old-deja/g++.pt/memtemp87.C: Likewise.
+ * g++.old-deja/g++.pt/overload13.C: Likewise.
+
+2012-10-15 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/avx256-unaligned-load-1.c: Update asm scan patterns.
+ * gcc.target/i386/avx256-unaligned-load-2.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-load-3.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-load-4.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-store-1.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-store-2.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-store-3.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-store-4.c: Ditto.
+
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080
+ * g++.dg/parse/tmpl-outside2.C: New.
+ * g++.dg/parse/tmpl-outside1.C: Adjust.
+ * g++.dg/template/qualttp18.C: Likewise.
+ * g++.old-deja/g++.pt/memtemp87.C: Likewise.
+ * g++.old-deja/g++.pt/overload13.C: Likewise.
+
+2012-10-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/54915
+ * gcc.dg/tree-ssa/pr54915.c: New testcase.
+
+2012-10-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/54920
+ * gcc.dg/torture/pr54920.c: New testcase.
+
+2012-10-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/unchecked_convert9.ad[sb]: New test.
+
+2012-10-13 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/tls/thread_local7g.C: Require tls_native.
+
+2012-10-14 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/inh-ctor1.C: New.
+ * g++.dg/cpp0x/inh-ctor2.C: New.
+ * g++.dg/cpp0x/inh-ctor3.C: New.
+ * g++.dg/cpp0x/inh-ctor4.C: New.
+ * g++.dg/cpp0x/inh-ctor5.C: New.
+ * g++.dg/cpp0x/inh-ctor6.C: New.
+ * g++.dg/cpp0x/inh-ctor7.C: New.
+ * g++.dg/cpp0x/inh-ctor8.C: New.
+ * g++.dg/cpp0x/inh-ctor9.C: New.
+ * g++.dg/cpp0x/inh-ctor10.C: New.
+ * g++.dg/cpp0x/inh-ctor11.C: New.
+ * g++.dg/cpp0x/inh-ctor12.C: New.
+ * g++.dg/cpp0x/inh-ctor13.C: New.
+
2012-10-14 Steven Bosscher <steven@gcc.gnu.org>
PR rtl-optimization/54919
diff --git a/gcc/testsuite/c-c++-common/tm/pr54893.c b/gcc/testsuite/c-c++-common/tm/pr54893.c
new file mode 100644
index 000000000..8967f384a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tm/pr54893.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */
+
+/* Test that volatiles are allowed inside relaxed transactions. */
+
+volatile int test_var = 0;
+
+int main()
+{
+ __transaction_relaxed {
+ test_var++;
+ }
+}
+
+/* { dg-final { scan-ipa-dump "GTMA_DOES_GO_IRREVOCABLE" "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C
new file mode 100644
index 000000000..996031065
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C
@@ -0,0 +1,17 @@
+// { dg-options -std=c++11 }
+
+struct A
+{
+ int i;
+ constexpr A(int i): i(i) {}
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+constexpr B b(42);
+
+#define SA(X) static_assert((X),#X)
+SA(b.i == 42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
new file mode 100644
index 000000000..de5745358
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ template <class... Ts> A(Ts...);
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+B b1(42);
+B b2(1.0, 42, (void*)0);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C
new file mode 100644
index 000000000..8e8ff010f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ A(int, ...);
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+B b1(42);
+B b2(42, 1.0); // { dg-error "no match" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C
new file mode 100644
index 000000000..257487efb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C
@@ -0,0 +1,26 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+struct A
+{
+ int i;
+ template <class T>
+ A(T t) noexcept : i(t) {}
+};
+
+struct C
+{
+ C() { throw 42; }
+};
+
+struct B: A, C
+{
+ using A::A;
+};
+
+int main()
+{
+ try { B b(24); }
+ catch (int) { return 0; }
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
new file mode 100644
index 000000000..2e18e5d62
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ int i;
+ template <class T> A(T t);
+};
+
+struct C
+{
+ C() = delete; // { dg-error "declared here" }
+};
+
+struct B: A, C
+{
+ using A::A; // { dg-error "C::C" }
+};
+
+int main()
+{
+ B b(24); // { dg-error "B::B" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C
new file mode 100644
index 000000000..621ba604c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C
@@ -0,0 +1,19 @@
+// { dg-options -std=c++11 }
+
+struct A
+{
+ int i;
+ constexpr A(int, int i = num): i(i) {}
+private:
+ static const int num = 42;
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+constexpr B b(24);
+
+#define SA(X) static_assert((X),#X)
+SA(b.i == 42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C
new file mode 100644
index 000000000..7116e2f07
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C
@@ -0,0 +1,17 @@
+// { dg-options -std=c++11 }
+
+struct B1 {
+ B1(int);
+};
+struct B2 {
+ B2(int);
+};
+struct D1 : B1, B2 {
+ using B1::B1; // { dg-error "inherited" }
+ using B2::B2; // { dg-error "inherited" }
+}; // ill-formed: attempts to declare D1(int) twice
+struct D2 : B1, B2 {
+ using B1::B1;
+ using B2::B2;
+ D2(int); // OK: user declaration supersedes both implicit declarations
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C
new file mode 100644
index 000000000..b6754dc4a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C
@@ -0,0 +1,18 @@
+// From N3337
+// { dg-options -std=c++11 }
+
+struct B1 {
+ B1(int);
+};
+struct B2 {
+ B2(int = 13, int = 42);
+};
+struct D1 : B1 {
+ using B1::B1;
+};
+struct D2 : B2 {
+ using B2::B2;
+};
+
+D1 d1(1);
+D2 d2a(2), d2b(3,4);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
new file mode 100644
index 000000000..a8aa6d98a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
@@ -0,0 +1,21 @@
+// { dg-options "-std=c++11" }
+
+struct B1 {
+ B1(int) { }
+};
+struct B2 {
+ B2(double) { }
+};
+struct D1 : B1 { // { dg-error "no match" }
+ using B1::B1; // implicitly declares D1(int)
+ int x;
+};
+void test() {
+ D1 d(6); // OK: d.x is not initialized
+ D1 e; // { dg-error "deleted" } D1 has no default constructor
+}
+struct D2 : B2 {
+ using B2::B2; // { dg-error "no match" } implicitly declares D2(double)
+ B1 b;
+};
+D2 f(1.0); // { dg-error "deleted" } B1 has no default constructor
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C
new file mode 100644
index 000000000..5ac88d6b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C
@@ -0,0 +1,15 @@
+// { dg-options "-std=c++11" }
+
+extern "C" int printf (const char *, ...);
+template< class T >
+struct D : T {
+ using T::T;
+ // declares all constructors from class T
+ ~D() { printf ("Destroying wrapper\n"); }
+};
+
+struct A {
+ A(int);
+};
+
+D<A> d(42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C
new file mode 100644
index 000000000..226082467
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C
@@ -0,0 +1,18 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ int i;
+ template <class T>
+ constexpr A(T t): i(t) {}
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+constexpr B b(42);
+
+#define SA(X) static_assert((X),#X)
+SA(b.i == 42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C
new file mode 100644
index 000000000..d55d3d2a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C
@@ -0,0 +1,20 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ int i;
+ explicit A(int i): i(i) {}
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+void f(B);
+
+int main()
+{
+ f(B(42)); // OK
+ f(42); // { dg-error "could not convert" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C
new file mode 100644
index 000000000..dc5e86b63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C
@@ -0,0 +1,15 @@
+// { dg-options "-std=c++11" }
+
+class A
+{
+ int i;
+protected:
+ A(int i): i(i) {}
+};
+
+struct B: A
+{
+ using A::A; // { dg-error "protected" }
+};
+
+B b(42); // { dg-error "this context" }
diff --git a/gcc/testsuite/g++.dg/init/array30.C b/gcc/testsuite/g++.dg/init/array30.C
new file mode 100644
index 000000000..696d9bf99
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array30.C
@@ -0,0 +1,7 @@
+// PR c++/54501
+// { dg-options "" }
+
+int main()
+{
+ int a[][0] = {0}; // { dg-error "too many" }
+}
diff --git a/gcc/testsuite/g++.dg/init/array31.C b/gcc/testsuite/g++.dg/init/array31.C
new file mode 100644
index 000000000..9bb66a595
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array31.C
@@ -0,0 +1,10 @@
+// PR c++/54501
+// { dg-options "" }
+
+struct A
+{
+ int i[0];
+ int j;
+};
+
+struct A a = { 1 };
diff --git a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
new file mode 100644
index 000000000..87c183aab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-ada-spec" } */
+
+struct S
+{
+ int it;
+ __extension__ unsigned char data[];
+};
+
+/* { dg-final { scan-ada-spec "array \\(0 .. -1\\)" } } */
+/* { dg-final { cleanup-ada-spec } } */
diff --git a/gcc/testsuite/g++.dg/overload/operator6.C b/gcc/testsuite/g++.dg/overload/operator6.C
new file mode 100644
index 000000000..5002602b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/operator6.C
@@ -0,0 +1,27 @@
+// PR c++/17805
+
+// Per 13.3.1.2/3 bullet 2, an operator function is not a candidate
+// for overload resolution if neither argument is of class type and
+// neither enumerator-typed argument gets an exact match, with or
+// without reference binding, for the corresponding parameter.
+
+struct A
+{
+ A(int);
+ A(const char*);
+};
+
+bool operator==(const A&, const A&);
+const A& operator*(const A&);
+
+enum E { e };
+
+bool b1 = (e == ""); // { dg-error "no match" }
+
+bool b2 = (A(1) == "");
+
+bool b3 = (e == A(1));
+
+const A& a1 = *e; // { dg-error "no match" }
+
+const A& a2 = *A(1);
diff --git a/gcc/testsuite/g++.dg/parse/tmpl-outside1.C b/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
index e63e3cd44..7d969e468 100644
--- a/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
+++ b/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
@@ -7,4 +7,4 @@ struct X
template <int i> struct Y {};
};
-typedef X::template Y<0> y; // { dg-error "template|invalid" }
+typedef X::template Y<0> y; // { dg-error "template|invalid" "" { target c++98 } }
diff --git a/gcc/testsuite/g++.dg/parse/tmpl-outside2.C b/gcc/testsuite/g++.dg/parse/tmpl-outside2.C
new file mode 100644
index 000000000..54d39fa88
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/tmpl-outside2.C
@@ -0,0 +1,19 @@
+// PR c++/50080
+
+template <typename T>
+struct A
+{
+ template <typename U>
+ struct B {};
+};
+
+template <typename T>
+void test()
+{
+ typename A<T>::template B<int> b;
+}
+
+int main()
+{
+ typename A<double>::template B<int> b; // { dg-error "template|expected" "" { target c++98 } }
+}
diff --git a/gcc/testsuite/g++.dg/template/pr29633.C b/gcc/testsuite/g++.dg/template/pr29633.C
new file mode 100644
index 000000000..3e0254a46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr29633.C
@@ -0,0 +1,29 @@
+// PR c++/29633
+
+template <typename T>
+struct Class1
+{
+ void testfn1(void);
+};
+
+template <typename T>
+class Class2
+{
+public:
+ void testfn2(void)
+ {
+ Class1<T> * tc_a;
+ do
+ {
+ int x = 0;
+ }
+ while (tc_a && tc_a->testfn1); // { dg-error "invalid use of member" }
+ }
+};
+
+int main(void)
+{
+ Class2<int> tc2;
+ tc2.testfn2();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/template/qualttp18.C b/gcc/testsuite/g++.dg/template/qualttp18.C
index 31dfa6a83..691517fd3 100644
--- a/gcc/testsuite/g++.dg/template/qualttp18.C
+++ b/gcc/testsuite/g++.dg/template/qualttp18.C
@@ -14,7 +14,7 @@ template <template <class> class TT> struct X
struct C
{
- X<A::template B> x; // { dg-error "" }
+ X<A::template B> x; // { dg-error "template" "" { target c++98 } }
};
int main()
diff --git a/gcc/testsuite/g++.dg/tls/thread_local-cse.C b/gcc/testsuite/g++.dg/tls/thread_local-cse.C
index 47c6aede3..29553d2ba 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local-cse.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local-cse.C
@@ -1,11 +1,11 @@
// Test for CSE of the wrapper function: we should only call it once
// for the two references to ir.
+// { dg-do run }
// { dg-options "-std=c++11 -O -fno-inline -save-temps" }
// { dg-require-effective-target tls_runtime }
// { dg-require-alias }
// { dg-final { scan-assembler-times "call *_ZTW2ir" 1 { xfail *-*-* } } }
// { dg-final cleanup-saved-temps }
-// { dg-do run }
// XFAILed until the back end supports a way to mark a function as cseable
// though not pure.
diff --git a/gcc/testsuite/g++.dg/tls/thread_local-wrap4.C b/gcc/testsuite/g++.dg/tls/thread_local-wrap4.C
index 130114811..7c8481cc2 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local-wrap4.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local-wrap4.C
@@ -2,6 +2,7 @@
// copy per shared object.
// { dg-require-effective-target tls }
+// { dg-require-effective-target fpic }
// { dg-options "-std=c++11 -fPIC" }
// { dg-final { scan-assembler-not "_ZTW1i@PLT" { target i?86-*-* x86_64-*-* } } }
diff --git a/gcc/testsuite/g++.dg/tls/thread_local7g.C b/gcc/testsuite/g++.dg/tls/thread_local7g.C
index 696059817..3479aeb31 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local7g.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local7g.C
@@ -3,7 +3,7 @@
// { dg-require-alias }
// The reference temp should be TLS, not normal data.
-// { dg-final { scan-assembler-not "\\.data" } }
+// { dg-final { scan-assembler-not "\\.data" { target tls_native } } }
thread_local int&& ir = 42;
diff --git a/gcc/testsuite/g++.dg/torture/predcom-1.C b/gcc/testsuite/g++.dg/torture/predcom-1.C
index c668cac60..9e9a4b38c 100644
--- a/gcc/testsuite/g++.dg/torture/predcom-1.C
+++ b/gcc/testsuite/g++.dg/torture/predcom-1.C
@@ -1,5 +1,5 @@
/* Test for ICE in predictive commoning with empty loop header block
- on arm-none-linux-gnueabi. */
+ on arm-none-linux-*. */
struct Foo
{
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/enum6.C b/gcc/testsuite/g++.old-deja/g++.jason/enum6.C
index 7be0cd868..97bc2bafe 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/enum6.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/enum6.C
@@ -7,10 +7,10 @@
// enum-size attributes should only be emitted if there are values of
// enum type that can escape the compilation unit, gcc cannot currently
// detect this; if this facility is added then this linker option should
-// not be needed. arm-*-linux*eabi should be a good approximation to
+// not be needed. arm-*-linux* should be a good approximation to
// those platforms where the EABI supplement defines enum values to be
// 32 bits wide.
-// { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+// { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux* } }
#include <limits.h>
diff --git a/gcc/testsuite/g++.old-deja/g++.law/enum9.C b/gcc/testsuite/g++.old-deja/g++.law/enum9.C
index 5a74b2f6f..e4045b50b 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/enum9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/enum9.C
@@ -7,10 +7,10 @@
// enum-size attributes should only be emitted if there are values of
// enum type that can escape the compilation unit, gcc cannot currently
// detect this; if this facility is added then this linker option should
-// not be needed. arm-*-linux*eabi should be a good approximation to
+// not be needed. arm-*-linux* should be a good approximation to
// those platforms where the EABI supplement defines enum values to be
// 32 bits wide.
-// { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+// { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux* } }
// GROUPS passed enums
extern "C" int printf (const char *, ...);
diff --git a/gcc/testsuite/g++.old-deja/g++.other/enum4.C b/gcc/testsuite/g++.old-deja/g++.other/enum4.C
index 429e8127c..3c8bb0c08 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/enum4.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/enum4.C
@@ -9,10 +9,10 @@
// enum-size attributes should only be emitted if there are values of
// enum type that can escape the compilation unit, gcc cannot currently
// detect this; if this facility is added then this linker option should
-// not be needed. arm-*-linux*eabi should be a good approximation to
+// not be needed. arm-*-linux* should be a good approximation to
// those platforms where the EABI supplement defines enum values to be
// 32 bits wide.
-// { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+// { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux* } }
enum E {
a = -312
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C
index 99b4cd384..51a66fd41 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C
@@ -12,5 +12,4 @@ public:
template<template<class> class>
class Y {
};
-Q::template X<int> x; // { dg-error "" } template syntax
-
+Q::template X<int> x; // { dg-error "template" "" { target c++98 } }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload13.C b/gcc/testsuite/g++.old-deja/g++.pt/overload13.C
index f66f1038c..9c985141f 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/overload13.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/overload13.C
@@ -7,5 +7,5 @@ struct A {
int main ()
{
A a;
- return a.template f (0); // { dg-error "" }
+ return a.template f (0); // { dg-error "template" "" { target c++98 } }
}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54925.c b/gcc/testsuite/gcc.c-torture/compile/pr54925.c
new file mode 100644
index 000000000..72349c9d7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr54925.c
@@ -0,0 +1,27 @@
+/* PR target/54925 */
+extern int bar;
+extern void foo (int *);
+static unsigned char *
+nr_memcpy (unsigned char *, unsigned char *, unsigned short);
+
+void
+baz (char *buf, unsigned short len)
+{
+ unsigned char data[10];
+ if (len == 0)
+ return;
+ nr_memcpy (data, (unsigned char *) buf, len);
+ foo (&bar);
+}
+
+static unsigned char *
+nr_memcpy (unsigned char * to, unsigned char * from, unsigned short len)
+{
+ unsigned char *p = to;
+ while (len > 0)
+ {
+ len--;
+ *to++ = *from++;
+ }
+ return p;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-24.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-24.c
new file mode 100644
index 000000000..05e8dd144
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-24.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2" } */
+/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
+#pragma GCC diagnostic error "-Wstrict-overflow"
+
+int
+foo (int i)
+{
+ return __builtin_abs (i) >= 0; /* { dg-error "assuming signed overflow does not occur" "correct warning" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
index 7061b1041..9b731470e 100644
--- a/gcc/testsuite/gcc.dg/builtin-apply2.c
+++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
@@ -17,6 +17,9 @@
E, F and G are passed on stack. So the size of the stack argument
data is 20. */
#define STACK_ARGUMENTS_SIZE 20
+#elif defined __MMIX__
+/* No parameters on stack for bar. */
+#define STACK_ARGUMENTS_SIZE 0
#else
#define STACK_ARGUMENTS_SIZE 64
#endif
diff --git a/gcc/testsuite/gcc.dg/guality/pr54796.c b/gcc/testsuite/gcc.dg/guality/pr54796.c
new file mode 100644
index 000000000..f58e5a02c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54796.c
@@ -0,0 +1,25 @@
+/* PR debug/54796 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+bar (char *a, int b)
+{
+ __asm volatile ("" : "+r" (a), "+r" (b) : : "memory");
+}
+
+__attribute__((noinline, noclone)) void
+foo (int a, int b)
+{
+ int c = a;
+ char d[b]; /* { dg-final { gdb-test 17 "a" "5" } } */
+ bar (d, 2); /* { dg-final { gdb-test 17 "b" "6" } } */
+ bar (d, 4); /* { dg-final { gdb-test 17 "c" "5" } } */
+}
+
+int
+main ()
+{
+ foo (5, 6);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr54920.c b/gcc/testsuite/gcc.dg/torture/pr54920.c
new file mode 100644
index 000000000..d1622f765
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr54920.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+typedef short __v8hi __attribute__ ((__vector_size__ (16)));
+typedef long long __m128i __attribute__ ((__vector_size__ (16)));
+int a;
+__m128i b;
+
+void
+fn1 ()
+{
+ while (1)
+ b = (__m128i) (__v8hi) { a, 0, 0, 0, 0, 0 };
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
index 6ba587188..cbb38efc8 100644
--- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
@@ -16,6 +16,9 @@
E, F and G are passed on stack. So the size of the stack argument
data is 20. */
#define STACK_ARGUMENTS_SIZE 20
+#elif defined __MMIX__
+/* No parameters on stack for bar. */
+#define STACK_ARGUMENTS_SIZE 0
#else
#define STACK_ARGUMENTS_SIZE 64
#endif
diff --git a/gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c b/gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c
new file mode 100644
index 000000000..50ee9e44f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c
@@ -0,0 +1,40 @@
+/* { dg-options "-O2 -fdump-rtl-expand-all" } */
+int g;
+
+__attribute__((noinline)) void foo (int n)
+{
+ switch (n)
+ {
+ case 1:
+ g++; break;
+ case 2:
+ g += 2; break;
+ case 3:
+ g += 1; break;
+ case 4:
+ g += 3; break;
+ case 5:
+ g += 4; break;
+ case 6:
+ g += 5; break;
+ case 7:
+ g += 6; break;
+ case 8:
+ g += 7; break;
+ case 9:
+ g += 8; break;
+ default:
+ g += 8; break;
+ }
+}
+
+int main ()
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+ foo ((i * i) % 5);
+ return 0;
+}
+/* { dg-final-use { scan-rtl-dump-times ";; basic block\[^\\n\]*count 4000" 2 "expand"} } */
+/* { dg-final-use { scan-rtl-dump-times ";; basic block\[^\\n\]*count 2000" 1 "expand"} } */
+/* { dg-final-use { cleanup-rtl-dump "expand" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c b/gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c
new file mode 100644
index 000000000..07d4363d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c
@@ -0,0 +1,40 @@
+/* { dg-options "-O2 -fdump-rtl-expand-all" } */
+int g;
+
+__attribute__((noinline)) void foo (int n)
+{
+ switch (n)
+ {
+ case 99:
+ g += 2; break;
+ case 1:
+ g++; break;
+ case 100:
+ g += 1; break;
+ case 4:
+ g += 3; break;
+ case 5:
+ g += 4; break;
+ case 6:
+ g += 5; break;
+ case 7:
+ g += 6; break;
+ case 8:
+ g += 7; break;
+ case 9:
+ g += 8; break;
+ default:
+ g += 8; break;
+ }
+}
+
+int main ()
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+ foo ((i * i) % 5);
+ return 0;
+}
+/* { dg-final-use { scan-rtl-dump-times ";; basic block\[^\\n\]*count 4000" 2 "expand"} } */
+/* { dg-final-use { scan-rtl-dump-times ";; basic block\[^\\n\]*count 2000" 1 "expand"} } */
+/* { dg-final-use { cleanup-rtl-dump "expand" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c
index fe40bed58..5c280b3f0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-loop-distribution -ftree-loop-distribute-patterns -fdump-tree-ldist-details" } */
+/* { dg-options "-O2 -ftree-loop-distribution -ftree-loop-distribute-patterns -fdump-tree-ldist-details -fdisable-tree-cunroll -fdisable-tree-cunrolli" } */
typedef int mad_fixed_t;
struct mad_pcm
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr54915.c b/gcc/testsuite/gcc.dg/tree-ssa/pr54915.c
new file mode 100644
index 000000000..1e11df198
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr54915.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+typedef double v4df __attribute__ ((__vector_size__ (32)));
+
+void f (v2df *ret, v4df* xp)
+{
+ v4df x = *xp;
+ v2df xx = { x[2], x[3] };
+ *ret = xx;
+}
diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv8a-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv8a-arm.c
new file mode 100644
index 000000000..1fab3c8a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/ftest-armv8a-arm.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_nothumb } */
+/* { dg-require-effective-target arm_arch_v8a_multilib } */
+/* { dg-options "-marm" } */
+/* { dg-add-options arm_arch_v8a } */
+
+#include "ftest-support-arm.h"
+
+int
+main (void)
+{
+ return ftest (ARCH_V8A);
+}
+
diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv8a-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv8a-thumb.c
new file mode 100644
index 000000000..c57f4cec2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/ftest-armv8a-thumb.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_eabi } */
+/* { dg-require-effective-target arm_arch_v8a_multilib } */
+/* { dg-options "-mthumb" } */
+/* { dg-add-options arm_arch_v8a } */
+
+#include "ftest-support-thumb.h"
+
+int
+main (void)
+{
+ return ftest (ARCH_V8A);
+}
+
diff --git a/gcc/testsuite/gcc.target/arm/ftest-support-arm.h b/gcc/testsuite/gcc.target/arm/ftest-support-arm.h
index 512d50e83..259207432 100644
--- a/gcc/testsuite/gcc.target/arm/ftest-support-arm.h
+++ b/gcc/testsuite/gcc.target/arm/ftest-support-arm.h
@@ -26,4 +26,5 @@ int feature_matrix[ARCH_COUNT][NUM_FEATURES] =
{7, 1, 2, 'A', 1, 15, 1, 1, 1, 1, 1}, /* ARCH_V7A. */
{7, 1, 2, 'R', 1, 15, 1, 1, 1, 1, 1}, /* ARCH_V7R. */
{7, 0, 2, 'M', 1, 7, 1, 0, 0, 1, 1}, /* ARCH_V7M. */
- {7, 0, 2, 'M', 1, 7, 1, 1, 0, 1, 1}}; /* ARCH_V7EM. */
+ {7, 0, 2, 'M', 1, 7, 1, 1, 0, 1, 1}, /* ARCH_V7EM. */
+ {8, 1, 2, 'A', 1, 15, 1, 1, 1, 1, 1}}; /* ARCH_V8A. */
diff --git a/gcc/testsuite/gcc.target/arm/ftest-support-thumb.h b/gcc/testsuite/gcc.target/arm/ftest-support-thumb.h
index 99918310e..a58799968 100644
--- a/gcc/testsuite/gcc.target/arm/ftest-support-thumb.h
+++ b/gcc/testsuite/gcc.target/arm/ftest-support-thumb.h
@@ -26,4 +26,5 @@ int feature_matrix[ARCH_COUNT][NUM_FEATURES] =
{7, 1, 2, 'A', 1, 15, 1, 1, 1, 1, 1}, /* ARCH_V7A. */
{7, 1, 2, 'R', 1, 15, 1, 1, 1, 1, 1}, /* ARCH_V7R. */
{7, 0, 2, 'M', 1, 7, 1, 0, 0, 1, 1}, /* ARCH_V7M. */
- {7, 0, 2, 'M', 1, 7, 1, 1, 1, 1, 1}}; /* ARCH_V7EM. */
+ {7, 0, 2, 'M', 1, 7, 1, 1, 1, 1, 1}, /* ARCH_V7EM. */
+ {8, 1, 2, 'A', 1, 15, 1, 1, 1, 1, 1}}; /* ARCH_V8A. */
diff --git a/gcc/testsuite/gcc.target/arm/ftest-support.h b/gcc/testsuite/gcc.target/arm/ftest-support.h
index c5f98105b..5983760ee 100644
--- a/gcc/testsuite/gcc.target/arm/ftest-support.h
+++ b/gcc/testsuite/gcc.target/arm/ftest-support.h
@@ -22,6 +22,7 @@ enum architecture {
ARCH_V7R,
ARCH_V7M,
ARCH_V7EM,
+ ARCH_V8A,
ARCH_COUNT
};
diff --git a/gcc/testsuite/gcc.target/arm/neon/vfmaQf32.c b/gcc/testsuite/gcc.target/arm/neon/vfmaQf32.c
new file mode 100644
index 000000000..d400163a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vfmaQf32.c
@@ -0,0 +1,22 @@
+/* Test the `vfmaQf32' ARM Neon intrinsic. */
+/* This file was autogenerated by neon-testgen. */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_neonv2_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_neonv2 } */
+
+#include "arm_neon.h"
+
+void test_vfmaQf32 (void)
+{
+ float32x4_t out_float32x4_t;
+ float32x4_t arg0_float32x4_t;
+ float32x4_t arg1_float32x4_t;
+ float32x4_t arg2_float32x4_t;
+
+ out_float32x4_t = vfmaq_f32 (arg0_float32x4_t, arg1_float32x4_t, arg2_float32x4_t);
+}
+
+/* { dg-final { scan-assembler "vfma\.f32\[ \]+\[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vfmaf32.c b/gcc/testsuite/gcc.target/arm/neon/vfmaf32.c
new file mode 100644
index 000000000..988328dd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vfmaf32.c
@@ -0,0 +1,22 @@
+/* Test the `vfmaf32' ARM Neon intrinsic. */
+/* This file was autogenerated by neon-testgen. */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_neonv2_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_neonv2 } */
+
+#include "arm_neon.h"
+
+void test_vfmaf32 (void)
+{
+ float32x2_t out_float32x2_t;
+ float32x2_t arg0_float32x2_t;
+ float32x2_t arg1_float32x2_t;
+ float32x2_t arg2_float32x2_t;
+
+ out_float32x2_t = vfma_f32 (arg0_float32x2_t, arg1_float32x2_t, arg2_float32x2_t);
+}
+
+/* { dg-final { scan-assembler "vfma\.f32\[ \]+\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vfmsQf32.c b/gcc/testsuite/gcc.target/arm/neon/vfmsQf32.c
new file mode 100644
index 000000000..247a8edfd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vfmsQf32.c
@@ -0,0 +1,22 @@
+/* Test the `vfmsQf32' ARM Neon intrinsic. */
+/* This file was autogenerated by neon-testgen. */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_neonv2_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_neonv2 } */
+
+#include "arm_neon.h"
+
+void test_vfmsQf32 (void)
+{
+ float32x4_t out_float32x4_t;
+ float32x4_t arg0_float32x4_t;
+ float32x4_t arg1_float32x4_t;
+ float32x4_t arg2_float32x4_t;
+
+ out_float32x4_t = vfmsq_f32 (arg0_float32x4_t, arg1_float32x4_t, arg2_float32x4_t);
+}
+
+/* { dg-final { scan-assembler "vfms\.f32\[ \]+\[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+, \[qQ\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vfmsf32.c b/gcc/testsuite/gcc.target/arm/neon/vfmsf32.c
new file mode 100644
index 000000000..7f9e8570d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon/vfmsf32.c
@@ -0,0 +1,22 @@
+/* Test the `vfmsf32' ARM Neon intrinsic. */
+/* This file was autogenerated by neon-testgen. */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_neonv2_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_neonv2 } */
+
+#include "arm_neon.h"
+
+void test_vfmsf32 (void)
+{
+ float32x2_t out_float32x2_t;
+ float32x2_t arg0_float32x2_t;
+ float32x2_t arg1_float32x2_t;
+ float32x2_t arg2_float32x2_t;
+
+ out_float32x2_t = vfms_f32 (arg0_float32x2_t, arg1_float32x2_t, arg2_float32x2_t);
+}
+
+/* { dg-final { scan-assembler "vfms\.f32\[ \]+\[dD\]\[0-9\]+, \[dD\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/synchronize.c b/gcc/testsuite/gcc.target/arm/synchronize.c
index 8626d8ee0..7ef10e2d9 100644
--- a/gcc/testsuite/gcc.target/arm/synchronize.c
+++ b/gcc/testsuite/gcc.target/arm/synchronize.c
@@ -1,4 +1,4 @@
-/* { dg-final { scan-assembler "__sync_synchronize|dmb|mcr" { target arm*-*-linux-*eabi } } } */
+/* { dg-final { scan-assembler "__sync_synchronize|dmb|mcr" { target arm*-*-linux-* } } } */
void *foo (void)
{
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c
index c2511c643..e7eef6d7a 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c
@@ -14,6 +14,6 @@ avx_test (void)
c[i] = a[i] * b[i+3];
}
-/* { dg-final { scan-assembler-not "avx_movups256/1" } } */
-/* { dg-final { scan-assembler "sse_movups/1" } } */
+/* { dg-final { scan-assembler-not "avx_loadups256" } } */
+/* { dg-final { scan-assembler "sse_loadups" } } */
/* { dg-final { scan-assembler "vinsertf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c
index 9d7167304..3f4fbf764 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c
@@ -24,6 +24,6 @@ avx_test (void)
}
}
-/* { dg-final { scan-assembler-not "avx_movdqu256/1" } } */
-/* { dg-final { scan-assembler "sse2_movdqu/1" } } */
+/* { dg-final { scan-assembler-not "avx_loaddqu256" } } */
+/* { dg-final { scan-assembler "sse2_loaddqu" } } */
/* { dg-final { scan-assembler "vinsert.128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-3.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-3.c
index efb5f573f..b0e0e79bd 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-3.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-3.c
@@ -14,6 +14,6 @@ avx_test (void)
c[i] = a[i] * b[i+3];
}
-/* { dg-final { scan-assembler-not "avx_movupd256/1" } } */
-/* { dg-final { scan-assembler "sse2_movupd/1" } } */
+/* { dg-final { scan-assembler-not "avx_loadupd256" } } */
+/* { dg-final { scan-assembler "sse2_loadupd" } } */
/* { dg-final { scan-assembler "vinsertf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c
index e527b3816..e0eb92b57 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c
@@ -14,6 +14,6 @@ avx_test (void)
b[i] = a[i+3] * 2;
}
-/* { dg-final { scan-assembler "avx_movups256/1" } } */
-/* { dg-final { scan-assembler-not "avx_movups/1" } } */
+/* { dg-final { scan-assembler "avx_loadups256" } } */
+/* { dg-final { scan-assembler-not "sse_loadups" } } */
/* { dg-final { scan-assembler-not "vinsertf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c
index 0b5839669..1a53ba14a 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c
@@ -17,6 +17,6 @@ avx_test (void)
d[i] = c[i] * 20.0;
}
-/* { dg-final { scan-assembler-not "avx_movups256/2" } } */
+/* { dg-final { scan-assembler-not "avx_storeups256" } } */
/* { dg-final { scan-assembler "vmovups.*\\*movv4sf_internal/3" } } */
/* { dg-final { scan-assembler "vextractf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c
index eac460fef..e98d1b684 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c
@@ -24,6 +24,6 @@ avx_test (void)
}
}
-/* { dg-final { scan-assembler-not "avx_movdqu256/2" } } */
+/* { dg-final { scan-assembler-not "avx_storedqu256" } } */
/* { dg-final { scan-assembler "vmovdqu.*\\*movv16qi_internal/3" } } */
/* { dg-final { scan-assembler "vextract.128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
index 753625892..26c993be7 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
@@ -17,6 +17,6 @@ avx_test (void)
d[i] = c[i] * 20.0;
}
-/* { dg-final { scan-assembler-not "avx_movupd256/2" } } */
+/* { dg-final { scan-assembler-not "avx_storeupd256" } } */
/* { dg-final { scan-assembler "vmovupd.*\\*movv2df_internal/3" } } */
/* { dg-final { scan-assembler "vextractf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c
index 39b6f3bef..6d734faa2 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c
@@ -14,7 +14,7 @@ avx_test (void)
b[i+3] = a[i] * c[i];
}
-/* { dg-final { scan-assembler "avx_movups256/2" } } */
-/* { dg-final { scan-assembler-not "avx_movups/2" } } */
+/* { dg-final { scan-assembler "avx_storeups256" } } */
+/* { dg-final { scan-assembler-not "sse_storeups" } } */
/* { dg-final { scan-assembler-not "\\*avx_movv4sf_internal/3" } } */
/* { dg-final { scan-assembler-not "vextractf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_1.c b/gcc/testsuite/gcc.target/i386/l_fma_double_1.c
index 87225ba3e..716acfef6 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_1.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_1.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231pd" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd213sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub213sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213sd" 8 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmadd213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmsub213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213sd" 20 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_2.c b/gcc/testsuite/gcc.target/i386/l_fma_double_2.c
index 8b00fe1ef..01173afb2 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_2.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_2.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_3.c b/gcc/testsuite/gcc.target/i386/l_fma_double_3.c
index 37d062c3a..8cda521a8 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_3.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_3.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231pd" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd213sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub213sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213sd" 8 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmadd213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmsub213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213sd" 20 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_4.c b/gcc/testsuite/gcc.target/i386/l_fma_double_4.c
index 7311913e8..9f2331b51 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_4.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_4.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_5.c b/gcc/testsuite/gcc.target/i386/l_fma_double_5.c
index a7a337be1..9e33975b1 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_5.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_5.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_6.c b/gcc/testsuite/gcc.target/i386/l_fma_double_6.c
index fcb596c55..28d264dd2 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_6.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_6.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_1.c b/gcc/testsuite/gcc.target/i386/l_fma_float_1.c
index b85971ddb..fea0b2061 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_1.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_1.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231ps" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd213ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub213ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213ss" 8 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmadd213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmsub213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213ss" 36 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_2.c b/gcc/testsuite/gcc.target/i386/l_fma_float_2.c
index 9cd02495b..dd5f543f5 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_2.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_2.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_3.c b/gcc/testsuite/gcc.target/i386/l_fma_float_3.c
index 8388cfe03..38853353b 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_3.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_3.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231ps" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd213ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfmsub213ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 8 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213ss" 8 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmadd213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmsub213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213ss" 36 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_4.c b/gcc/testsuite/gcc.target/i386/l_fma_float_4.c
index bb8df6989..5a7bb2178 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_4.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_4.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_5.c b/gcc/testsuite/gcc.target/i386/l_fma_float_5.c
index 3adf99f57..0b0454ed3 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_5.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_5.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_6.c b/gcc/testsuite/gcc.target/i386/l_fma_float_6.c
index ddf05e200..03bf8e848 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_6.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_6.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 16 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-17.c b/gcc/testsuite/gcc.target/sh/pr51244-17.c
new file mode 100644
index 000000000..e7d1ddd2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-17.c
@@ -0,0 +1,297 @@
+/* Check that no unnecessary zero extensions are done on values that are
+ results of arithmetic with T bit inputs. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-not "extu|exts" } } */
+
+int
+test00 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x == y;
+}
+
+int
+test01 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == d;
+ return x == y;
+}
+
+int
+test02 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c == d;
+ return x == y;
+}
+
+int
+test03 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != d;
+ return x == y;
+}
+
+int
+test04 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != d;
+ return x == y;
+}
+
+int
+test05 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x != y;
+}
+
+int
+test06 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x ^ y;
+}
+
+int
+test07 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x | y;
+}
+
+int
+test08 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x & y;
+}
+
+int
+test09 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == d;
+ return x != y;
+}
+
+int
+test10 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c == d;
+ return x != y;
+}
+
+int
+test11 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != d;
+ return x != y;
+}
+
+int
+test12 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != d;
+ return x != y;
+}
+
+int
+test13 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a == b;
+ int y = c == 0;
+ int z = d == e;
+ return x == y || x == z;
+}
+
+int
+test14 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a == b;
+ int y = c == 0;
+ int z = d == e;
+ return x == y && x == z;
+}
+
+int
+test15 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a != b;
+ int y = c == 0;
+ int z = d == e;
+ return x == y || x == z;
+}
+
+int
+test16 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a != b;
+ int y = c == 0;
+ int z = d == e;
+ return x == y && x == z;
+}
+
+int
+test17 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a != b;
+ int y = c != 0;
+ int z = d == e;
+ return x == y || x == z;
+}
+
+int
+test18 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a != b;
+ int y = c != 0;
+ int z = d == e;
+ return x == y && x == z;
+}
+
+int
+test19 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a != b;
+ int y = c != 0;
+ int z = d == e;
+ return x == y || x == z;
+}
+
+int
+test20 (int a, int b, int c, int d, int e, int f)
+{
+ int x = a != b;
+ int y = c != 0;
+ int z = d != e;
+ return x == y && x == z;
+}
+
+int
+test21 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x + y;
+}
+
+int
+test22 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c == 0;
+ return x + y;
+}
+
+int
+test23 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != 0;
+ return x + y;
+}
+
+int
+test24 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x - y;
+}
+
+int
+test25 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c == 0;
+ return x - y;
+}
+
+int
+test26 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != 0;
+ return x - y;
+}
+
+int
+test27 (int a, int b, int c, int d)
+{
+ int x = a == b;
+ int y = c == 0;
+ return x * y;
+}
+
+int
+test28 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c == 0;
+ return x * y;
+}
+
+int
+test29 (int a, int b, int c, int d)
+{
+ int x = a != b;
+ int y = c != 0;
+ return x * y;
+}
+
+int
+test30 (int a, int b)
+{
+ return ((a & 0x7F) == 1)
+ | ((a & 0xFF00) == 0x0200)
+ | ((a & 0xFF0000) == 0x030000);
+}
+
+int
+test31 (int a, int b)
+{
+ return ((a & 0x7F) == 1)
+ | ((a & 0xFF00) == 0x0200)
+ | ((a & 0xFF0000) == 0x030000)
+ | ((a & 0xFF000000) == 0x04000000);
+}
+
+int
+test32 (int* a, int b, int c, volatile char* d)
+{
+ d[1] = a[0] != 0;
+ return b;
+}
+
+int
+test33 (int* a, int b, int c, volatile char* d)
+{
+ d[1] = a[0] == 0;
+ return b;
+}
+
+char
+test34 (int a, int* b)
+{
+ return (b[4] & b[0] & a) == a;
+}
+
+unsigned char
+test35 (int a, int* b)
+{
+ return (b[4] & b[0] & a) == a;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54760-2.c b/gcc/testsuite/gcc.target/sh/pr54760-2.c
index b8a501847..91f3648a5 100644
--- a/gcc/testsuite/gcc.target/sh/pr54760-2.c
+++ b/gcc/testsuite/gcc.target/sh/pr54760-2.c
@@ -9,107 +9,129 @@
/* ---------------------------------------------------------------------------
Simple GBR load.
*/
-#define func(name, type, disp)\
- int \
+#define func(name, rettype, type, disp)\
+ rettype \
name ## _tp_load (void) \
{ \
type* tp = (type*)__builtin_thread_pointer (); \
return tp[disp]; \
}
-func (test00, int, 0)
-func (test01, int, 5)
-func (test02, int, 255)
+func (test00, int, int, 0)
+func (test01, int, int, 5)
+func (test02, int, int, 255)
-func (test03, short, 0)
-func (test04, short, 5)
-func (test05, short, 255)
+func (test03, int, short, 0)
+func (test04, int, short, 5)
+func (test05, int, short, 255)
-func (test06, char, 0)
-func (test07, char, 5)
-func (test08, char, 255)
+func (test06, int, char, 0)
+func (test07, int, char, 5)
+func (test08, int, char, 255)
-func (test09, unsigned int, 0)
-func (test10, unsigned int, 5)
-func (test11, unsigned int, 255)
+func (test09, int, unsigned int, 0)
+func (test10, int, unsigned int, 5)
+func (test11, int, unsigned int, 255)
-func (test12, unsigned short, 0)
-func (test13, unsigned short, 5)
-func (test14, unsigned short, 255)
+func (test12, int, unsigned short, 0)
+func (test13, int, unsigned short, 5)
+func (test14, int, unsigned short, 255)
-func (test15, unsigned char, 0)
-func (test16, unsigned char, 5)
-func (test17, unsigned char, 255)
+func (test15, int, unsigned char, 0)
+func (test16, int, unsigned char, 5)
+func (test17, int, unsigned char, 255)
+
+func (test18, long long, long long, 0)
+func (test19, long long, long long, 5)
+func (test20, long long, long long, 127)
+
+func (test21, long long, unsigned long long, 0)
+func (test22, long long, unsigned long long, 5)
+func (test23, long long, unsigned long long, 127)
#undef func
/* ---------------------------------------------------------------------------
Simple GBR store.
*/
-#define func(name, type, disp)\
+#define func(name, argtype, type, disp)\
void \
- name ## _tp_store (int a) \
+ name ## _tp_store (argtype a) \
{ \
type* tp = (type*)__builtin_thread_pointer (); \
tp[disp] = (type)a; \
}
-func (test00, int, 0)
-func (test01, int, 5)
-func (test02, int, 255)
+func (test00, int, int, 0)
+func (test01, int, int, 5)
+func (test02, int, int, 255)
+
+func (test03, int, short, 0)
+func (test04, int, short, 5)
+func (test05, int, short, 255)
+
+func (test06, int, char, 0)
+func (test07, int, char, 5)
+func (test08, int, char, 255)
-func (test03, short, 0)
-func (test04, short, 5)
-func (test05, short, 255)
+func (test09, int, unsigned int, 0)
+func (test10, int, unsigned int, 5)
+func (test11, int, unsigned int, 255)
-func (test06, char, 0)
-func (test07, char, 5)
-func (test08, char, 255)
+func (test12, int, unsigned short, 0)
+func (test13, int, unsigned short, 5)
+func (test14, int, unsigned short, 255)
-func (test09, unsigned int, 0)
-func (test10, unsigned int, 5)
-func (test11, unsigned int, 255)
+func (test15, int, unsigned char, 0)
+func (test16, int, unsigned char, 5)
+func (test17, int, unsigned char, 255)
-func (test12, unsigned short, 0)
-func (test13, unsigned short, 5)
-func (test14, unsigned short, 255)
+func (test18, long long, long long, 0)
+func (test19, long long, long long, 5)
+func (test20, long long, long long, 127)
-func (test15, unsigned char, 0)
-func (test16, unsigned char, 5)
-func (test17, unsigned char, 255)
+func (test21, long long, unsigned long long, 0)
+func (test22, long long, unsigned long long, 5)
+func (test23, long long, unsigned long long, 127)
#undef func
/* ---------------------------------------------------------------------------
Arithmetic on the result of a GBR load.
*/
-#define func(name, type, disp, op, opname)\
- int \
- name ## _tp_load_arith_ ##opname (int a) \
+#define func(name, retargtype, type, disp, op, opname)\
+ retargtype \
+ name ## _tp_load_arith_ ##opname (retargtype a) \
{ \
type* tp = (type*)__builtin_thread_pointer (); \
return tp[disp] op a; \
}
#define funcs(op, opname) \
- func (test00, int, 0, op, opname) \
- func (test01, int, 5, op, opname) \
- func (test02, int, 255, op, opname) \
- func (test03, short, 0, op, opname) \
- func (test04, short, 5, op, opname) \
- func (test05, short, 255, op, opname) \
- func (test06, char, 0, op, opname) \
- func (test07, char, 5, op, opname) \
- func (test08, char, 255, op, opname) \
- func (test09, unsigned int, 0, op, opname) \
- func (test10, unsigned int, 5, op, opname) \
- func (test11, unsigned int, 255, op, opname) \
- func (test12, unsigned short, 0, op, opname) \
- func (test13, unsigned short, 5, op, opname) \
- func (test14, unsigned short, 255, op, opname) \
- func (test15, unsigned char, 0, op, opname) \
- func (test16, unsigned char, 5, op, opname) \
- func (test17, unsigned char, 255, op, opname) \
+ func (test00, int, int, 0, op, opname) \
+ func (test01, int, int, 5, op, opname) \
+ func (test02, int, int, 255, op, opname) \
+ func (test03, int, short, 0, op, opname) \
+ func (test04, int, short, 5, op, opname) \
+ func (test05, int, short, 255, op, opname) \
+ func (test06, int, char, 0, op, opname) \
+ func (test07, int, char, 5, op, opname) \
+ func (test08, int, char, 255, op, opname) \
+ func (test09, int, unsigned int, 0, op, opname) \
+ func (test10, int, unsigned int, 5, op, opname) \
+ func (test11, int, unsigned int, 255, op, opname) \
+ func (test12, int, unsigned short, 0, op, opname) \
+ func (test13, int, unsigned short, 5, op, opname) \
+ func (test14, int, unsigned short, 255, op, opname) \
+ func (test15, int, unsigned char, 0, op, opname) \
+ func (test16, int, unsigned char, 5, op, opname) \
+ func (test17, int, unsigned char, 255, op, opname) \
+ func (test18, long long, long long, 0, op, opname) \
+ func (test19, long long, long long, 5, op, opname) \
+ func (test20, long long, long long, 127, op, opname) \
+ func (test21, long long, unsigned long long, 0, op, opname) \
+ func (test22, long long, unsigned long long, 5, op, opname) \
+ func (test23, long long, unsigned long long, 127, op, opname) \
funcs (+, plus)
funcs (-, minus)
@@ -124,8 +146,8 @@ funcs (^, xor)
/* ---------------------------------------------------------------------------
Arithmetic of the result of two GBR loads.
*/
-#define func(name, type, disp0, disp1, op, opname)\
- int \
+#define func(name, rettype, type, disp0, disp1, op, opname)\
+ rettype \
name ## _tp_load_load_arith_ ##opname (void) \
{ \
type* tp = (type*)__builtin_thread_pointer (); \
@@ -133,18 +155,22 @@ funcs (^, xor)
}
#define funcs(op, opname) \
- func (test00, int, 0, 5, op, opname) \
- func (test02, int, 1, 255, op, opname) \
- func (test03, short, 0, 5, op, opname) \
- func (test05, short, 1, 255, op, opname) \
- func (test06, char, 0, 5, op, opname) \
- func (test08, char, 1, 255, op, opname) \
- func (test09, unsigned int, 0, 5, op, opname) \
- func (test11, unsigned int, 1, 255, op, opname) \
- func (test12, unsigned short, 0, 5, op, opname) \
- func (test14, unsigned short, 1, 255, op, opname) \
- func (test15, unsigned char, 0, 5, op, opname) \
- func (test17, unsigned char, 1, 255, op, opname) \
+ func (test00, int, int, 0, 5, op, opname) \
+ func (test02, int, int, 1, 255, op, opname) \
+ func (test03, int, short, 0, 5, op, opname) \
+ func (test05, int, short, 1, 255, op, opname) \
+ func (test06, int, char, 0, 5, op, opname) \
+ func (test08, int, char, 1, 255, op, opname) \
+ func (test09, int, unsigned int, 0, 5, op, opname) \
+ func (test11, int, unsigned int, 1, 255, op, opname) \
+ func (test12, int, unsigned short, 0, 5, op, opname) \
+ func (test14, int, unsigned short, 1, 255, op, opname) \
+ func (test15, int, unsigned char, 0, 5, op, opname) \
+ func (test17, int, unsigned char, 1, 255, op, opname) \
+ func (test18, long long, long long, 0, 5, op, opname) \
+ func (test19, long long, long long, 1, 127, op, opname) \
+ func (test20, long long, unsigned long long, 0, 5, op, opname) \
+ func (test21, long long, unsigned long long, 1, 127, op, opname) \
funcs (+, plus)
funcs (-, minus)
@@ -180,6 +206,10 @@ func (test12, unsigned short, 0, 5)
func (test14, unsigned short, 1, 255)
func (test15, unsigned char, 0, 5)
func (test17, unsigned char, 1, 255)
+func (test18, long long, 0, 5)
+func (test19, long long, 1, 127)
+func (test20, unsigned long long, 0, 5)
+func (test21, unsigned long long, 1, 127)
#undef func
@@ -187,33 +217,39 @@ func (test17, unsigned char, 1, 255)
GBR load, arithmetic, GBR store
*/
-#define func(name, type, disp, op, opname)\
+#define func(name, argtype, type, disp, op, opname)\
void \
- name ## _tp_load_arith_store_ ##opname (int a) \
+ name ## _tp_load_arith_store_ ##opname (argtype a) \
{ \
type* tp = (type*)__builtin_thread_pointer (); \
tp[disp] op a; \
}
#define funcs(op, opname) \
- func (test00, int, 0, op, opname) \
- func (test01, int, 5, op, opname) \
- func (test02, int, 255, op, opname) \
- func (test03, short, 0, op, opname) \
- func (test04, short, 5, op, opname) \
- func (test05, short, 255, op, opname) \
- func (test06, char, 0, op, opname) \
- func (test07, char, 5, op, opname) \
- func (test08, char, 255, op, opname) \
- func (test09, unsigned int, 0, op, opname) \
- func (test10, unsigned int, 5, op, opname) \
- func (test11, unsigned int, 255, op, opname) \
- func (test12, unsigned short, 0, op, opname) \
- func (test13, unsigned short, 5, op, opname) \
- func (test14, unsigned short, 255, op, opname) \
- func (test15, unsigned char, 0, op, opname) \
- func (test16, unsigned char, 5, op, opname) \
- func (test17, unsigned char, 255, op, opname) \
+ func (test00, int, int, 0, op, opname) \
+ func (test01, int, int, 5, op, opname) \
+ func (test02, int, int, 255, op, opname) \
+ func (test03, int, short, 0, op, opname) \
+ func (test04, int, short, 5, op, opname) \
+ func (test05, int, short, 255, op, opname) \
+ func (test06, int, char, 0, op, opname) \
+ func (test07, int, char, 5, op, opname) \
+ func (test08, int, char, 255, op, opname) \
+ func (test09, int, unsigned int, 0, op, opname) \
+ func (test10, int, unsigned int, 5, op, opname) \
+ func (test11, int, unsigned int, 255, op, opname) \
+ func (test12, int, unsigned short, 0, op, opname) \
+ func (test13, int, unsigned short, 5, op, opname) \
+ func (test14, int, unsigned short, 255, op, opname) \
+ func (test15, int, unsigned char, 0, op, opname) \
+ func (test16, int, unsigned char, 5, op, opname) \
+ func (test17, int, unsigned char, 255, op, opname) \
+ func (test18, long long, long long, 0, op, opname) \
+ func (test19, long long, long long, 5, op, opname) \
+ func (test20, long long, long long, 127, op, opname) \
+ func (test21, long long, unsigned long long, 0, op, opname) \
+ func (test22, long long, unsigned long long, 5, op, opname) \
+ func (test23, long long, unsigned long long, 127, op, opname) \
funcs (+=, plus)
funcs (-=, minus)
diff --git a/gcc/testsuite/gcc.target/sh/pr54760-4.c b/gcc/testsuite/gcc.target/sh/pr54760-4.c
new file mode 100644
index 000000000..3ee36a313
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54760-4.c
@@ -0,0 +1,19 @@
+/* Check that the GBR address optimization does not combine a gbr store
+ and its use when a function call is inbetween, when GBR is a call used
+ register, i.e. it is invalidated by function calls. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1 -fcall-used-gbr" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler "stc\tgbr" } } */
+
+extern int test00 (void);
+int
+test01 (int x)
+{
+ /* We must see a stc gbr,rn before the function call, because
+ a function call could modify the gbr. In this case the user requests
+ the old gbr value, before the function call. */
+ int* p = (int*)__builtin_thread_pointer ();
+ p[5] = test00 ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/sh/torture/pr34777.c b/gcc/testsuite/gcc.target/sh/torture/pr34777.c
new file mode 100644
index 000000000..b2ec56adf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/torture/pr34777.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-additional-options "-fschedule-insns -fPIC -mprefergot" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+
+static __inline __attribute__ ((__always_inline__)) void *
+_dl_mmap (void * start, int length, int prot, int flags, int fd,
+ int offset)
+{
+ register long __sc3 __asm__ ("r3") = 90;
+ register long __sc4 __asm__ ("r4") = (long) start;
+ register long __sc5 __asm__ ("r5") = (long) length;
+ register long __sc6 __asm__ ("r6") = (long) prot;
+ register long __sc7 __asm__ ("r7") = (long) flags;
+ register long __sc0 __asm__ ("r0") = (long) fd;
+ register long __sc1 __asm__ ("r1") = (long) offset;
+ __asm__ __volatile__ ("trapa %1"
+ : "=z" (__sc0)
+ : "i" (0x10 + 6), "0" (__sc0), "r" (__sc4),
+ "r" (__sc5), "r" (__sc6), "r" (__sc7),
+ "r" (__sc3), "r" (__sc1)
+ : "memory" );
+}
+
+extern int _dl_pagesize;
+void
+_dl_dprintf(int fd, const char *fmt, ...)
+{
+ static char *buf;
+ buf = _dl_mmap ((void *) 0, _dl_pagesize, 0x1 | 0x2, 0x02 | 0x20, -1, 0);
+}
diff --git a/gcc/testsuite/gcc.target/sh/torture/sh-torture.exp b/gcc/testsuite/gcc.target/sh/torture/sh-torture.exp
new file mode 100644
index 000000000..f025aa3ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/torture/sh-torture.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program 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 program 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `gcc-dg.exp' driver, looping over
+# optimization options.
+
+# Exit immediately if this isn't a SH target.
+if { ![istarget sh*-*-*] } then {
+ return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gfortran.dg/class_optional_1.f90 b/gcc/testsuite/gfortran.dg/class_optional_1.f90
new file mode 100644
index 000000000..2b408dbda
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_optional_1.f90
@@ -0,0 +1,175 @@
+! { dg-do run }
+! { dg-options "-fcoarray=single" }
+!
+! PR fortran/50981
+! PR fortran/54618
+!
+
+ implicit none
+ type t
+ integer, allocatable :: i
+ end type t
+ type, extends (t):: t2
+ integer, allocatable :: j
+ end type t2
+
+ class(t), allocatable :: xa, xa2(:), xac[:], xa2c(:)[:]
+ class(t), pointer :: xp, xp2(:)
+
+ xp => null()
+ xp2 => null()
+
+ call suba(alloc=.false., prsnt=.false.)
+ call suba(xa, alloc=.false., prsnt=.true.)
+ if (.not. allocated (xa)) call abort ()
+ if (.not. allocated (xa%i)) call abort ()
+ if (xa%i /= 5) call abort ()
+ xa%i = -3
+ call suba(xa, alloc=.true., prsnt=.true.)
+ if (allocated (xa)) call abort ()
+
+ call suba2(alloc=.false., prsnt=.false.)
+ call suba2(xa2, alloc=.false., prsnt=.true.)
+ if (.not. allocated (xa2)) call abort ()
+ if (size (xa2) /= 1) call abort ()
+ if (.not. allocated (xa2(1)%i)) call abort ()
+ if (xa2(1)%i /= 5) call abort ()
+ xa2(1)%i = -3
+ call suba2(xa2, alloc=.true., prsnt=.true.)
+ if (allocated (xa2)) call abort ()
+
+ call subp(alloc=.false., prsnt=.false.)
+ call subp(xp, alloc=.false., prsnt=.true.)
+ if (.not. associated (xp)) call abort ()
+ if (.not. allocated (xp%i)) call abort ()
+ if (xp%i /= 5) call abort ()
+ xp%i = -3
+ call subp(xp, alloc=.true., prsnt=.true.)
+ if (associated (xp)) call abort ()
+
+ call subp2(alloc=.false., prsnt=.false.)
+ call subp2(xp2, alloc=.false., prsnt=.true.)
+ if (.not. associated (xp2)) call abort ()
+ if (size (xp2) /= 1) call abort ()
+ if (.not. allocated (xp2(1)%i)) call abort ()
+ if (xp2(1)%i /= 5) call abort ()
+ xp2(1)%i = -3
+ call subp2(xp2, alloc=.true., prsnt=.true.)
+ if (associated (xp2)) call abort ()
+
+ call subac(alloc=.false., prsnt=.false.)
+ call subac(xac, alloc=.false., prsnt=.true.)
+ if (.not. allocated (xac)) call abort ()
+ if (.not. allocated (xac%i)) call abort ()
+ if (xac%i /= 5) call abort ()
+ xac%i = -3
+ call subac(xac, alloc=.true., prsnt=.true.)
+ if (allocated (xac)) call abort ()
+
+ call suba2c(alloc=.false., prsnt=.false.)
+ call suba2c(xa2c, alloc=.false., prsnt=.true.)
+ if (.not. allocated (xa2c)) call abort ()
+ if (size (xa2c) /= 1) call abort ()
+ if (.not. allocated (xa2c(1)%i)) call abort ()
+ if (xa2c(1)%i /= 5) call abort ()
+ xa2c(1)%i = -3
+ call suba2c(xa2c, alloc=.true., prsnt=.true.)
+ if (allocated (xa2c)) call abort ()
+
+contains
+ subroutine suba2c(x, prsnt, alloc)
+ class(t), optional, allocatable :: x(:)[:]
+ logical prsnt, alloc
+ if (present (x) .neqv. prsnt) call abort ()
+ if (prsnt) then
+ if (alloc .neqv. allocated(x)) call abort ()
+ if (.not. allocated (x)) then
+ allocate (x(1)[*])
+ x(1)%i = 5
+ else
+ if (x(1)%i /= -3) call abort()
+ deallocate (x)
+ end if
+ end if
+ end subroutine suba2c
+
+ subroutine subac(x, prsnt, alloc)
+ class(t), optional, allocatable :: x[:]
+ logical prsnt, alloc
+ if (present (x) .neqv. prsnt) call abort ()
+ if (present (x)) then
+ if (alloc .neqv. allocated(x)) call abort ()
+ if (.not. allocated (x)) then
+ allocate (x[*])
+ x%i = 5
+ else
+ if (x%i /= -3) call abort()
+ deallocate (x)
+ end if
+ end if
+ end subroutine subac
+
+ subroutine suba2(x, prsnt, alloc)
+ class(t), optional, allocatable :: x(:)
+ logical prsnt, alloc
+ if (present (x) .neqv. prsnt) call abort ()
+ if (prsnt) then
+ if (alloc .neqv. allocated(x)) call abort ()
+ if (.not. allocated (x)) then
+ allocate (x(1))
+ x(1)%i = 5
+ else
+ if (x(1)%i /= -3) call abort()
+ deallocate (x)
+ end if
+ end if
+ end subroutine suba2
+
+ subroutine suba(x, prsnt, alloc)
+ class(t), optional, allocatable :: x
+ logical prsnt, alloc
+ if (present (x) .neqv. prsnt) call abort ()
+ if (present (x)) then
+ if (alloc .neqv. allocated(x)) call abort ()
+ if (.not. allocated (x)) then
+ allocate (x)
+ x%i = 5
+ else
+ if (x%i /= -3) call abort()
+ deallocate (x)
+ end if
+ end if
+ end subroutine suba
+
+ subroutine subp2(x, prsnt, alloc)
+ class(t), optional, pointer :: x(:)
+ logical prsnt, alloc
+ if (present (x) .neqv. prsnt) call abort ()
+ if (present (x)) then
+ if (alloc .neqv. associated(x)) call abort ()
+ if (.not. associated (x)) then
+ allocate (x(1))
+ x(1)%i = 5
+ else
+ if (x(1)%i /= -3) call abort()
+ deallocate (x)
+ end if
+ end if
+ end subroutine subp2
+
+ subroutine subp(x, prsnt, alloc)
+ class(t), optional, pointer :: x
+ logical prsnt, alloc
+ if (present (x) .neqv. prsnt) call abort ()
+ if (present (x)) then
+ if (alloc .neqv. associated(x)) call abort ()
+ if (.not. associated (x)) then
+ allocate (x)
+ x%i = 5
+ else
+ if (x%i /= -3) call abort()
+ deallocate (x)
+ end if
+ end if
+ end subroutine subp
+end
diff --git a/gcc/testsuite/gfortran.dg/class_optional_2.f90 b/gcc/testsuite/gfortran.dg/class_optional_2.f90
new file mode 100644
index 000000000..90b1719c1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_optional_2.f90
@@ -0,0 +1,800 @@
+! { dg-do run }
+! { dg-options "-fcoarray=single" }
+!
+! PR fortran/50981
+! PR fortran/54618
+!
+
+ implicit none
+ type t
+ integer, allocatable :: i
+ end type t
+ type, extends (t):: t2
+ integer, allocatable :: j
+ end type t2
+
+ call s1a1()
+ call s1a()
+ call s1ac1()
+ call s1ac()
+ call s2()
+ call s2p(psnt=.false.)
+ call s2caf()
+ call s2elem()
+ call s2elem_t()
+ call s2elem_t2()
+ call s2t()
+ call s2tp(psnt=.false.)
+ call s2t2()
+ call s2t2p(psnt=.false.)
+
+ call a1a1()
+ call a1a()
+ call a1ac1()
+ call a1ac()
+ call a2()
+ call a2p(psnt=.false.)
+ call a2caf()
+
+ call a3a1()
+ call a3a()
+ call a3ac1()
+ call a3ac()
+ call a4()
+ call a4p(psnt=.false.)
+ call a4caf()
+
+ call ar1a1()
+ call ar1a()
+ call ar1ac1()
+ call ar1ac()
+ call ar()
+ call art()
+ call arp(psnt=.false.)
+ call artp(psnt=.false.)
+
+contains
+
+ subroutine s1a1(z, z2, z3, z4, z5)
+ type(t), optional :: z, z4[*]
+ type(t), pointer, optional :: z2
+ type(t), allocatable, optional :: z3, z5[:]
+ type(t), allocatable :: x
+ type(t), pointer :: y
+ y => null()
+ call s2(x)
+ call s2(y)
+ call s2(z)
+ call s2(z2)
+ call s2(z3)
+ call s2(z4)
+ call s2(z5)
+ call s2p(y,psnt=.true.)
+ call s2p(z2,psnt=.false.)
+ call s2elem(x)
+ call s2elem(y)
+ call s2elem(z)
+ call s2elem(z2)
+ call s2elem(z3)
+ call s2elem(z4)
+ call s2elem(z5)
+ call s2elem_t(x)
+ call s2elem_t(y)
+ call s2elem_t(z)
+! call s2elem_t(z2) ! FIXME: Segfault
+! call s2elem_t(z3) ! FIXME: Segfault
+! call s2elem_t(z4) ! FIXME: Segfault
+! call s2elem_t(z5) ! FIXME: Segfault
+ call s2caf(z4)
+ call s2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+ call s2t(x)
+ call s2t(y)
+ call s2t(z)
+! call s2t(z2) ! FIXME: Segfault
+! call s2t(z3) ! FIXME: Segfault
+! call s2t(z4) ! FIXME: Segfault
+! call s2t(z5) ! FIXME: Segfault
+ call s2tp(y,psnt=.true.)
+ call s2tp(z2,psnt=.false.)
+ end subroutine s1a1
+ subroutine s1a(z, z2, z3, z4, z5)
+ type(t2), optional :: z, z4[*]
+ type(t2), optional, pointer :: z2
+ type(t2), optional, allocatable :: z3, z5[:]
+ type(t2), allocatable :: x
+ type(t2), pointer :: y
+ y => null()
+ call s2(x)
+ call s2(y)
+ call s2(z)
+ call s2(z2)
+ call s2(z3)
+ call s2(z4)
+ call s2(z5)
+ call s2p(y,psnt=.true.)
+ call s2p(z2,psnt=.false.)
+ call s2elem(x)
+ call s2elem(y)
+ call s2elem(z)
+ call s2elem(z2)
+ call s2elem(z3)
+ call s2elem(z4)
+ call s2elem(z5)
+ call s2elem_t2(x)
+ call s2elem_t2(y)
+ call s2elem_t2(z)
+! call s2elem_t2(z2) ! FIXME: Segfault
+! call s2elem_t2(z3) ! FIXME: Segfault
+! call s2elem_t2(z4) ! FIXME: Segfault
+! call s2elem_t2(z5) ! FIXME: Segfault
+ call s2caf(z4)
+ call s2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+ call s2t2(x)
+ call s2t2(y)
+ call s2t2(z)
+! call s2t2(z2) ! FIXME: Segfault
+! call s2t2(z3) ! FIXME: Segfault
+ call s2t2(z4)
+! call s2t2(z5) ! FIXME: Segfault
+ call s2t2p(y,psnt=.true.)
+ call s2t2p(z2,psnt=.false.)
+ end subroutine s1a
+ subroutine s1ac1(z, z2, z3, z4, z5)
+ class(t), optional :: z, z4[*]
+ class(t), optional, pointer :: z2
+ class(t), optional, allocatable :: z3, z5[:]
+ class(t), allocatable :: x
+ class(t), pointer :: y
+ y => null()
+ call s2(x)
+ call s2(y)
+ call s2(z)
+ call s2(z2)
+ call s2(z3)
+ call s2(z4)
+ call s2(z5)
+ call s2p(y,psnt=.true.)
+ call s2p(z2,psnt=.false.)
+ call s2elem(x)
+ call s2elem(y)
+ call s2elem(z)
+ call s2elem(z2)
+ call s2elem(z3)
+ call s2elem(z4)
+ call s2elem(z5)
+ call s2elem_t(x)
+ call s2elem_t(y)
+! call s2elem_t(z) ! FIXME: Segfault
+! call s2elem_t(z2) ! FIXME: Segfault
+! call s2elem_t(z3) ! FIXME: Segfault
+! call s2elem_t(z4) ! FIXME: Segfault
+! call s2elem_t(z5) ! FIXME: Segfault
+ call s2caf(z4)
+ call s2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+ call s2t(x)
+ call s2t(y)
+! call s2t(z) ! FIXME: Segfault
+! call s2t(z2) ! FIXME: Segfault
+! call s2t(z3) ! FIXME: Segfault
+! call s2t(z4) ! FIXME: Segfault
+! call s2t(z5) ! FIXME: Segfault
+ call s2tp(y,psnt=.true.)
+ call s2tp(z2,psnt=.false.)
+ end subroutine s1ac1
+ subroutine s1ac(z, z2, z3, z4, z5)
+ class(t2), optional :: z, z4[*]
+ class(t2), optional, pointer :: z2
+ class(t2), optional, allocatable :: z3, z5[:]
+ class(t2), allocatable :: x
+ class(t2), pointer :: y
+ y => null()
+ call s2(x)
+ call s2(y)
+ call s2(z)
+ call s2(z2)
+ call s2(z3)
+ call s2(z4)
+ call s2(z5)
+ call s2p(y,psnt=.true.)
+ call s2p(z2,psnt=.false.)
+ call s2elem(x)
+ call s2elem(y)
+ call s2elem(z)
+ call s2elem(z2)
+ call s2elem(z3)
+ call s2elem(z4)
+ call s2elem(z5)
+ call s2elem_t2(x)
+! call s2elem_t2(y) ! FIXME: Segfault
+! call s2elem_t2(z) ! FIXME: Segfault
+! call s2elem_t2(z2) ! FIXME: Segfault
+! call s2elem_t2(z3) ! FIXME: Segfault
+! call s2elem_t2(z4) ! FIXME: Segfault
+! call s2elem_t2(z5) ! FIXME: Segfault
+ call s2caf(z4)
+ call s2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+ call s2t2(x)
+ call s2t2(y)
+! call s2t2(z) ! FIXME: Segfault
+! call s2t2(z2) ! FIXME: Segfault
+! call s2t2(z3) ! FIXME: Segfault
+! call s2t2(z4) ! FIXME: Segfault
+! call s2t2(z5) ! FIXME: Segfault
+ call s2t2p(y,psnt=.true.)
+ call s2t2p(z2,psnt=.false.)
+ end subroutine s1ac
+
+ subroutine s2(x)
+ class(t), intent(in), optional :: x
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2
+ subroutine s2p(x,psnt)
+ class(t), intent(in), pointer, optional :: x
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine s2p
+ subroutine s2caf(x)
+ class(t), intent(in), optional :: x[*]
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2caf
+ subroutine s2t(x)
+ type(t), intent(in), optional :: x
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2t
+ subroutine s2t2(x)
+ type(t2), intent(in), optional :: x
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2t2
+ subroutine s2tp(x, psnt)
+ type(t), pointer, intent(in), optional :: x
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine s2tp
+ subroutine s2t2p(x, psnt)
+ type(t2), pointer, intent(in), optional :: x
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine s2t2p
+ impure elemental subroutine s2elem(x)
+ class(t), intent(in), optional :: x
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2elem
+ impure elemental subroutine s2elem_t(x)
+ type(t), intent(in), optional :: x
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2elem_t
+ impure elemental subroutine s2elem_t2(x)
+ type(t2), intent(in), optional :: x
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine s2elem_t2
+
+
+ subroutine a1a1(z, z2, z3, z4, z5)
+ type(t), optional :: z(:), z4(:)[*]
+ type(t), optional, pointer :: z2(:)
+ type(t), optional, allocatable :: z3(:), z5(:)[:]
+ type(t), allocatable :: x(:)
+ type(t), pointer :: y(:)
+ y => null()
+ call a2(x)
+ call a2(y)
+ call a2(z)
+ call a2(z2)
+ call a2(z3)
+ call a2(z4)
+ call a2(z5)
+ call a2p(y,psnt=.true.)
+ call a2p(z2,psnt=.false.)
+ call a2caf(z4)
+ call a2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Segfault
+! call s2elem(y) ! FIXME: Segfault
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t(x) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(y) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(z) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(z2) ! FIXME: Segfault
+! call s2elem_t(z3) ! FIXME: Segfault
+! call s2elem_t(z4) ! FIXME: Segfault
+! call s2elem_t(z5) ! FIXME: Segfault
+ end subroutine a1a1
+ subroutine a1a(z, z2, z3, z4, z5)
+ type(t2), optional :: z(:), z4(:)[*]
+ type(t2), optional, pointer :: z2(:)
+ type(t2), optional, allocatable :: z3(:), z5(:)[:]
+ type(t2), allocatable :: x(:)
+ type(t2), pointer :: y(:)
+ y => null()
+ call a2(x)
+ call a2(y)
+ call a2(z)
+ call a2(z2)
+ call a2(z3)
+ call a2(z4)
+ call a2(z5)
+ call a2p(y,psnt=.true.)
+ call a2p(z2,psnt=.false.)
+ call a2caf(z4)
+ call a2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Segfault
+! call s2elem(y) ! FIXME: Segfault
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t2(x) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t2(y) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t2(z) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t2(z2) ! FIXME: Segfault
+! call s2elem_t2(z3) ! FIXME: Segfault
+! call s2elem_t2(z4) ! FIXME: Segfault
+! call s2elem_t2(z5) ! FIXME: Segfault
+ end subroutine a1a
+ subroutine a1ac1(z, z2, z3, z4, z5)
+ class(t), optional :: z(:), z4(:)[*]
+ class(t), optional, pointer :: z2(:)
+ class(t), optional, allocatable :: z3(:), z5(:)[:]
+ class(t), allocatable :: x(:)
+ class(t), pointer :: y(:)
+ y => null()
+ call a2(x)
+ call a2(y)
+ call a2(z)
+ call a2(z2)
+ call a2(z3)
+ call a2(z4)
+ call a2(z5)
+ call a2p(y,psnt=.true.)
+ call a2p(z2,psnt=.false.)
+ call a2caf(z4)
+ call a2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Segfault
+! call s2elem(y) ! FIXME: Segfault
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t(x) ! FIXME: Segfault
+! call s2elem_t(y) ! FIXME: Segfault
+! call s2elem_t(z) ! FIXME: Segfault
+! call s2elem_t(z2) ! FIXME: Segfault
+! call s2elem_t(z3) ! FIXME: Segfault
+! call s2elem_t(z4) ! FIXME: Segfault
+! call s2elem_t(z5) ! FIXME: Segfault
+ end subroutine a1ac1
+ subroutine a1ac(z, z2, z3, z4, z5)
+ class(t2), optional :: z(:), z4(:)[*]
+ class(t2), optional, pointer :: z2(:)
+ class(t2), optional, allocatable :: z3(:), z5(:)[:]
+ class(t2), allocatable :: x(:)
+ class(t2), pointer :: y(:)
+ y => null()
+ call a2(x)
+ call a2(y)
+ call a2(z)
+ call a2(z2)
+ call a2(z3)
+ call a2(z4)
+ call a2(z5)
+ call a2p(y,psnt=.true.)
+ call a2p(z2,psnt=.false.)
+ call a2caf(z4)
+ call a2caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Segfault
+! call s2elem(y) ! FIXME: Segfault
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t2(x) ! FIXME: Segfault
+! call s2elem_t2(y) ! FIXME: Segfault
+! call s2elem_t2(z) ! FIXME: Segfault
+! call s2elem_t2(z2) ! FIXME: Segfault
+! call s2elem_t2(z3) ! FIXME: Segfault
+! call s2elem_t2(z4) ! FIXME: Segfault
+! call s2elem_t2(z5) ! FIXME: Segfault
+ end subroutine a1ac
+
+ subroutine a2(x)
+ class(t), intent(in), optional :: x(:)
+ if (present (x)) call abort ()
+ ! print *, present(x)
+ end subroutine a2
+ subroutine a2p(x, psnt)
+ class(t), pointer, intent(in), optional :: x(:)
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ ! print *, present(x)
+ end subroutine a2p
+ subroutine a2caf(x)
+ class(t), intent(in), optional :: x(:)[*]
+ if (present (x)) call abort ()
+ ! print *, present(x)
+ end subroutine a2caf
+
+
+ subroutine a3a1(z, z2, z3, z4, z5)
+ type(t), optional :: z(4), z4(4)[*]
+ type(t), optional, pointer :: z2(:)
+ type(t), optional, allocatable :: z3(:), z5(:)[:]
+ type(t), allocatable :: x(:)
+ type(t), pointer :: y(:)
+ y => null()
+ call a4(x)
+ call a4(y)
+ call a4(z)
+ call a4(z2)
+ call a4(z3)
+ call a4(z4)
+ call a4(z5)
+ call a4p(y,psnt=.true.)
+ call a4p(z2,psnt=.false.)
+ call a4t(x)
+ call a4t(y)
+ call a4t(z)
+! call a4t(z2) ! FIXME: Segfault
+! call a4t(z3) ! FIXME: Segfault
+! call a4t(z4) ! FIXME: Segfault
+! call a4t(z5) ! FIXME: Segfault
+ call a4tp(y,psnt=.true.)
+ call a4tp(z2,psnt=.false.)
+ call a4caf(z4)
+ call a4caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Segfault
+! call s2elem(y) ! FIXME: Segfault
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t(x) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(y) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(z) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(z2) ! FIXME: Segfault
+! call s2elem_t(z3) ! FIXME: Segfault
+! call s2elem_t(z4) ! FIXME: Segfault
+! call s2elem_t(z5) ! FIXME: Segfault
+ end subroutine a3a1
+ subroutine a3a(z, z2, z3)
+ type(t2), optional :: z(4)
+ type(t2), optional, pointer :: z2(:)
+ type(t2), optional, allocatable :: z3(:)
+ type(t2), allocatable :: x(:)
+ type(t2), pointer :: y(:)
+ y => null()
+ call a4(x)
+ call a4(y)
+ call a4(z)
+ call a4(z2)
+ call a4(z3)
+ call a4p(y,psnt=.true.)
+ call a4p(z2,psnt=.false.)
+ call a4t2(x)
+ call a4t2(y)
+ call a4t2(z)
+! call a4t2(z2) ! FIXME: Segfault
+! call a4t2(z3) ! FIXME: Segfault
+ call a4t2p(y,psnt=.true.)
+ call a4t2p(z2,psnt=.false.)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Segfault
+! call s2elem(y) ! FIXME: Segfault
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t2(x) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t2(y) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t2(z) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t2(z2) ! FIXME: Segfault
+! call s2elem_t2(z3) ! FIXME: Segfault
+! call s2elem_t2(z4) ! FIXME: Segfault
+! call s2elem_t2(z5) ! FIXME: Segfault
+ end subroutine a3a
+ subroutine a3ac1(z, z2, z3, z4, z5)
+ class(t), optional :: z(4), z4(4)[*]
+ class(t), optional, pointer :: z2(:)
+ class(t), optional, allocatable :: z3(:), z5(:)[:]
+ class(t), allocatable :: x(:)
+ class(t), pointer :: y(:)
+ y => null()
+ call a4(x)
+ call a4(y)
+ call a4(z)
+ call a4(z2)
+ call a4(z3)
+ call a4(z4)
+ call a4(z5)
+ call a4p(y,psnt=.true.)
+ call a4p(z2,psnt=.false.)
+! call a4t(x) ! FIXME: Segfault
+! call a4t(y) ! FIXME: Segfault
+! call a4t(z) ! FIXME: Segfault
+! call a4t(z2) ! FIXME: Segfault
+! call a4t(z3) ! FIXME: Segfault
+! call a4t(z4) ! FIXME: Segfault
+! call a4t(z5) ! FIXME: Segfault
+! call a4tp(y,psnt=.true.) ! FIXME: Segfault
+! call a4tp(z2,psnt=.false.) ! FIXME: Segfault
+ call a4caf(z4)
+ call a4caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+! call s2elem(x) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem(y) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem(z) ! FIXME: Segfault
+! call s2elem(z2) ! FIXME: Segfault
+! call s2elem(z3) ! FIXME: Segfault
+! call s2elem(z4) ! FIXME: Segfault
+! call s2elem(z5) ! FIXME: Segfault
+! call s2elem_t(x) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(y) ! FIXME: Conditional jump or move depends on uninitialised value
+! call s2elem_t(z) ! FIXME: Segfault
+! call s2elem_t(z2) ! FIXME: Segfault
+! call s2elem_t(z3) ! FIXME: Segfault
+! call s2elem_t(z4) ! FIXME: Segfault
+! call s2elem_t(z5) ! FIXME: Segfault
+ end subroutine a3ac1
+ subroutine a3ac(z, z2, z3, z4, z5)
+ class(t2), optional :: z(4), z4(4)[*]
+ class(t2), optional, pointer :: z2(:)
+ class(t2), optional, allocatable :: z3(:), z5(:)[:]
+ class(t2), allocatable :: x(:)
+ class(t2), pointer :: y(:)
+ y => null()
+ call a4(x)
+ call a4(y)
+ call a4(z)
+ call a4(z2)
+ call a4(z3)
+ call a4(z4)
+ call a4(z5)
+ call a4p(y,psnt=.true.)
+ call a4p(z2,psnt=.false.)
+! call a4t2(x) ! FIXME: Segfault
+! call a4t2(y) ! FIXME: Segfault
+! call a4t2(z) ! FIXME: Segfault
+! call a4t2(z2) ! FIXME: Segfault
+! call a4t2(z3) ! FIXME: Segfault
+! call a4t2(z4) ! FIXME: Segfault
+! call a4t2(z5) ! FIXME: Segfault
+! call a4t2p(y,psnt=.true.) ! FIXME: Segfault
+! call a4t2p(z2,psnt=.false.) ! FIXME: Segfault
+ call a4caf(z4)
+ call a4caf(z5)
+ call ar(x)
+ call ar(y)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call ar(z4)
+ call ar(z5)
+ call arp(y,psnt=.true.)
+ call arp(z2,psnt=.false.)
+ end subroutine a3ac
+
+ subroutine a4(x)
+ class(t), intent(in), optional :: x(4)
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine a4
+ subroutine a4p(x, psnt)
+ class(t), pointer, intent(in), optional :: x(:)
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine a4p
+ subroutine a4caf(x)
+ class(t), intent(in), optional :: x(4)[*]
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine a4caf
+ subroutine a4t(x)
+ type(t), intent(in), optional :: x(4)
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine a4t
+ subroutine a4t2(x)
+ type(t2), intent(in), optional :: x(4)
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine a4t2
+ subroutine a4tp(x, psnt)
+ type(t), pointer, intent(in), optional :: x(:)
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine a4tp
+ subroutine a4t2p(x, psnt)
+ type(t2), pointer, intent(in), optional :: x(:)
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine a4t2p
+
+
+ subroutine ar(x)
+ class(t), intent(in), optional :: x(..)
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine ar
+
+ subroutine art(x)
+ type(t), intent(in), optional :: x(..)
+ if (present (x)) call abort ()
+ !print *, present(x)
+ end subroutine art
+
+ subroutine arp(x, psnt)
+ class(t), pointer, intent(in), optional :: x(..)
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine arp
+
+ subroutine artp(x, psnt)
+ type(t), intent(in), pointer, optional :: x(..)
+ logical psnt
+ if (present (x).neqv. psnt) call abort ()
+ !print *, present(x)
+ end subroutine artp
+
+
+
+ subroutine ar1a1(z, z2, z3)
+ type(t), optional :: z(..)
+ type(t), pointer, optional :: z2(..)
+ type(t), allocatable, optional :: z3(..)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call art(z)
+ call art(z2)
+ call art(z3)
+ call arp(z2, .false.)
+ call artp(z2, .false.)
+ end subroutine ar1a1
+ subroutine ar1a(z, z2, z3)
+ type(t2), optional :: z(..)
+ type(t2), optional, pointer :: z2(..)
+ type(t2), optional, allocatable :: z3(..)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call arp(z2, .false.)
+ end subroutine ar1a
+ subroutine ar1ac1(z, z2, z3)
+ class(t), optional :: z(..)
+ class(t), optional, pointer :: z2(..)
+ class(t), optional, allocatable :: z3(..)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+! call art(z) ! FIXME: ICE - This requires packing support for assumed-rank
+! call art(z2)! FIXME: ICE - This requires packing support for assumed-rank
+! call art(z3)! FIXME: ICE - This requires packing support for assumed-rank
+ call arp(z2, .false.)
+! call artp(z2, .false.) ! FIXME: ICE
+ end subroutine ar1ac1
+ subroutine ar1ac(z, z2, z3)
+ class(t2), optional :: z(..)
+ class(t2), optional, pointer :: z2(..)
+ class(t2), optional, allocatable :: z3(..)
+ call ar(z)
+ call ar(z2)
+ call ar(z3)
+ call arp(z2, .false.)
+ end subroutine ar1ac
+end
diff --git a/gcc/testsuite/gfortran.dg/do_1.f90 b/gcc/testsuite/gfortran.dg/do_1.f90
index 171275af3..8ed0f7fb6 100644
--- a/gcc/testsuite/gfortran.dg/do_1.f90
+++ b/gcc/testsuite/gfortran.dg/do_1.f90
@@ -1,4 +1,5 @@
-! { dg-do run }
+! { dg-do run { xfail *-*-* } }
+! XFAIL is tracked in PR 54932
! Program to check corner cases for DO statements.
program do_1
implicit none
diff --git a/gcc/testsuite/gfortran.dg/enum_10.f90 b/gcc/testsuite/gfortran.dg/enum_10.f90
index b387fe339..80e7fca80 100644
--- a/gcc/testsuite/gfortran.dg/enum_10.f90
+++ b/gcc/testsuite/gfortran.dg/enum_10.f90
@@ -1,7 +1,7 @@
! { dg-do run }
! { dg-additional-sources enum_10.c }
! { dg-options "-fshort-enums -w" }
-! { dg-options "-fshort-enums -w -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+! { dg-options "-fshort-enums -w -Wl,--no-enum-size-warning" { target arm*-*-linux* } }
! Make sure short enums are indeed interoperable with the
! corresponding C type.
diff --git a/gcc/testsuite/gfortran.dg/enum_9.f90 b/gcc/testsuite/gfortran.dg/enum_9.f90
index 8a5c60a10..d3187c75b 100644
--- a/gcc/testsuite/gfortran.dg/enum_9.f90
+++ b/gcc/testsuite/gfortran.dg/enum_9.f90
@@ -1,6 +1,6 @@
! { dg-do run }
! { dg-options "-fshort-enums" }
-! { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+! { dg-options "-fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux* } }
! Program to test enumerations when option -fshort-enums is given
program main
diff --git a/gcc/testsuite/gfortran.dg/pr54889.f90 b/gcc/testsuite/gfortran.dg/pr54889.f90
new file mode 100644
index 000000000..68c6bee00
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr54889.f90
@@ -0,0 +1,10 @@
+! PR tree-optimization/54889
+! { dg-do compile }
+! { dg-options "-O3" }
+! { dg-additional-options "-mavx" { target { i?86-*-* x86_64-*-* } } }
+
+subroutine foo(x,y,z)
+ logical, pointer :: x(:,:)
+ integer :: y, z
+ x=x(1:y,1:z)
+end subroutine
diff --git a/gcc/testsuite/gfortran.dg/public_private_module_7.f90 b/gcc/testsuite/gfortran.dg/public_private_module_7.f90
new file mode 100644
index 000000000..d03b7047a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/public_private_module_7.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-O2" }
+!
+! PR fortran/54884
+!
+! Check that get_key_len is not optimized away as it
+! is used in a publicly visible specification expression.
+!
+module m_common_attrs
+ private
+ !...
+ public :: get_key
+contains
+ pure function get_key_len() result(n)
+ n = 5
+ end function get_key_len
+ pure function other() result(n)
+ n = 5
+ end function other
+ ! ...
+ function get_key() result(key)
+ ! ...
+ character(len=get_key_len()) :: key
+ key = ''
+ end function get_key
+end module m_common_attrs
+
+! { dg-final { scan-assembler-not "__m_common_attrs_MOD_other" } }
+! { dg-final { scan-assembler "__m_common_attrs_MOD_get_key_len" } }
diff --git a/gcc/testsuite/gnat.dg/loop_optimization13.adb b/gcc/testsuite/gnat.dg/loop_optimization13.adb
new file mode 100644
index 000000000..ffc516ff7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization13.adb
@@ -0,0 +1,21 @@
+-- { dg-do compile }
+-- { dg-options "-O" }
+
+with Loop_Optimization13_Pkg; use Loop_Optimization13_Pkg;
+
+package body Loop_Optimization13 is
+
+ function F (A : Rec) return Rec is
+ N : constant Integer := A.V'Length / L;
+ Res : Rec
+ := (True, new Complex_Vector' (0 .. A.V'Length / L - 1 => (0.0, 0.0)));
+ begin
+ for I in 0 .. L - 1 loop
+ for J in 0 .. N - 1 loop
+ Res.V (J) := Res.V (J) + A.V (I * N + J);
+ end loop;
+ end loop;
+ return Res;
+ end;
+
+end Loop_Optimization13;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization13.ads b/gcc/testsuite/gnat.dg/loop_optimization13.ads
new file mode 100644
index 000000000..2d3b8e59f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization13.ads
@@ -0,0 +1,17 @@
+with Ada.Numerics.Complex_Types; use Ada.Numerics.Complex_Types;
+
+package Loop_Optimization13 is
+
+ type Complex_Vector is array (Integer range <>) of Complex;
+ type Complex_Vector_Ptr is access Complex_Vector;
+
+ type Rec (Kind : Boolean := False) is record
+ case Kind is
+ when True => V : Complex_Vector_Ptr;
+ when False => null;
+ end case;
+ end record;
+
+ function F (A : Rec) return Rec;
+
+end Loop_Optimization13;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization13_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization13_pkg.ads
new file mode 100644
index 000000000..8f98b6e1f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization13_pkg.ads
@@ -0,0 +1,5 @@
+package Loop_Optimization13_Pkg is
+
+ L : Integer;
+
+end Loop_Optimization13_Pkg;
diff --git a/gcc/testsuite/gnat.dg/unchecked_convert9.adb b/gcc/testsuite/gnat.dg/unchecked_convert9.adb
new file mode 100644
index 000000000..133f3b94c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/unchecked_convert9.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-O -fdump-rtl-final" }
+
+package body Unchecked_Convert9 is
+
+ procedure Proc is
+ L : Unsigned_32 := 16#55557777#;
+ begin
+ Var := Conv (L);
+ end;
+
+end Unchecked_Convert9;
+
+-- { dg-final { scan-rtl-dump-times "set \\(mem/v" 1 "final" } }
+-- { dg-final { cleanup-rtl-dump "final" } }
diff --git a/gcc/testsuite/gnat.dg/unchecked_convert9.ads b/gcc/testsuite/gnat.dg/unchecked_convert9.ads
new file mode 100644
index 000000000..d4595f52a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/unchecked_convert9.ads
@@ -0,0 +1,20 @@
+with System;
+with Ada.Unchecked_Conversion;
+with Interfaces; use Interfaces;
+
+package Unchecked_Convert9 is
+
+ type R is record
+ H : Unsigned_16;
+ L : Unsigned_16;
+ end record;
+
+ Var : R;
+ pragma Volatile (Var);
+
+ function Conv is new
+ Ada.Unchecked_Conversion (Source => Unsigned_32, Target => R);
+
+ procedure Proc;
+
+end Unchecked_Convert9;
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index bd8c026a5..c01e74c3c 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2264,7 +2264,8 @@ foreach { armfunc armflag armdef } { v4 "-march=armv4 -marm" __ARM_ARCH_4__
v7a "-march=armv7-a" __ARM_ARCH_7A__
v7r "-march=armv7-r" __ARM_ARCH_7R__
v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__
- v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__ } {
+ v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__
+ v8a "-march=armv8-a" __ARM_ARCH_8A__ } {
eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef ] {
proc check_effective_target_arm_arch_FUNC_ok { } {
if { [ string match "*-marm*" "FLAG" ] &&
@@ -3953,7 +3954,7 @@ proc check_effective_target_sync_long_long_runtime { } {
}
} ""
}]
- } elseif { [istarget arm*-*-linux-gnueabi] } {
+ } elseif { [istarget arm*-*-linux-*] } {
return [check_runtime sync_longlong_runtime {
#include <stdlib.h>
int main ()
@@ -3998,7 +3999,7 @@ proc check_effective_target_sync_int_long { } {
|| [istarget x86_64-*-*]
|| [istarget aarch64*-*-*]
|| [istarget alpha*-*-*]
- || [istarget arm*-*-linux-gnueabi]
+ || [istarget arm*-*-linux-*]
|| [istarget bfin*-*linux*]
|| [istarget hppa*-*linux*]
|| [istarget s390*-*-*]
@@ -4030,7 +4031,7 @@ proc check_effective_target_sync_char_short { } {
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
|| [istarget alpha*-*-*]
- || [istarget arm*-*-linux-gnueabi]
+ || [istarget arm*-*-linux-*]
|| [istarget hppa*-*linux*]
|| [istarget s390*-*-*]
|| [istarget powerpc*-*-*]
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ef384acd7..211c45e48 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -548,6 +548,15 @@ struct diagnose_tm
gimple stmt;
};
+/* Return true if T is a volatile variable of some kind. */
+
+static bool
+volatile_var_p (tree t)
+{
+ return (SSA_VAR_P (t)
+ && TREE_THIS_VOLATILE (TREE_TYPE (t)));
+}
+
/* Tree callback function for diagnose_tm pass. */
static tree
@@ -556,13 +565,9 @@ diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
- enum tree_code code = TREE_CODE (*tp);
- if ((code == VAR_DECL
- || code == RESULT_DECL
- || code == PARM_DECL)
- && d->block_flags & (DIAG_TM_SAFE | DIAG_TM_RELAXED)
- && TREE_THIS_VOLATILE (TREE_TYPE (*tp))
+ if (volatile_var_p (*tp)
+ && d->block_flags & DIAG_TM_SAFE
&& !d->saw_volatile)
{
d->saw_volatile = 1;
@@ -3782,40 +3787,56 @@ ipa_tm_scan_irr_block (basic_block bb)
gimple stmt = gsi_stmt (gsi);
switch (gimple_code (stmt))
{
+ case GIMPLE_ASSIGN:
+ if (gimple_assign_single_p (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
+ if (volatile_var_p (lhs) || volatile_var_p (rhs))
+ return true;
+ }
+ break;
+
case GIMPLE_CALL:
- if (is_tm_pure_call (stmt))
- break;
+ {
+ tree lhs = gimple_call_lhs (stmt);
+ if (lhs && volatile_var_p (lhs))
+ return true;
- fn = gimple_call_fn (stmt);
+ if (is_tm_pure_call (stmt))
+ break;
- /* Functions with the attribute are by definition irrevocable. */
- if (is_tm_irrevocable (fn))
- return true;
+ fn = gimple_call_fn (stmt);
- /* For direct function calls, go ahead and check for replacement
- functions, or transitive irrevocable functions. For indirect
- functions, we'll ask the runtime. */
- if (TREE_CODE (fn) == ADDR_EXPR)
- {
- struct tm_ipa_cg_data *d;
- struct cgraph_node *node;
+ /* Functions with the attribute are by definition irrevocable. */
+ if (is_tm_irrevocable (fn))
+ return true;
- fn = TREE_OPERAND (fn, 0);
- if (is_tm_ending_fndecl (fn))
- break;
- if (find_tm_replacement_function (fn))
- break;
+ /* For direct function calls, go ahead and check for replacement
+ functions, or transitive irrevocable functions. For indirect
+ functions, we'll ask the runtime. */
+ if (TREE_CODE (fn) == ADDR_EXPR)
+ {
+ struct tm_ipa_cg_data *d;
+ struct cgraph_node *node;
- node = cgraph_get_node(fn);
- d = get_cg_data (&node, true);
+ fn = TREE_OPERAND (fn, 0);
+ if (is_tm_ending_fndecl (fn))
+ break;
+ if (find_tm_replacement_function (fn))
+ break;
- /* Return true if irrevocable, but above all, believe
- the user. */
- if (d->is_irrevocable
- && !is_tm_safe_or_pure (fn))
- return true;
- }
- break;
+ node = cgraph_get_node(fn);
+ d = get_cg_data (&node, true);
+
+ /* Return true if irrevocable, but above all, believe
+ the user. */
+ if (d->is_irrevocable
+ && !is_tm_safe_or_pure (fn))
+ return true;
+ }
+ break;
+ }
case GIMPLE_ASM:
/* ??? The Approved Method of indicating that an inline
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index eb1af4e9e..b6c5654da 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2840,6 +2840,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
{
if (TREE_CODE (ref) != SSA_NAME)
return false;
+ if (!useless_type_conversion_p (type, TREE_TYPE (ref)))
+ return false;
orig = ref;
}
if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index b790e1f43..81bf09e9f 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -192,7 +192,7 @@ constant_after_peeling (tree op, gimple stmt, struct loop *loop)
Return results in SIZE, estimate benefits for complete unrolling exiting by EXIT. */
static void
-tree_estimate_loop_size (struct loop *loop, edge exit, struct loop_size *size)
+tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, struct loop_size *size)
{
basic_block *body = get_loop_body (loop);
gimple_stmt_iterator gsi;
@@ -208,8 +208,8 @@ tree_estimate_loop_size (struct loop *loop, edge exit, struct loop_size *size)
fprintf (dump_file, "Estimating sizes for loop %i\n", loop->num);
for (i = 0; i < loop->num_nodes; i++)
{
- if (exit && body[i] != exit->src
- && dominated_by_p (CDI_DOMINATORS, body[i], exit->src))
+ if (edge_to_cancel && body[i] != edge_to_cancel->src
+ && dominated_by_p (CDI_DOMINATORS, body[i], edge_to_cancel->src))
after_exit = true;
else
after_exit = false;
@@ -231,7 +231,7 @@ tree_estimate_loop_size (struct loop *loop, edge exit, struct loop_size *size)
/* Look for reasons why we might optimize this stmt away. */
/* Exit conditional. */
- if (body[i] == exit->src && stmt == last_stmt (exit->src))
+ if (exit && body[i] == exit->src && stmt == last_stmt (exit->src))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Exit condition will be eliminated.\n");
@@ -314,36 +314,161 @@ estimated_unrolled_size (struct loop_size *size,
return unr_insns;
}
+/* Loop LOOP is known to not loop. See if there is an edge in the loop
+ body that can be remove to make the loop to always exit and at
+ the same time it does not make any code potentially executed
+ during the last iteration dead.
+
+ After complette unrolling we still may get rid of the conditional
+ on the exit in the last copy even if we have no idea what it does.
+ This is quite common case for loops of form
+
+ int a[5];
+ for (i=0;i<b;i++)
+ a[i]=0;
+
+ Here we prove the loop to iterate 5 times but we do not know
+ it from induction variable.
+
+ For now we handle only simple case where there is exit condition
+ just before the latch block and the latch block contains no statements
+ with side effect that may otherwise terminate the execution of loop
+ (such as by EH or by terminating the program or longjmp).
+
+ In the general case we may want to cancel the paths leading to statements
+ loop-niter identified as having undefined effect in the last iteration.
+ The other cases are hopefully rare and will be cleaned up later. */
+
+edge
+loop_edge_to_cancel (struct loop *loop)
+{
+ VEC (edge, heap) *exits;
+ unsigned i;
+ edge edge_to_cancel;
+ gimple_stmt_iterator gsi;
+
+ /* We want only one predecestor of the loop. */
+ if (EDGE_COUNT (loop->latch->preds) > 1)
+ return NULL;
+
+ exits = get_loop_exit_edges (loop);
+
+ FOR_EACH_VEC_ELT (edge, exits, i, edge_to_cancel)
+ {
+ /* Find the other edge than the loop exit
+ leaving the conditoinal. */
+ if (EDGE_COUNT (edge_to_cancel->src->succs) != 2)
+ continue;
+ if (EDGE_SUCC (edge_to_cancel->src, 0) == edge_to_cancel)
+ edge_to_cancel = EDGE_SUCC (edge_to_cancel->src, 1);
+ else
+ edge_to_cancel = EDGE_SUCC (edge_to_cancel->src, 0);
+
+ /* We should never have conditionals in the loop latch. */
+ gcc_assert (edge_to_cancel->dest != loop->header);
+
+ /* Check that it leads to loop latch. */
+ if (edge_to_cancel->dest != loop->latch)
+ continue;
+
+ VEC_free (edge, heap, exits);
+
+ /* Verify that the code in loop latch does nothing that may end program
+ execution without really reaching the exit. This may include
+ non-pure/const function calls, EH statements, volatile ASMs etc. */
+ for (gsi = gsi_start_bb (loop->latch); !gsi_end_p (gsi); gsi_next (&gsi))
+ if (gimple_has_side_effects (gsi_stmt (gsi)))
+ return NULL;
+ return edge_to_cancel;
+ }
+ VEC_free (edge, heap, exits);
+ return NULL;
+}
+
/* Tries to unroll LOOP completely, i.e. NITER times.
UL determines which loops we are allowed to unroll.
- EXIT is the exit of the loop that should be eliminated. */
+ EXIT is the exit of the loop that should be eliminated.
+ IRRED_INVALIDATED is used to bookkeep if information about
+ irreducible regions may become invalid as a result
+ of the transformation. */
static bool
try_unroll_loop_completely (struct loop *loop,
edge exit, tree niter,
- enum unroll_level ul)
+ enum unroll_level ul,
+ bool *irred_invalidated)
{
unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
gimple cond;
struct loop_size size;
+ bool n_unroll_found = false;
+ HOST_WIDE_INT maxiter;
+ basic_block latch;
+ edge latch_edge;
+ location_t locus;
+ int flags;
+ gimple stmt;
+ gimple_stmt_iterator gsi;
+ edge edge_to_cancel = NULL;
+ int num = loop->num;
- if (loop->inner)
- return false;
+ /* See if we proved number of iterations to be low constant.
- if (!host_integerp (niter, 1))
+ EXIT is an edge that will be removed in all but last iteration of
+ the loop.
+
+ EDGE_TO_CACNEL is an edge that will be removed from the last iteration
+ of the unrolled sequence and is expected to make the final loop not
+ rolling.
+
+ If the number of execution of loop is determined by standard induction
+ variable test, then EXIT and EDGE_TO_CANCEL are the two edges leaving
+ from the iv test. */
+ if (host_integerp (niter, 1))
+ {
+ n_unroll = tree_low_cst (niter, 1);
+ n_unroll_found = true;
+ edge_to_cancel = EDGE_SUCC (exit->src, 0);
+ if (edge_to_cancel == exit)
+ edge_to_cancel = EDGE_SUCC (exit->src, 1);
+ }
+ /* We do not know the number of iterations and thus we can not eliminate
+ the EXIT edge. */
+ else
+ exit = NULL;
+
+ /* See if we can improve our estimate by using recorded loop bounds. */
+ maxiter = max_loop_iterations_int (loop);
+ if (maxiter >= 0
+ && (!n_unroll_found || (unsigned HOST_WIDE_INT)maxiter < n_unroll))
+ {
+ n_unroll = maxiter;
+ n_unroll_found = true;
+ /* Loop terminates before the IV variable test, so we can not
+ remove it in the last iteration. */
+ edge_to_cancel = NULL;
+ }
+
+ if (!n_unroll_found)
return false;
- n_unroll = tree_low_cst (niter, 1);
max_unroll = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES);
if (n_unroll > max_unroll)
return false;
+ if (!edge_to_cancel)
+ edge_to_cancel = loop_edge_to_cancel (loop);
+
if (n_unroll)
{
+ sbitmap wont_exit;
+ edge e;
+ unsigned i;
+ VEC (edge, heap) *to_remove = NULL;
if (ul == UL_SINGLE_ITER)
return false;
- tree_estimate_loop_size (loop, exit, &size);
+ tree_estimate_loop_size (loop, exit, edge_to_cancel, &size);
ninsns = size.overall;
unr_insns = estimated_unrolled_size (&size, n_unroll);
@@ -354,6 +479,18 @@ try_unroll_loop_completely (struct loop *loop,
(int) unr_insns);
}
+ /* We unroll only inner loops, because we do not consider it profitable
+ otheriwse. We still can cancel loopback edge of not rolling loop;
+ this is always a good idea. */
+ if (loop->inner && unr_insns > ninsns)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Not unrolling loop %d:"
+ "it is not innermost and code would grow.\n",
+ loop->num);
+ return false;
+ }
+
if (unr_insns > ninsns
&& (unr_insns
> (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS)))
@@ -369,17 +506,10 @@ try_unroll_loop_completely (struct loop *loop,
&& unr_insns > ninsns)
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Not unrolling loop %d.\n", loop->num);
+ fprintf (dump_file, "Not unrolling loop %d: size would grow.\n",
+ loop->num);
return false;
}
- }
-
- if (n_unroll)
- {
- sbitmap wont_exit;
- edge e;
- unsigned i;
- VEC (edge, heap) *to_remove = NULL;
initialize_original_copy_tables ();
wont_exit = sbitmap_alloc (n_unroll + 1);
@@ -408,15 +538,67 @@ try_unroll_loop_completely (struct loop *loop,
free_original_copy_tables ();
}
- cond = last_stmt (exit->src);
- if (exit->flags & EDGE_TRUE_VALUE)
- gimple_cond_make_true (cond);
+ /* Remove the conditional from the last copy of the loop. */
+ if (edge_to_cancel)
+ {
+ cond = last_stmt (edge_to_cancel->src);
+ if (edge_to_cancel->flags & EDGE_TRUE_VALUE)
+ gimple_cond_make_false (cond);
+ else
+ gimple_cond_make_true (cond);
+ update_stmt (cond);
+ /* Do not remove the path. Doing so may remove outer loop
+ and confuse bookkeeping code in tree_unroll_loops_completelly. */
+ }
+ /* We did not manage to cancel the loop.
+ The loop latch remains reachable even if it will never be reached
+ at runtime. We must redirect it to somewhere, so create basic
+ block containg __builtin_unreachable call for this reason. */
else
- gimple_cond_make_false (cond);
- update_stmt (cond);
+ {
+ latch = loop->latch;
+ latch_edge = loop_latch_edge (loop);
+ flags = latch_edge->flags;
+ locus = latch_edge->goto_locus;
+
+ /* Unloop destroys the latch edge. */
+ unloop (loop, irred_invalidated);
+
+ /* Create new basic block for the latch edge destination and wire
+ it in. */
+ stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
+ latch_edge = make_edge (latch, create_basic_block (NULL, NULL, latch), flags);
+ latch_edge->probability = 0;
+ latch_edge->count = 0;
+ latch_edge->flags |= flags;
+ latch_edge->goto_locus = locus;
+
+ latch_edge->dest->loop_father = current_loops->tree_root;
+ latch_edge->dest->count = 0;
+ latch_edge->dest->frequency = 0;
+ set_immediate_dominator (CDI_DOMINATORS, latch_edge->dest, latch_edge->src);
+
+ gsi = gsi_start_bb (latch_edge->dest);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Unrolled loop %d completely.\n", loop->num);
+ {
+ if (!n_unroll)
+ fprintf (dump_file, "Turned loop %d to non-loop; it never loops.\n",
+ num);
+ else
+ fprintf (dump_file, "Unrolled loop %d completely "
+ "(duplicated %i times).\n", num, (int)n_unroll);
+ if (exit)
+ fprintf (dump_file, "Exit condition of peeled iterations was "
+ "eliminated.\n");
+ if (edge_to_cancel)
+ fprintf (dump_file, "Last iteration exit edge was proved true.\n");
+ else
+ fprintf (dump_file, "Latch of last iteration was marked by "
+ "__builtin_unreachable ().\n");
+ }
return true;
}
@@ -425,12 +607,15 @@ try_unroll_loop_completely (struct loop *loop,
CREATE_IV is true if we may create a new iv. UL determines
which loops we are allowed to completely unroll. If TRY_EVAL is true, we try
to determine the number of iterations of a loop by direct evaluation.
- Returns true if cfg is changed. */
+ Returns true if cfg is changed.
+
+ IRRED_INVALIDATED is used to keep if irreducible reginos needs to be recomputed. */
static bool
canonicalize_loop_induction_variables (struct loop *loop,
bool create_iv, enum unroll_level ul,
- bool try_eval)
+ bool try_eval,
+ bool *irred_invalidated)
{
edge exit = NULL;
tree niter;
@@ -455,22 +640,34 @@ canonicalize_loop_induction_variables (struct loop *loop,
|| TREE_CODE (niter) != INTEGER_CST))
niter = find_loop_niter_by_eval (loop, &exit);
- if (chrec_contains_undetermined (niter)
- || TREE_CODE (niter) != INTEGER_CST)
- return false;
+ if (TREE_CODE (niter) != INTEGER_CST)
+ exit = NULL;
}
- if (dump_file && (dump_flags & TDF_DETAILS))
+ /* We work exceptionally hard here to estimate the bound
+ by find_loop_niter_by_eval. Be sure to keep it for future. */
+ if (niter && TREE_CODE (niter) == INTEGER_CST)
+ record_niter_bound (loop, tree_to_double_int (niter), false, true);
+
+ if (dump_file && (dump_flags & TDF_DETAILS)
+ && TREE_CODE (niter) == INTEGER_CST)
{
fprintf (dump_file, "Loop %d iterates ", loop->num);
print_generic_expr (dump_file, niter, TDF_SLIM);
fprintf (dump_file, " times.\n");
}
+ if (dump_file && (dump_flags & TDF_DETAILS)
+ && max_loop_iterations_int (loop) >= 0)
+ {
+ fprintf (dump_file, "Loop %d iterates at most %i times.\n", loop->num,
+ (int)max_loop_iterations_int (loop));
+ }
- if (try_unroll_loop_completely (loop, exit, niter, ul))
+ if (try_unroll_loop_completely (loop, exit, niter, ul, irred_invalidated))
return true;
- if (create_iv)
+ if (create_iv
+ && niter && !chrec_contains_undetermined (niter))
create_canonical_iv (loop, exit, niter);
return false;
@@ -485,15 +682,21 @@ canonicalize_induction_variables (void)
loop_iterator li;
struct loop *loop;
bool changed = false;
+ bool irred_invalidated = false;
FOR_EACH_LOOP (li, loop, 0)
{
changed |= canonicalize_loop_induction_variables (loop,
true, UL_SINGLE_ITER,
- true);
+ true,
+ &irred_invalidated);
}
gcc_assert (!need_ssa_update_p (cfun));
+ if (irred_invalidated
+ && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
+ mark_irreducible_loops ();
+
/* Clean up the information about numbers of iterations, since brute force
evaluation could reveal new information. */
scev_reset ();
@@ -594,9 +797,10 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
do
{
+ bool irred_invalidated = false;
changed = false;
- FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
+ FOR_EACH_LOOP (li, loop, 0)
{
struct loop *loop_father = loop_outer (loop);
@@ -609,7 +813,8 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
ul = UL_NO_GROWTH;
if (canonicalize_loop_induction_variables (loop, false, ul,
- !flag_tree_loop_ivcanon))
+ !flag_tree_loop_ivcanon,
+ &irred_invalidated))
{
changed = true;
/* If we'll continue unrolling, we need to propagate constants
@@ -629,6 +834,10 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
struct loop **iter;
unsigned i;
+ if (irred_invalidated
+ && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
+ mark_irreducible_loops ();
+
update_ssa (TODO_update_ssa);
/* Propagate the constants within the new basic blocks. */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index fe9186cef..548c110f6 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -2853,7 +2853,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
case NARY:
{
vn_nary_op_t nary = PRE_EXPR_NARY (expr);
- tree genop[4];
+ tree *genop = XALLOCAVEC (tree, nary->length);
unsigned i;
for (i = 0; i < nary->length; ++i)
{
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index f77a66933..f573659ed 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -68,12 +68,11 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
tree
streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
{
- int i, count;
tree first, prev, curr;
+ /* The chain is written as NULL terminated list of trees. */
first = prev = NULL_TREE;
- count = streamer_read_hwi (ib);
- for (i = 0; i < count; i++)
+ do
{
curr = stream_read_tree (ib, data_in);
if (prev)
@@ -81,9 +80,9 @@ streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
else
first = curr;
- TREE_CHAIN (curr) = NULL_TREE;
prev = curr;
}
+ while (curr);
return first;
}
@@ -141,6 +140,17 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
}
+/* Unpack all the non-pointer fields of the TS_INT_CST structure of
+ expression EXPR from bitpack BP. */
+
+static void
+unpack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr)
+{
+ TREE_INT_CST_LOW (expr) = (unsigned) bp_unpack_var_len_unsigned (bp);
+ TREE_INT_CST_HIGH (expr) = (unsigned) bp_unpack_var_len_int (bp);
+}
+
+
/* Unpack all the non-pointer fields of the TS_REAL_CST structure of
expression EXPR from bitpack BP. */
@@ -366,8 +376,11 @@ unpack_ts_block_value_fields (struct data_in *data_in,
structure of expression EXPR from bitpack BP. */
static void
-unpack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
+unpack_ts_translation_unit_decl_value_fields (struct data_in *data_in,
+ struct bitpack_d *bp, tree expr)
{
+ TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (bp_unpack_string (data_in, bp));
+ VEC_safe_push (tree, gc, all_translation_units, expr);
}
/* Unpack a TS_TARGET_OPTION tree from BP into EXPR. */
@@ -414,6 +427,9 @@ unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr)
the types and sizes of each of the fields being packed. */
unpack_ts_base_value_fields (bp, expr);
+ if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
+ unpack_ts_int_cst_value_fields (bp, expr);
+
if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
unpack_ts_real_cst_value_fields (bp, expr);
@@ -445,13 +461,27 @@ unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr)
unpack_ts_block_value_fields (data_in, bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- unpack_ts_translation_unit_decl_value_fields (bp, expr);
+ unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
unpack_ts_target_option (bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
unpack_ts_optimization (bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
+ {
+ unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp);
+ if (length > 0)
+ VEC_safe_grow (tree, gc, BINFO_BASE_ACCESSES (expr), length);
+ }
+
+ if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
+ {
+ unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp);
+ if (length > 0)
+ VEC_safe_grow (constructor_elt, gc, CONSTRUCTOR_ELTS (expr), length);
+ }
}
@@ -627,9 +657,6 @@ lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
for early inlining so drop it on the floor instead of ICEing in
dwarf2out.c. */
- if (TREE_CODE (expr) == PARM_DECL)
- TREE_CHAIN (expr) = streamer_read_chain (ib, data_in);
-
if ((TREE_CODE (expr) == VAR_DECL
|| TREE_CODE (expr) == PARM_DECL)
&& DECL_HAS_VALUE_EXPR_P (expr))
@@ -654,7 +681,7 @@ lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
{
if (TREE_CODE (expr) == FUNCTION_DECL)
{
- DECL_ARGUMENTS (expr) = stream_read_tree (ib, data_in);
+ DECL_ARGUMENTS (expr) = streamer_read_chain (ib, data_in);
DECL_RESULT (expr) = stream_read_tree (ib, data_in);
}
else if (TREE_CODE (expr) == TYPE_DECL)
@@ -813,12 +840,9 @@ static void
lto_input_ts_exp_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- int i, length;
-
- length = streamer_read_hwi (ib);
- gcc_assert (length == TREE_OPERAND_LENGTH (expr));
+ int i;
- for (i = 0; i < length; i++)
+ for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
TREE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
@@ -878,7 +902,7 @@ static void
lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- unsigned i, len;
+ unsigned i;
tree t;
/* Note that the number of slots in EXPR was read in
@@ -898,15 +922,12 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);
BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in);
- len = streamer_read_uhwi (ib);
- if (len > 0)
+ /* The vector of BINFO_BASE_ACCESSES is pre-allocated during
+ unpacking the bitfield section. */
+ for (i = 0; i < VEC_length (tree, BINFO_BASE_ACCESSES (expr)); i++)
{
- VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len);
- for (i = 0; i < len; i++)
- {
- tree a = stream_read_tree (ib, data_in);
- VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a);
- }
+ tree a = stream_read_tree (ib, data_in);
+ VEC_replace (tree, BINFO_BASE_ACCESSES (expr), i, a);
}
BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in);
@@ -923,31 +944,18 @@ static void
lto_input_ts_constructor_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- unsigned i, len;
+ unsigned i;
- len = streamer_read_uhwi (ib);
- for (i = 0; i < len; i++)
+ for (i = 0; i < CONSTRUCTOR_NELTS (expr); i++)
{
- tree index, value;
-
- index = stream_read_tree (ib, data_in);
- value = stream_read_tree (ib, data_in);
- CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (expr), index, value);
+ constructor_elt e;
+ e.index = stream_read_tree (ib, data_in);
+ e.value = stream_read_tree (ib, data_in);
+ VEC_replace (constructor_elt, CONSTRUCTOR_ELTS (expr), i, e);
}
}
-/* Input a TS_TRANSLATION_UNIT_DECL tree from IB and DATA_IN into EXPR. */
-
-static void
-lto_input_ts_translation_unit_decl_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in,
- tree expr)
-{
- TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (streamer_read_string (data_in, ib));
- VEC_safe_push (tree, gc, all_translation_units, expr);
-}
-
/* Read all pointer fields in EXPR from input block IB. DATA_IN
contains tables and descriptors for the file being read. */
@@ -1009,9 +1017,6 @@ streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in,
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- lto_input_ts_translation_unit_decl_tree_pointers (ib, data_in, expr);
}
@@ -1021,25 +1026,10 @@ streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in,
tree
streamer_read_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
{
- tree result, type;
- HOST_WIDE_INT low, high;
- bool overflow_p;
-
- type = stream_read_tree (ib, data_in);
- overflow_p = (streamer_read_uchar (ib) != 0);
- low = streamer_read_uhwi (ib);
- high = streamer_read_uhwi (ib);
- result = build_int_cst_wide (type, low, high);
-
- /* If the original constant had overflown, build a replica of RESULT to
- avoid modifying the shared constant returned by build_int_cst_wide. */
- if (overflow_p)
- {
- result = copy_node (result);
- TREE_OVERFLOW (result) = 1;
- }
-
- return result;
+ tree type = stream_read_tree (ib, data_in);
+ unsigned HOST_WIDE_INT low = streamer_read_uhwi (ib);
+ HOST_WIDE_INT high = streamer_read_hwi (ib);
+ return build_int_cst_wide (type, low, high);
}
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index fc70eb9f8..1f0eb55ec 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -112,6 +112,17 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
}
+/* Pack all the non-pointer fields of the TS_INTEGER_CST structure of
+ expression EXPR into bitpack BP. */
+
+static void
+pack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr)
+{
+ bp_pack_var_len_unsigned (bp, TREE_INT_CST_LOW (expr));
+ bp_pack_var_len_int (bp, TREE_INT_CST_HIGH (expr));
+}
+
+
/* Pack all the non-pointer fields of the TS_REAL_CST structure of
expression EXPR into bitpack BP. */
@@ -316,8 +327,10 @@ pack_ts_block_value_fields (struct output_block *ob,
of expression EXPR into bitpack BP. */
static void
-pack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
+pack_ts_translation_unit_decl_value_fields (struct output_block *ob,
+ struct bitpack_d *bp, tree expr)
{
+ bp_pack_string (ob, bp, TRANSLATION_UNIT_LANGUAGE (expr), true);
}
/* Pack a TS_TARGET_OPTION tree in EXPR to BP. */
@@ -371,6 +384,9 @@ streamer_pack_tree_bitfields (struct output_block *ob,
the types and sizes of each of the fields being packed. */
pack_ts_base_value_fields (bp, expr);
+ if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
+ pack_ts_int_cst_value_fields (bp, expr);
+
if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
pack_ts_real_cst_value_fields (bp, expr);
@@ -402,13 +418,19 @@ streamer_pack_tree_bitfields (struct output_block *ob,
pack_ts_block_value_fields (ob, bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- pack_ts_translation_unit_decl_value_fields (bp, expr);
+ pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
pack_ts_target_option (bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
pack_ts_optimization (bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
+ bp_pack_var_len_unsigned (bp, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
+
+ if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
+ bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
}
@@ -454,11 +476,7 @@ streamer_write_builtin (struct output_block *ob, tree expr)
void
streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
{
- int i, count;
-
- count = list_length (t);
- streamer_write_hwi (ob, count);
- for (i = 0; i < count; i++)
+ while (t)
{
tree saved_chain;
@@ -480,6 +498,9 @@ streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
TREE_CHAIN (t) = saved_chain;
t = TREE_CHAIN (t);
}
+
+ /* Write a sentinel to terminate the chain. */
+ stream_write_tree (ob, NULL_TREE, ref_p);
}
@@ -555,9 +576,6 @@ write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
for early inlining so drop it on the floor instead of ICEing in
dwarf2out.c. */
- if (TREE_CODE (expr) == PARM_DECL)
- streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);
-
if ((TREE_CODE (expr) == VAR_DECL
|| TREE_CODE (expr) == PARM_DECL)
&& DECL_HAS_VALUE_EXPR_P (expr))
@@ -578,7 +596,7 @@ write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
{
if (TREE_CODE (expr) == FUNCTION_DECL)
{
- stream_write_tree (ob, DECL_ARGUMENTS (expr), ref_p);
+ streamer_write_chain (ob, DECL_ARGUMENTS (expr), ref_p);
stream_write_tree (ob, DECL_RESULT (expr), ref_p);
}
else if (TREE_CODE (expr) == TYPE_DECL)
@@ -725,7 +743,6 @@ write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
{
int i;
- streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
@@ -786,7 +803,8 @@ write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
- streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
+ /* The number of BINFO_BASE_ACCESSES has already been emitted in
+ EXPR's bitfield section. */
FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t)
stream_write_tree (ob, t, ref_p);
@@ -807,7 +825,6 @@ write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
unsigned i;
tree index, value;
- streamer_write_uhwi (ob, CONSTRUCTOR_NELTS (expr));
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
{
stream_write_tree (ob, index, ref_p);
@@ -815,16 +832,6 @@ write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
}
}
-/* Write a TS_TRANSLATION_UNIT_DECL tree in EXPR to OB. */
-
-static void
-write_ts_translation_unit_decl_tree_pointers (struct output_block *ob,
- tree expr)
-{
- streamer_write_string (ob, ob->main_stream,
- TRANSLATION_UNIT_LANGUAGE (expr), true);
-}
-
/* Write all pointer fields in EXPR to output block OB. If REF_P is true,
the leaves of EXPR are emitted as references. */
@@ -885,9 +892,6 @@ streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
write_ts_constructor_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- write_ts_translation_unit_decl_tree_pointers (ob, expr);
}
@@ -945,9 +949,9 @@ streamer_write_tree_header (struct output_block *ob, tree expr)
void
streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p)
{
- streamer_write_record_start (ob, lto_tree_code_to_tag (INTEGER_CST));
+ gcc_assert (!TREE_OVERFLOW (cst));
+ streamer_write_record_start (ob, LTO_integer_cst);
stream_write_tree (ob, TREE_TYPE (cst), ref_p);
- streamer_write_char_stream (ob->main_stream, TREE_OVERFLOW_P (cst));
streamer_write_uhwi (ob, TREE_INT_CST_LOW (cst));
- streamer_write_uhwi (ob, TREE_INT_CST_HIGH (cst));
+ streamer_write_hwi (ob, TREE_INT_CST_HIGH (cst));
}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index e1b7b7a0e..70bcebbe9 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -4743,12 +4743,18 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
tree newref, newoff;
gimple incr;
if (TREE_CODE (ref) == ARRAY_REF)
- newref = build4 (ARRAY_REF, TREE_TYPE (ref),
- unshare_expr (TREE_OPERAND (ref, 0)),
- running_off,
- NULL_TREE, NULL_TREE);
+ {
+ newref = build4 (ARRAY_REF, TREE_TYPE (ref),
+ unshare_expr (TREE_OPERAND (ref, 0)),
+ running_off,
+ NULL_TREE, NULL_TREE);
+ if (!useless_type_conversion_p (TREE_TYPE (vectype),
+ TREE_TYPE (newref)))
+ newref = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vectype),
+ newref);
+ }
else
- newref = build2 (MEM_REF, TREE_TYPE (ref),
+ newref = build2 (MEM_REF, TREE_TYPE (vectype),
running_off,
TREE_OPERAND (ref, 1));
diff --git a/gcc/tree.c b/gcc/tree.c
index 8df1b86d2..d974362de 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9524,6 +9524,15 @@ build_common_builtin_nodes (void)
tree tmp, ftype;
int ecf_flags;
+ if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE))
+ {
+ ftype = build_function_type (void_type_node, void_list_node);
+ local_define_builtin ("__builtin_unreachable", ftype, BUILT_IN_UNREACHABLE,
+ "__builtin_unreachable",
+ ECF_NOTHROW | ECF_LEAF | ECF_NORETURN
+ | ECF_CONST | ECF_LEAF);
+ }
+
if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
|| !builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
{
diff --git a/gcc/tree.h b/gcc/tree.h
index 12e7948d3..c6a5eab50 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -484,9 +484,10 @@ struct GTY(()) tree_base {
TREE_ADDRESSABLE in
VAR_DECL, PARM_DECL, RESULT_DECL, FUNCTION_DECL, LABEL_DECL
+ SSA_NAME
all types
CONSTRUCTOR, IDENTIFIER_NODE
- STMT_EXPR, it means we want the result of the enclosed expression
+ STMT_EXPR
CALL_EXPR_TAILCALL in
CALL_EXPR
@@ -1085,15 +1086,18 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* In VAR_DECL, PARM_DECL and RESULT_DECL nodes, nonzero means address
of this is needed. So it cannot be in a register.
In a FUNCTION_DECL it has no meaning.
- In CONSTRUCTOR nodes, it means object constructed must be in memory.
In LABEL_DECL nodes, it means a goto for this label has been seen
from a place outside all binding contours that restore stack levels.
+ In an artificial SSA_NAME that points to a stack partition with at least
+ two variables, it means that at least one variable has TREE_ADDRESSABLE.
In ..._TYPE nodes, it means that objects of this type must be fully
addressable. This means that pieces of this object cannot go into
register parameters, for example. If this a function type, this
means that the value must be returned in memory.
+ In CONSTRUCTOR nodes, it means object constructed must be in memory.
In IDENTIFIER_NODEs, this means that some extern decl for this name
- had its address taken. That matters for inline functions. */
+ had its address taken. That matters for inline functions.
+ In a STMT_EXPR, it means we want the result of the enclosed expression. */
#define TREE_ADDRESSABLE(NODE) ((NODE)->base.addressable_flag)
/* Set on a CALL_EXPR if the call is in a tail position, ie. just before the
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 6a6cd420a..25973a977 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -4680,11 +4680,11 @@ dataflow_set_remove_mem_locs (void **slot, void *data)
static void
dataflow_set_clear_at_call (dataflow_set *set)
{
- int r;
+ unsigned int r;
+ hard_reg_set_iterator hrsi;
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, r))
- var_regno_delete (set, r);
+ EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, r, hrsi)
+ var_regno_delete (set, r);
if (MAY_HAVE_DEBUG_INSNS)
{
@@ -5769,6 +5769,11 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
resolve = preserve = !cselib_preserved_value_p (v);
+ if (loc == stack_pointer_rtx
+ && hard_frame_pointer_adjustment != -1
+ && preserve)
+ cselib_set_value_sp_based (v);
+
nloc = replace_expr_with_values (oloc);
if (nloc)
oloc = nloc;
@@ -5892,9 +5897,8 @@ static rtx call_arguments;
static void
prepare_call_arguments (basic_block bb, rtx insn)
{
- rtx link, x;
+ rtx link, x, call;
rtx prev, cur, next;
- rtx call = PATTERN (insn);
rtx this_arg = NULL_RTX;
tree type = NULL_TREE, t, fndecl = NULL_TREE;
tree obj_type_ref = NULL_TREE;
@@ -5903,11 +5907,8 @@ prepare_call_arguments (basic_block bb, rtx insn)
memset (&args_so_far_v, 0, sizeof (args_so_far_v));
args_so_far = pack_cumulative_args (&args_so_far_v);
- if (GET_CODE (call) == PARALLEL)
- call = XVECEXP (call, 0, 0);
- if (GET_CODE (call) == SET)
- call = SET_SRC (call);
- if (GET_CODE (call) == CALL && MEM_P (XEXP (call, 0)))
+ call = get_call_rtx_from (insn);
+ if (call)
{
if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
{
@@ -6181,12 +6182,8 @@ prepare_call_arguments (basic_block bb, rtx insn)
}
call_arguments = prev;
- x = PATTERN (insn);
- if (GET_CODE (x) == PARALLEL)
- x = XVECEXP (x, 0, 0);
- if (GET_CODE (x) == SET)
- x = SET_SRC (x);
- if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
+ x = get_call_rtx_from (insn);
+ if (x)
{
x = XEXP (XEXP (x, 0), 0);
if (GET_CODE (x) == SYMBOL_REF)
@@ -9867,6 +9864,19 @@ vt_initialize (void)
{
vt_init_cfa_base ();
hard_frame_pointer_adjustment = fp_cfa_offset;
+ /* Disassociate sp from fp now. */
+ if (MAY_HAVE_DEBUG_INSNS)
+ {
+ cselib_val *v;
+ cselib_invalidate_rtx (stack_pointer_rtx);
+ v = cselib_lookup (stack_pointer_rtx, Pmode, 1,
+ VOIDmode);
+ if (v && !cselib_preserved_value_p (v))
+ {
+ cselib_set_value_sp_based (v);
+ preserve_value (v);
+ }
+ }
}
}
}
diff --git a/gcc/web.c b/gcc/web.c
index 74904d2c3..d56563430 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -1,6 +1,6 @@
/* Web construction code for GNU compiler.
Contributed by Jan Hubicka.
- Copyright (C) 2001, 2002, 2004, 2006, 2007, 2008, 2010
+ Copyright (C) 2001, 2002, 2004, 2006, 2007, 2008, 2010, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -96,6 +96,7 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
df_ref *use_link = DF_INSN_INFO_USES (insn_info);
df_ref *def_link = DF_INSN_INFO_DEFS (insn_info);
+ struct web_entry *dup_entry;
int i;
extract_insn (insn);
@@ -107,10 +108,24 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
df_ref *ref, *dupref;
struct web_entry *entry;
- for (dupref = use_link; *dupref; dupref++)
+ for (dup_entry = use_entry, dupref = use_link; *dupref; dupref++)
if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i])
break;
+ if (*dupref == NULL && type == OP_INOUT)
+ {
+
+ for (dup_entry = def_entry, dupref = def_link; *dupref; dupref++)
+ if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i])
+ break;
+ }
+ /* ??? *DUPREF can still be zero, because when an operand matches
+ a memory, DF_REF_LOC (use_link[n]) points to the register part
+ of the address, whereas recog_data.dup_loc[m] points to the
+ entire memory ref, thus we fail to find the duplicate entry,
+ even though it is there.
+ Example: i686-pc-linux-gnu gcc.c-torture/compile/950607-1.c
+ -O3 -fomit-frame-pointer -funroll-loops */
if (*dupref == NULL
|| DF_REF_REGNO (*dupref) < FIRST_PSEUDO_REGISTER)
continue;
@@ -121,7 +136,15 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
if (DF_REF_LOC (*ref) == recog_data.operand_loc[op])
break;
- (*fun) (use_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref));
+ if (!*ref && type == OP_INOUT)
+ {
+ for (ref = use_link, entry = use_entry; *ref; ref++)
+ if (DF_REF_LOC (*ref) == recog_data.operand_loc[op])
+ break;
+ }
+
+ gcc_assert (*ref);
+ (*fun) (dup_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref));
}
}
@@ -313,8 +336,7 @@ web_main (void)
rtx insn;
df_set_flags (DF_NO_HARD_REGS + DF_EQ_NOTES);
- /* We can not RD_PRUNE_DEAD_DEFS, because we care about REG_EQUAL
- notes. */
+ df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
df_chain_add_problem (DF_UD_CHAIN);
df_analyze ();
df_set_flags (DF_DEFER_INSN_RESCAN);
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 957b216d4..fdc151c9a 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,11 @@
+2012-10-15 Tobias Burnus <burnus@net-b.de>
+
+ * files.c (read_file_guts, _cpp_save_file_entries): Free memory
+ before returning.
+ * lex.c (warn_about_normalization): Ditto.
+ * mkdeps.c (deps_save): Ditto.
+ * pch.c (cpp_valid_state): Ditto.
+
2012-10-04 Florian Weimer <fweimer@redhat.com>
* directives.c (do_pragma_warning_or_error): New.
diff --git a/libcpp/files.c b/libcpp/files.c
index 5b3a37b02..6fc24e2af 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -671,6 +671,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
if (count < 0)
{
cpp_errno (pfile, CPP_DL_ERROR, file->path);
+ free (buf);
return false;
}
@@ -1759,6 +1760,7 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp)
if (!open_file (f))
{
open_file_failed (pfile, f, 0);
+ free (result);
return false;
}
ff = fdopen (f->fd, "rb");
diff --git a/libcpp/lex.c b/libcpp/lex.c
index ab904db58..23809bc4b 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1094,6 +1094,7 @@ warn_about_normalization (cpp_reader *pfile,
else
cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0,
"`%.*s' is not in NFC", (int) sz, buf);
+ free (buf);
}
}
diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c
index af11ac3a6..b57681392 100644
--- a/libcpp/mkdeps.c
+++ b/libcpp/mkdeps.c
@@ -399,25 +399,33 @@ deps_restore (struct deps *deps, FILE *fd, const char *self)
unsigned int i, count;
size_t num_to_read;
size_t buf_size = 512;
- char *buf = XNEWVEC (char, buf_size);
+ char *buf;
/* Number of dependences. */
if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
return -1;
+ buf = XNEWVEC (char, buf_size);
+
/* The length of each dependence string, followed by the string. */
for (i = 0; i < count; i++)
{
/* Read in # bytes in string. */
if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
- return -1;
+ {
+ free (buf);
+ return -1;
+ }
if (buf_size < num_to_read + 1)
{
buf_size = num_to_read + 1 + 127;
buf = XRESIZEVEC (char, buf, buf_size);
}
if (fread (buf, 1, num_to_read, fd) != num_to_read)
- return -1;
+ {
+ free (buf);
+ return -1;
+ }
buf[num_to_read] = '\0';
/* Generate makefile dependencies from .pch if -nopch-deps. */
diff --git a/libcpp/pch.c b/libcpp/pch.c
index d278f1437..001bf3fae 100644
--- a/libcpp/pch.c
+++ b/libcpp/pch.c
@@ -710,7 +710,6 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
error:
cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
- return -1;
fail:
free (namebuf);
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index b6c3c8e5b..b8d2af783 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-17 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * config/arm/lib1funcs.S (__ARM_ARCH__): Define for ARMv8-A.
+
+2012-10-15 Matthias Klose <doko@ubuntu.com>
+
+ * config.host: Match arm*-*-linux-* for ARM Linux/GNU.
+
+2012-10-15 Pavel Chupin <pavel.v.chupin@intel.com>
+
+ * configure: Regenerate.
+ * configure.ac: Replace code with GCC_AC_THREAD_HEADER use.
+
2012-10-10 Uros Bizjak <ubizjak@gmail.com>
* config/i386/sfp-exceptions.c (__sfp_handle_exceptions): Emit SSE
diff --git a/libgcc/config.host b/libgcc/config.host
index 96c93a4e6..922356f9e 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -329,7 +329,7 @@ arm*-*-netbsdelf*)
arm*-*-linux*) # ARM GNU/Linux with ELF
tmake_file="${tmake_file} arm/t-arm t-fixedpoint-gnu-prefix"
case ${host} in
- arm*-*-linux-*eabi)
+ arm*-*-linux-*)
tmake_file="${tmake_file} arm/t-elf arm/t-bpabi arm/t-linux-eabi t-slibgcc-libgcc"
tm_file="$tm_file arm/bpabi-lib.h"
unwind_header=config/arm/unwind-arm.h
diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
index 45c3251bd..ac3c995a8 100644
--- a/libgcc/config/arm/lib1funcs.S
+++ b/libgcc/config/arm/lib1funcs.S
@@ -109,6 +109,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# define __ARM_ARCH__ 7
#endif
+#if defined(__ARM_ARCH_8A__)
+# define __ARM_ARCH__ 8
+#endif
+
#ifndef __ARM_ARCH__
#error Unable to determine architecture.
#endif
diff --git a/libgcc/configure b/libgcc/configure
index a226f8116..ed6eabf2a 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -558,6 +558,7 @@ LIBOBJS
asm_hidden_op
extra_parts
cpu_type
+thread_header
tm_defines
tm_file
tmake_file
@@ -4503,6 +4504,7 @@ tm_file="${tm_file_}"
# Map from thread model to thread header.
+
case $target_thread_file in
aix) thread_header=config/rs6000/gthr-aix.h ;;
dce) thread_header=config/pa/gthr-dce.h ;;
@@ -4516,6 +4518,8 @@ case $target_thread_file in
win32) thread_header=config/i386/gthr-win32.h ;;
esac
+
+
# Substitute configuration variables
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 24b15f0b1..8b7aba582 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -9,6 +9,7 @@ sinclude(../config/override.m4)
sinclude(../config/picflag.m4)
sinclude(../config/dfp.m4)
sinclude(../config/unwind_ipinfo.m4)
+sinclude(../config/gthr.m4)
AC_PREREQ(2.64)
AC_INIT([GNU C Runtime Library], 1.0,,[libgcc])
@@ -376,18 +377,7 @@ AC_SUBST(tm_file)
AC_SUBST(tm_defines)
# Map from thread model to thread header.
-case $target_thread_file in
- aix) thread_header=config/rs6000/gthr-aix.h ;;
- dce) thread_header=config/pa/gthr-dce.h ;;
- lynx) thread_header=config/gthr-lynx.h ;;
- mipssde) thread_header=config/mips/gthr-mipssde.h ;;
- posix) thread_header=gthr-posix.h ;;
- rtems) thread_header=config/gthr-rtems.h ;;
- single) thread_header=gthr-single.h ;;
- tpf) thread_header=config/s390/gthr-tpf.h ;;
- vxworks) thread_header=config/gthr-vxworks.h ;;
- win32) thread_header=config/i386/gthr-win32.h ;;
-esac
+GCC_AC_THREAD_HEADER([$target_thread_file])
# Substitute configuration variables
AC_SUBST(cpu_type)
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 69b13d722..1a586d10d 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-15 Matthias Klose <doko@ubuntu.com>
+
+ * configure.ac: Match arm*-*-linux-* for ARM Linux/GNU.
+ * configure: Regenerate.
+
2012-09-14 Dehao Chen <dehao@google.com>
* testsuite/libjava.lang/sourcelocation.java: New cases.
diff --git a/libjava/configure b/libjava/configure
index 7d6db50d1..53ab75412 100755
--- a/libjava/configure
+++ b/libjava/configure
@@ -20551,7 +20551,7 @@ case "${host}" in
# on Darwin -single_module speeds up loading of the dynamic libraries.
extra_ldflags_libjava=-Wl,-single_module
;;
-arm*linux*eabi)
+arm*-*-linux-*)
# Some of the ARM unwinder code is actually in libstdc++. We
# could in principle replicate it in libgcj, but it's better to
# have a dependency on libstdc++.
diff --git a/libjava/configure.ac b/libjava/configure.ac
index 62c50003f..5fa75c6d5 100644
--- a/libjava/configure.ac
+++ b/libjava/configure.ac
@@ -931,7 +931,7 @@ case "${host}" in
# on Darwin -single_module speeds up loading of the dynamic libraries.
extra_ldflags_libjava=-Wl,-single_module
;;
-arm*linux*eabi)
+arm*-*-linux-*)
# Some of the ARM unwinder code is actually in libstdc++. We
# could in principle replicate it in libgcj, but it's better to
# have a dependency on libstdc++.
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index e23ef31d5..1c9251164 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,154 @@
+2012-10-18 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/bits/forward_list.h: Add C++11 allocator support.
+ * include/bits/forward_list.tcc: Likewise.
+ * doc/xml/manual/status_cxx2011.xml: Update.
+ * testsuite/23_containers/forward_list/allocator/copy.cc: New.
+ * testsuite/23_containers/forward_list/allocator/copy_assign.cc: New.
+ * testsuite/23_containers/forward_list/allocator/minimal.cc: New.
+ * testsuite/23_containers/forward_list/allocator/move_assign.cc: New.
+ * testsuite/23_containers/forward_list/allocator/noexcept.cc: New.
+ * testsuite/23_containers/forward_list/allocator/swap.cc: New.
+
+2012-10-18 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/debug/formatter.h (_Debug_msg_id): Add
+ __msg_valid_load_factor.
+ * include/debug/macros.h (__glibcxx_check_max_load_factor): New.
+ * include/debug/unordered_set
+ (unordered_set<>::max_load_factor(float)): Check max load factor
+ is positive.
+ (unordered_multiset<>::max_load_factor(float)): Likewise.
+ * include/debug/unordered_map
+ (unordered_map<>::max_load_factor(float)): Likewise.
+ (unordered_multimap<>::max_load_factor(float)): Likewise.
+ * testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc:
+ New.
+ * testsuite/23_containers/unordered_multimap/debug/
+ max_load_factor_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/max_load_factor_neg.cc:
+ New.
+ * testsuite/23_containers/unordered_multiset/debug/
+ max_load_factor_neg.cc: New.
+
+2012-10-17 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/move.h (move_if_noexcept): Mark constexpr.
+ * include/std/array (front, back): Same.
+ * include/std/chrono: Add comment.
+ * include/std/tuple (__tuple_compare): Mark __eq, __less constexpr.
+ (operator ==, <, >, !=, <=, >=): Same.
+ * testsuite/20_util/forward/c_neg.cc: Adjust line numbers.
+ * testsuite/20_util/forward/f_neg.cc: Same.
+ * testsuite/20_util/move_if_noexcept/constexpr.cc: New.
+ * testsuite/20_util/tuple/comparison_operators/constexpr.cc: New.
+ * testsuite/20_util/tuple/creation_functions/constexpr.cc: Add.
+ * testsuite/23_containers/array/element_access/
+ constexpr_element_access.cc: Same.
+ * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust
+ line numbers.
+ * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
+ Same.
+
+ * testsuite/20_util/tuple/comparison_operators/35480_neg.cc:
+ Temporarily add dg-excess-errors.
+
+2012-10-16 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/debug/formatter.h (_Debug_msg_id): Add
+ __msg_bucket_index_oob.
+ * include/debug/macros.h (__glibcxx_check_bucket_index): New.
+ * include/debug/unordered_set (unordered_set<>::begin(size_type)):
+ Add check on bucket index.
+ (unordered_set<>::begin(size_type) const): Likewise.
+ (unordered_set<>::cbegin(size_type) const): Likewise.
+ (unordered_set<>::end(size_type)): Likewise.
+ (unordered_set<>::end(size_type) const): Likewise.
+ (unordered_set<>::cend(size_type) const): Likewise.
+ (unordered_set<>::bucket_size(size_type)): Likewise.
+ (unordered_multiset<>::begin(size_type)): Likewise.
+ (unordered_multiset<>::begin(size_type) const): Likewise.
+ (unordered_multiset<>::cbegin(size_type) const): Likewise.
+ (unordered_multiset<>::end(size_type)): Likewise.
+ (unordered_multiset<>::end(size_type) const): Likewise.
+ (unordered_multiset<>::cend(size_type) const): Likewise.
+ (unordered_multiset<>::bucket_size(size_type)): Likewise.
+ * include/debug/unordered_map (unordered_map<>::begin(size_type)):
+ Likewise.
+ (unordered_map<>::begin(size_type) const): Likewise.
+ (unordered_map<>::cbegin(size_type) const): Likewise.
+ (unordered_map<>::end(size_type)): Likewise.
+ (unordered_map<>::end(size_type) const): Likewise.
+ (unordered_map<>::cend(size_type) const): Likewise.
+ (unordered_map<>::bucket_size(size_type)): Likewise.
+ (unordered_multimap<>::begin(size_type)): Likewise.
+ (unordered_multimap<>::begin(size_type) const): Likewise.
+ (unordered_multimap<>::cbegin(size_type) const): Likewise.
+ (unordered_multimap<>::end(size_type)): Likewise.
+ (unordered_multimap<>::end(size_type) const): Likewise.
+ (unordered_multimap<>::cend(size_type) const): Likewise.
+ (unordered_multimap<>::bucket_size(size_type)): Likewise.
+ * testsuite/23_containers/unordered_map/debug/bucket_size_neg.cc:
+ New.
+ * testsuite/23_containers/unordered_map/debug/begin1_neg.cc: New.
+ * testsuite/23_containers/unordered_map/debug/begin2_neg.cc: New.
+ * testsuite/23_containers/unordered_map/debug/cbegin_neg.cc: New.
+ * testsuite/23_containers/unordered_map/debug/end1_neg.cc: New.
+ * testsuite/23_containers/unordered_map/debug/end2_neg.cc: New.
+ * testsuite/23_containers/unordered_map/debug/cend_neg.cc: New.
+ * testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc:
+ New.
+ * testsuite/23_containers/unordered_multimap/debug/begin1_neg.cc: New.
+ * testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc: New.
+ * testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc: New.
+ * testsuite/23_containers/unordered_multimap/debug/end1_neg.cc: New.
+ * testsuite/23_containers/unordered_multimap/debug/end2_neg.cc: New.
+ * testsuite/23_containers/unordered_multimap/debug/cend_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/bucket_size_neg.cc:
+ New.
+ * testsuite/23_containers/unordered_set/debug/begin1_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/begin2_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/cbegin_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/end1_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/end2_neg.cc: New.
+ * testsuite/23_containers/unordered_set/debug/cend_neg.cc: New.
+ * testsuite/23_containers/unordered_multiset/debug/bucket_size_neg.cc:
+ New.
+ * testsuite/23_containers/unordered_multiset/debug/begin1_neg.cc: New.
+ * testsuite/23_containers/unordered_multiset/debug/begin2_neg.cc: New.
+ * testsuite/23_containers/unordered_multiset/debug/cbegin_neg.cc: New.
+ * testsuite/23_containers/unordered_multiset/debug/end1_neg.cc: New.
+ * testsuite/23_containers/unordered_multiset/debug/end2_neg.cc: New.
+ * testsuite/23_containers/unordered_multiset/debug/cend_neg.cc: New.
+
+2012-10-15 Matthias Klose <doko@ubuntu.com>
+
+ * configure.host: Match arm*-*-linux-* for ARM Linux/GNU.
+ * testsuite/20_util/make_signed/requirements/typedefs-2.cc: Likewise.
+ * testsuite/20_util/make_unsigned/requirements/typedefs-2.cc: Likewise.
+
+2012-10-15 Pavel Chupin <pavel.v.chupin@intel.com>
+
+ * Makefile.in: Regenerate.
+ * acinclude.m4: Replace code with GCC_AC_THREAD_HEADER use.
+ * configure: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * include/Makefile.am: Regenerate.
+ * include/Makefile.in: Rename variable.
+ * libsupc++/Makefile.in: Regenerate.
+ * po/Makefile.in: Regenerate.
+ * python/Makefile.in: Regenerate.
+ * src/Makefile.in: Regenerate.
+ * src/c++11/Makefile.in: Regenerate.
+ * src/c++98/Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2012-10-14 Jason Merrill <jason@redhat.com>
+
+ PR target/54908
+ * libsupc++/atexit_thread.cc: Rewrite to keep the cleanup list
+ with get/setspecific. Destroy the key on dlclose.
+
2012-10-12 Edward Smith-Rowland <3dw4rd@verizon.net>
* include/ext/random: Add __gnu_cxx::arcsine_distribution<>
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 34d0e02ed..ab7caafed 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -62,7 +62,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -281,6 +282,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index f8765971b..10dac63dc 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -3305,10 +3305,14 @@ dnl having to write complex code (the sed commands to clean the macro
dnl namespace are complex and fragile enough as it is). We must also
dnl add a relative path so that -I- is supported properly.
dnl
+dnl Substs:
+dnl thread_header
+dnl
AC_DEFUN([GLIBCXX_ENABLE_THREADS], [
AC_MSG_CHECKING([for thread model used by GCC])
target_thread_file=`$CXX -v 2>&1 | sed -n 's/^Thread model: //p'`
AC_MSG_RESULT([$target_thread_file])
+ GCC_AC_THREAD_HEADER([$target_thread_file])
])
@@ -3615,3 +3619,4 @@ AC_DEFUN([GLIBCXX_ENABLE_WERROR], [
# Macros from the top-level gcc directory.
m4_include([../config/gc++filt.m4])
m4_include([../config/tls.m4])
+m4_include([../config/gthr.m4])
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 09a06c1f2..0c939ed90 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -708,6 +708,7 @@ BASIC_FILE_H
CSTDIO_H
SECTION_FLAGS
WERROR
+thread_header
glibcxx_PCHFLAGS
GLIBCXX_BUILD_PCH_FALSE
GLIBCXX_BUILD_PCH_TRUE
@@ -11512,7 +11513,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11515 "configure"
+#line 11516 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11618,7 +11619,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11621 "configure"
+#line 11622 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15032,7 +15033,7 @@ fi
#
# Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style.
cat > conftest.$ac_ext << EOF
-#line 15035 "configure"
+#line 15036 "configure"
struct S { ~S(); };
void bar();
void foo()
@@ -15160,6 +15161,21 @@ $as_echo_n "checking for thread model used by GCC... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $target_thread_file" >&5
$as_echo "$target_thread_file" >&6; }
+case $target_thread_file in
+ aix) thread_header=config/rs6000/gthr-aix.h ;;
+ dce) thread_header=config/pa/gthr-dce.h ;;
+ lynx) thread_header=config/gthr-lynx.h ;;
+ mipssde) thread_header=config/mips/gthr-mipssde.h ;;
+ posix) thread_header=gthr-posix.h ;;
+ rtems) thread_header=config/gthr-rtems.h ;;
+ single) thread_header=gthr-single.h ;;
+ tpf) thread_header=config/s390/gthr-tpf.h ;;
+ vxworks) thread_header=config/gthr-vxworks.h ;;
+ win32) thread_header=config/i386/gthr-win32.h ;;
+esac
+
+
+
ac_ext=cpp
@@ -15367,7 +15383,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
# Fake what AC_TRY_COMPILE does.
cat > conftest.$ac_ext << EOF
-#line 15370 "configure"
+#line 15386 "configure"
int main()
{
typedef bool atomic_type;
@@ -15402,7 +15418,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15405 "configure"
+#line 15421 "configure"
int main()
{
typedef short atomic_type;
@@ -15437,7 +15453,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15440 "configure"
+#line 15456 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
@@ -15473,7 +15489,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15476 "configure"
+#line 15492 "configure"
int main()
{
typedef long long atomic_type;
@@ -15552,7 +15568,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15555 "configure"
+#line 15571 "configure"
int main()
{
_Decimal32 d1;
@@ -15594,7 +15610,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15597 "configure"
+#line 15613 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -15628,7 +15644,7 @@ $as_echo "$enable_int128" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15631 "configure"
+#line 15647 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index af5d3ffbf..2970de4e6 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -351,7 +351,7 @@ case "${host}" in
fi
esac
case "${host}" in
- arm*-*-linux-*eabi)
+ arm*-*-linux-*)
port_specific_symbol_files="\$(srcdir)/../config/os/gnu-linux/arm-eabi-extra.ver"
;;
esac
diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in
index 240a68c8f..3c1a0d5d1 100644
--- a/libstdc++-v3/doc/Makefile.in
+++ b/libstdc++-v3/doc/Makefile.in
@@ -57,7 +57,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -263,6 +264,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
index 1e149f031..ba37e0ecc 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
@@ -1378,7 +1378,8 @@ particular release.
<entry>23.2.1</entry>
<entry>General container requirements</entry>
<entry>Partial</entry>
- <entry>Only <code>vector</code> meets the requirements
+ <entry>Only <code>vector</code> and <code>forward_list</code>
+ meet the requirements
relating to allocator use and propagation.</entry>
</row>
<row>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 09925d583..c2487d3c4 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1148,7 +1148,7 @@ ${host_builddir}/gthr-posix.h: ${toplevel_srcdir}/libgcc/gthr-posix.h \
-e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
< $< > $@
-${host_builddir}/gthr-default.h: ${toplevel_builddir}/libgcc/gthr-default.h \
+${host_builddir}/gthr-default.h: ${toplevel_srcdir}/libgcc/${thread_header} \
stamp-${host_alias}
sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
-e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index a2536900d..666ed19ee 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -57,7 +57,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -253,6 +254,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -1545,7 +1547,7 @@ ${host_builddir}/gthr-posix.h: ${toplevel_srcdir}/libgcc/gthr-posix.h \
-e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
< $< > $@
-${host_builddir}/gthr-default.h: ${toplevel_builddir}/libgcc/gthr-default.h \
+${host_builddir}/gthr-default.h: ${toplevel_srcdir}/libgcc/${thread_header} \
stamp-${host_alias}
sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
-e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index ce355048a..a5c9f434b 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -266,11 +266,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Fwd_list_base
{
protected:
- typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
+ typedef typename _Alloc_traits::template rebind<_Tp>::other
+ _Tp_alloc_type;
- typedef typename _Alloc::template
+ typedef typename _Alloc_traits::template
rebind<_Fwd_list_node<_Tp>>::other _Node_alloc_type;
+ typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
+
struct _Fwd_list_impl
: public _Node_alloc_type
{
@@ -312,12 +316,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Fwd_list_base(const _Fwd_list_base& __lst, const _Node_alloc_type& __a);
- _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
- : _M_impl(__a)
- {
- this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
- __lst._M_impl._M_head._M_next = 0;
- }
+ _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a);
_Fwd_list_base(_Fwd_list_base&& __lst)
: _M_impl(std::move(__lst._M_get_Node_allocator()))
@@ -333,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Node*
_M_get_node()
- { return _M_get_Node_allocator().allocate(1); }
+ { return _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); }
template<typename... _Args>
_Node*
@@ -342,8 +341,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Node* __node = this->_M_get_node();
__try
{
- _M_get_Node_allocator().construct(__node,
- std::forward<_Args>(__args)...);
+ _Node_alloc_traits::construct(_M_get_Node_allocator(), __node,
+ std::forward<_Args>(__args)...);
__node->_M_next = 0;
}
__catch(...)
@@ -360,7 +359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_put_node(_Node* __p)
- { _M_get_Node_allocator().deallocate(__p, 1); }
+ { _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
_Fwd_list_node_base*
_M_erase_after(_Fwd_list_node_base* __pos);
@@ -413,14 +412,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef _Fwd_list_node_base _Node_base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef typename _Base::_Node_alloc_type _Node_alloc_type;
+ typedef typename _Base::_Node_alloc_traits _Node_alloc_traits;
+ typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
public:
// types:
typedef _Tp value_type;
- typedef typename _Tp_alloc_type::pointer pointer;
- typedef typename _Tp_alloc_type::const_pointer const_pointer;
- typedef typename _Tp_alloc_type::reference reference;
- typedef typename _Tp_alloc_type::const_reference const_reference;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
typedef _Fwd_list_iterator<_Tp> iterator;
typedef _Fwd_list_const_iterator<_Tp> const_iterator;
@@ -504,12 +505,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief The %forward_list copy constructor.
* @param __list A %forward_list of identical element and allocator
* types.
- *
- * The newly-created %forward_list uses a copy of the allocation
- * object used by @a __list.
*/
forward_list(const forward_list& __list)
- : _Base(__list._M_get_Node_allocator())
+ : _Base(_Node_alloc_traits::_S_select_on_copy(
+ __list._M_get_Node_allocator()))
{ _M_range_initialize(__list.begin(), __list.end()); }
/**
@@ -560,16 +559,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* types.
*
* The contents of @a __list are moved into this %forward_list
- * (without copying). @a __list is a valid, but unspecified
- * %forward_list
+ * (without copying, if the allocators permit it).
+ * @a __list is a valid, but unspecified %forward_list
*/
forward_list&
operator=(forward_list&& __list)
+ noexcept(_Node_alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__list);
+ constexpr bool __move_storage =
+ _Node_alloc_traits::_S_propagate_on_move_assign()
+ || _Node_alloc_traits::_S_always_equal();
+ _M_move_assign(std::move(__list),
+ integral_constant<bool, __move_storage>());
return *this;
}
@@ -740,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
size_type
max_size() const noexcept
- { return this->_M_get_Node_allocator().max_size(); }
+ { return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); }
// 23.2.3.3 element access:
@@ -981,8 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(forward_list& __list)
- { std::swap(this->_M_impl._M_head._M_next,
- __list._M_impl._M_head._M_next); }
+ noexcept(_Node_alloc_traits::_S_nothrow_swap())
+ {
+ std::swap(this->_M_impl._M_head._M_next,
+ __list._M_impl._M_head._M_next);
+ _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
+ __list._M_get_Node_allocator());
+ }
/**
* @brief Resizes the %forward_list to the specified number of
@@ -1239,6 +1245,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by resize(sz).
void
_M_default_insert_after(const_iterator __pos, size_type __n);
+
+ // Called by operator=(forward_list&&)
+ void
+ _M_move_assign(forward_list&& __list, std::true_type) noexcept
+ {
+ clear();
+ std::swap(this->_M_impl._M_head._M_next,
+ __list._M_impl._M_head._M_next);
+ std::__alloc_on_move(this->_M_get_Node_allocator(),
+ __list._M_get_Node_allocator());
+ }
+
+ // Called by operator=(forward_list&&)
+ void
+ _M_move_assign(forward_list&& __list, std::false_type)
+ {
+ if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
+ _M_move_assign(std::move(__list), std::true_type());
+ else
+ {
+ // The rvalue's allocator cannot be moved, or is not equal,
+ // so we need to individually move each element.
+ this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
+ std::__make_move_if_noexcept_iterator(__list.end()));
+ __list.clear();
+ }
+ }
};
/**
diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc
index 3c9f2380b..5d18a6ebf 100644
--- a/libstdc++-v3/include/bits/forward_list.tcc
+++ b/libstdc++-v3/include/bits/forward_list.tcc
@@ -52,6 +52,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<typename _Tp, typename _Alloc>
+ _Fwd_list_base<_Tp, _Alloc>::
+ _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
+ : _M_impl(__a)
+ {
+ if (__lst._M_get_Node_allocator() == __a)
+ this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
+ else
+ {
+ this->_M_impl._M_head._M_next = 0;
+ _Fwd_list_node_base* __to = &this->_M_impl._M_head;
+ _Node* __curr = static_cast<_Node*>(__lst._M_impl._M_head._M_next);
+
+ while (__curr)
+ {
+ __to->_M_next =
+ _M_create_node(std::move_if_noexcept(__curr->_M_value));
+ __to = __to->_M_next;
+ __curr = static_cast<_Node*>(__curr->_M_next);
+ }
+ }
+ __lst._M_impl._M_head._M_next = 0;
+ }
+
+ template<typename _Tp, typename _Alloc>
template<typename... _Args>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
@@ -72,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
__pos->_M_next = __curr->_M_next;
- _M_get_Node_allocator().destroy(__curr);
+ _Node_alloc_traits::destroy(_M_get_Node_allocator(), __curr);
_M_put_node(__curr);
return __pos->_M_next;
}
@@ -88,7 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Node* __temp = __curr;
__curr = static_cast<_Node*>(__curr->_M_next);
- _M_get_Node_allocator().destroy(__temp);
+ _Node_alloc_traits::destroy(_M_get_Node_allocator(), __temp);
_M_put_node(__temp);
}
__pos->_M_next = __last;
@@ -144,6 +168,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
if (&__list != this)
{
+ if (_Node_alloc_traits::_S_propagate_on_copy_assign())
+ {
+ auto& __this_alloc = this->_M_get_Node_allocator();
+ auto& __that_alloc = __list._M_get_Node_allocator();
+ if (!_Node_alloc_traits::_S_always_equal()
+ && __this_alloc != __that_alloc)
+ {
+ // replacement allocator cannot free existing storage
+ clear();
+ }
+ std::__alloc_on_copy(__this_alloc, __that_alloc);
+ }
iterator __prev1 = before_begin();
iterator __curr1 = begin();
iterator __last1 = end();
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 353c466d8..236f0de30 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -1,6 +1,6 @@
// Move, forward and identity for C++0x + swap -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -65,7 +65,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @{
*/
- // forward (as per N3143)
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
@@ -117,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* type is copyable, in which case an lvalue-reference is returned instead.
*/
template<typename _Tp>
- inline typename
+ inline constexpr typename
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
move_if_noexcept(_Tp& __x) noexcept
{ return std::move(__x); }
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 8f36285ff..1d29d8ce5 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -107,11 +107,14 @@ namespace __gnu_debug
__msg_insert_after_end,
__msg_erase_after_bad,
__msg_valid_range2,
- // unordered sequence local iterators
+ // unordered container local iterators
__msg_local_iter_compare_bad,
__msg_non_empty_range,
// self move assign
- __msg_self_move_assign
+ __msg_self_move_assign,
+ // unordered container buckets
+ __msg_bucket_index_oob,
+ __msg_valid_load_factor
};
class _Error_formatter
diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h
index 1b7871957..3df0c9bd3 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -202,11 +202,19 @@ _GLIBCXX_DEBUG_VERIFY(!_Last._M_is_before_begin(), \
// Verify that the subscript _N is less than the container's size.
#define __glibcxx_check_subscript(_N) \
_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \
- _M_message(__gnu_debug::__msg_subscript_oob) \
+ _M_message(__gnu_debug::__msg_subscript_oob) \
._M_sequence(*this, "this") \
._M_integer(_N, #_N) \
._M_integer(this->size(), "size"))
+// Verify that the bucket _N is less than the container's buckets count.
+#define __glibcxx_check_bucket_index(_N) \
+_GLIBCXX_DEBUG_VERIFY(_N < this->bucket_count(), \
+ _M_message(__gnu_debug::__msg_bucket_index_oob) \
+ ._M_sequence(*this, "this") \
+ ._M_integer(_N, #_N) \
+ ._M_integer(this->bucket_count(), "size"))
+
// Verify that the container is nonempty
#define __glibcxx_check_nonempty() \
_GLIBCXX_DEBUG_VERIFY(! this->empty(), \
@@ -316,7 +324,13 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
// Verify that the container is not self move assigned
#define __glibcxx_check_self_move_assign(_Other) \
_GLIBCXX_DEBUG_VERIFY(this != &_Other, \
- _M_message(__gnu_debug::__msg_self_move_assign) \
+ _M_message(__gnu_debug::__msg_self_move_assign) \
+ ._M_sequence(*this, "this"))
+
+// Verify that load factor is position
+#define __glibcxx_check_max_load_factor(_F) \
+_GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \
+ _M_message(__gnu_debug::__msg_valid_load_factor) \
._M_sequence(*this, "this"))
#ifdef _GLIBCXX_DEBUG_PEDANTIC
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 96cb148eb..b03772d4c 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -183,27 +183,63 @@ namespace __debug
// local versions
local_iterator
begin(size_type __b)
- { return local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::begin(__b), __b, this);
+ }
local_iterator
end(size_type __b)
- { return local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
begin(size_type __b) const
- { return const_local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::begin(__b), __b, this);
+ }
const_local_iterator
end(size_type __b) const
- { return const_local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
cbegin(size_type __b) const
- { return const_local_iterator(_Base::cbegin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cbegin(__b), __b, this);
+ }
const_local_iterator
cend(size_type __b) const
- { return const_local_iterator(_Base::cend(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cend(__b), __b, this);
+ }
+
+ size_type
+ bucket_size(size_type __b) const
+ {
+ __glibcxx_check_bucket_index(__b);
+ return _Base::bucket_size(__b);
+ }
+
+ float
+ max_load_factor() const noexcept
+ { return _Base::max_load_factor(); }
+
+ void
+ max_load_factor(float __f)
+ {
+ __glibcxx_check_max_load_factor(__f);
+ _Base::max_load_factor(__f);
+ }
template<typename... _Args>
std::pair<iterator, bool>
@@ -598,27 +634,63 @@ namespace __debug
// local versions
local_iterator
begin(size_type __b)
- { return local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::begin(__b), __b, this);
+ }
local_iterator
end(size_type __b)
- { return local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
begin(size_type __b) const
- { return const_local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::begin(__b), __b, this);
+ }
const_local_iterator
end(size_type __b) const
- { return const_local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
cbegin(size_type __b) const
- { return const_local_iterator(_Base::cbegin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cbegin(__b), __b, this);
+ }
const_local_iterator
cend(size_type __b) const
- { return const_local_iterator(_Base::cend(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cend(__b), __b, this);
+ }
+
+ size_type
+ bucket_size(size_type __b) const
+ {
+ __glibcxx_check_bucket_index(__b);
+ return _Base::bucket_size(__b);
+ }
+
+ float
+ max_load_factor() const noexcept
+ { return _Base::max_load_factor(); }
+
+ void
+ max_load_factor(float __f)
+ {
+ __glibcxx_check_max_load_factor(__f);
+ _Base::max_load_factor(__f);
+ }
template<typename... _Args>
iterator
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 799676382..07d2893b8 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -183,27 +183,63 @@ namespace __debug
// local versions
local_iterator
begin(size_type __b)
- { return local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::begin(__b), __b, this);
+ }
local_iterator
end(size_type __b)
- { return local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
begin(size_type __b) const
- { return const_local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::begin(__b), __b, this);
+ }
const_local_iterator
end(size_type __b) const
- { return const_local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
cbegin(size_type __b) const
- { return const_local_iterator(_Base::cbegin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cbegin(__b), __b, this);
+ }
const_local_iterator
cend(size_type __b) const
- { return const_local_iterator(_Base::cend(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cend(__b), __b, this);
+ }
+
+ size_type
+ bucket_size(size_type __b) const
+ {
+ __glibcxx_check_bucket_index(__b);
+ return _Base::bucket_size(__b);
+ }
+
+ float
+ max_load_factor() const noexcept
+ { return _Base::max_load_factor(); }
+
+ void
+ max_load_factor(float __f)
+ {
+ __glibcxx_check_max_load_factor(__f);
+ _Base::max_load_factor(__f);
+ }
template<typename... _Args>
std::pair<iterator, bool>
@@ -593,27 +629,63 @@ namespace __debug
// local versions
local_iterator
begin(size_type __b)
- { return local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::begin(__b), __b, this);
+ }
local_iterator
end(size_type __b)
- { return local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
begin(size_type __b) const
- { return const_local_iterator(_Base::begin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::begin(__b), __b, this);
+ }
const_local_iterator
end(size_type __b) const
- { return const_local_iterator(_Base::end(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::end(__b), __b, this);
+ }
const_local_iterator
cbegin(size_type __b) const
- { return const_local_iterator(_Base::cbegin(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cbegin(__b), __b, this);
+ }
const_local_iterator
cend(size_type __b) const
- { return const_local_iterator(_Base::cend(__b), __b, this); }
+ {
+ __glibcxx_check_bucket_index(__b);
+ return const_local_iterator(_Base::cend(__b), __b, this);
+ }
+
+ size_type
+ bucket_size(size_type __b) const
+ {
+ __glibcxx_check_bucket_index(__b);
+ return _Base::bucket_size(__b);
+ }
+
+ float
+ max_load_factor() const noexcept
+ { return _Base::max_load_factor(); }
+
+ void
+ max_load_factor(float __f)
+ {
+ __glibcxx_check_max_load_factor(__f);
+ _Base::max_load_factor(__f);
+ }
template<typename... _Args>
iterator
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index c7c0a5ae8..15dd6c132 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -198,17 +198,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
front()
{ return *begin(); }
- const_reference
+ constexpr const_reference
front() const
- { return *begin(); }
+ { return _AT_Type::_S_ref(_M_elems, 0); }
reference
back()
{ return _Nm ? *(end() - 1) : *end(); }
- const_reference
+ constexpr const_reference
back() const
- { return _Nm ? *(end() - 1) : *end(); }
+ {
+ return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
+ : _AT_Type::_S_ref(_M_elems, _Nm);
+ }
pointer
data() noexcept
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 209f395ed..d920a7dd3 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -250,7 +250,10 @@ _GLIBCXX_END_NAMESPACE_VERSION
// 20.11.5.1 construction / copy / destroy
constexpr duration() = default;
- constexpr duration(const duration&) = default;
+ // NB: Make constexpr implicit. This cannot be explicitly
+ // constexpr, as any UDT that is not a literal type with a
+ // constexpr copy constructor will be ill-formed.
+ duration(const duration&) = default;
template<typename _Rep2, typename = typename
enable_if<is_convertible<_Rep2, rep>::value
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index fb9e09fff..b4985d280 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -775,14 +775,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
struct __tuple_compare<0, __i, __j, _Tp, _Up>
{
- static bool
+ static constexpr bool
__eq(const _Tp& __t, const _Up& __u)
{
return (get<__i>(__t) == get<__i>(__u) &&
__tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
}
- static bool
+ static constexpr bool
__less(const _Tp& __t, const _Up& __u)
{
return ((get<__i>(__t) < get<__i>(__u))
@@ -794,55 +794,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<std::size_t __i, typename _Tp, typename _Up>
struct __tuple_compare<0, __i, __i, _Tp, _Up>
{
- static bool
+ static constexpr bool
__eq(const _Tp&, const _Up&) { return true; }
- static bool
+ static constexpr bool
__less(const _Tp&, const _Up&) { return false; }
};
template<typename... _TElements, typename... _UElements>
- bool
+ constexpr bool
operator==(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{
typedef tuple<_TElements...> _Tp;
typedef tuple<_UElements...> _Up;
- return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
+ return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
}
template<typename... _TElements, typename... _UElements>
- bool
+ constexpr bool
operator<(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{
typedef tuple<_TElements...> _Tp;
typedef tuple<_UElements...> _Up;
- return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
+ return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
}
template<typename... _TElements, typename... _UElements>
- inline bool
+ inline constexpr bool
operator!=(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return !(__t == __u); }
template<typename... _TElements, typename... _UElements>
- inline bool
+ inline constexpr bool
operator>(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return __u < __t; }
template<typename... _TElements, typename... _UElements>
- inline bool
+ inline constexpr bool
operator<=(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return !(__u < __t); }
template<typename... _TElements, typename... _UElements>
- inline bool
+ inline constexpr bool
operator>=(const tuple<_TElements...>& __t,
const tuple<_UElements...>& __u)
{ return !(__t < __u); }
@@ -858,7 +858,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename... _Elements>
- constexpr tuple<_Elements&&...>
+ tuple<_Elements&&...>
forward_as_tuple(_Elements&&... __args) noexcept
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index e745179cd..8bf86f35a 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -59,7 +59,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -90,10 +91,10 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(bitsdir)" \
"$(DESTDIR)$(stddir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
libsupc___la_LIBADD =
-am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo bad_alloc.lo \
- bad_cast.lo bad_typeid.lo class_type_info.lo del_op.lo \
- del_opnt.lo del_opv.lo del_opvnt.lo dyncast.lo eh_alloc.lo \
- eh_arm.lo eh_aux_runtime.lo eh_call.lo eh_catch.lo \
+am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo \
+ bad_alloc.lo bad_cast.lo bad_typeid.lo class_type_info.lo \
+ del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo dyncast.lo \
+ eh_alloc.lo eh_arm.lo eh_aux_runtime.lo eh_call.lo eh_catch.lo \
eh_exception.lo eh_globals.lo eh_personality.lo eh_ptr.lo \
eh_term_handler.lo eh_terminate.lo eh_tm.lo eh_throw.lo \
eh_type.lo eh_unex_handler.lo enum_type_info.lo \
@@ -313,6 +314,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
index 5e47708d9..95bdcf09d 100644
--- a/libstdc++-v3/libsupc++/atexit_thread.cc
+++ b/libstdc++-v3/libsupc++/atexit_thread.cc
@@ -27,109 +27,92 @@
#include "bits/gthr.h"
namespace {
- // Data structure for the list of destructors: Singly-linked list
- // of arrays.
- class list
+ // One element in a singly-linked stack of cleanups.
+ struct elt
{
- struct elt
- {
- void *object;
- void (*destructor)(void *);
- };
-
- static const int max_nelts = 32;
-
- list *next;
- int nelts;
- elt array[max_nelts];
-
- elt *allocate_elt();
- public:
- void run();
- static void run(void *p);
- int add_elt(void (*)(void *), void *);
+ void (*destructor)(void *);
+ void *object;
+ elt *next;
};
- // Return the address of an open slot.
- list::elt *
- list::allocate_elt()
- {
- if (nelts < max_nelts)
- return &array[nelts++];
- if (!next)
- next = new (std::nothrow) list();
- if (!next)
- return 0;
- return next->allocate_elt();
- }
+ // Keep a per-thread list of cleanups in gthread_key storage.
+ __gthread_key_t key;
+ // But also support non-threaded mode.
+ elt *single_thread;
- // Run all the cleanups in the list.
- void
- list::run()
+ // Run the specified stack of cleanups.
+ void run (void *p)
{
- for (int i = nelts - 1; i >= 0; --i)
- array[i].destructor (array[i].object);
- if (next)
- next->run();
+ elt *e = static_cast<elt*>(p);
+ for (; e; e = e->next)
+ e->destructor (e->object);
}
- // Static version to use as a callback to __gthread_key_create.
- void
- list::run(void *p)
+ // Run the stack of cleanups for the current thread.
+ void run ()
{
- static_cast<list *>(p)->run();
+ void *e;
+ if (__gthread_active_p ())
+ e = __gthread_getspecific (key);
+ else
+ e = single_thread;
+ run (e);
}
- // The list of cleanups is per-thread.
- thread_local list first;
-
- // The pthread data structures for actually running the destructors at
- // thread exit are shared. The constructor of the thread-local sentinel
- // object in add_elt performs the initialization.
- __gthread_key_t key;
- __gthread_once_t once = __GTHREAD_ONCE_INIT;
- void run_current () { first.run(); }
+ // Initialize the key for the cleanup stack. We use a static local for
+ // key init/delete rather than atexit so that delete is run on dlclose.
void key_init() {
- __gthread_key_create (&key, list::run);
+ struct key_s {
+ key_s() { __gthread_key_create (&key, run); }
+ ~key_s() { __gthread_key_delete (key); }
+ };
+ static key_s ks;
// Also make sure the destructors are run by std::exit.
// FIXME TLS cleanups should run before static cleanups and atexit
// cleanups.
- std::atexit (run_current);
+ std::atexit (run);
}
- struct sentinel
- {
- sentinel()
+}
+
+extern "C" int
+__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *), void *obj, void */*dso_handle*/)
+ _GLIBCXX_NOTHROW
+{
+ // Do this initialization once.
+ if (__gthread_active_p ())
+ {
+ // When threads are active use __gthread_once.
+ static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+ __gthread_once (&once, key_init);
+ }
+ else
{
- if (__gthread_active_p ())
+ // And when threads aren't active use a static local guard.
+ static bool queued;
+ if (!queued)
{
- __gthread_once (&once, key_init);
- __gthread_setspecific (key, &first);
+ queued = true;
+ std::atexit (run);
}
- else
- std::atexit (run_current);
}
- };
- // Actually insert an element.
- int
- list::add_elt(void (*dtor)(void *), void *obj)
- {
- thread_local sentinel s;
- elt *e = allocate_elt ();
- if (!e)
- return -1;
- e->object = obj;
- e->destructor = dtor;
- return 0;
- }
-}
+ elt *first;
+ if (__gthread_active_p ())
+ first = static_cast<elt*>(__gthread_getspecific (key));
+ else
+ first = single_thread;
-namespace __cxxabiv1
-{
- extern "C" int
- __cxa_thread_atexit (void (*dtor)(void *), void *obj, void */*dso_handle*/)
- _GLIBCXX_NOTHROW
- {
- return first.add_elt (dtor, obj);
- }
+ elt *new_elt = new (std::nothrow) elt;
+ if (!new_elt)
+ return -1;
+ new_elt->destructor = dtor;
+ new_elt->object = obj;
+ new_elt->next = first;
+
+ if (__gthread_active_p ())
+ __gthread_setspecific (key, new_elt);
+ else
+ single_thread = new_elt;
+
+ return 0;
}
diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in
index b6e9def9b..bb0f59084 100644
--- a/libstdc++-v3/po/Makefile.in
+++ b/libstdc++-v3/po/Makefile.in
@@ -57,7 +57,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -253,6 +254,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in
index d0fd51d89..49f71a117 100644
--- a/libstdc++-v3/python/Makefile.in
+++ b/libstdc++-v3/python/Makefile.in
@@ -58,7 +58,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -277,6 +278,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 56eb09afc..f9ff31943 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -58,7 +58,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -303,6 +304,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index 22a8c531f..793bbae40 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -58,7 +58,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -270,6 +271,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index f0ab4bc4e..8a18026a4 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -178,7 +178,10 @@ namespace __gnu_debug
"attempt to compare local iterators from different unordered container"
" buckets",
"function requires a non-empty iterator range [%1.name;, %2.name;)",
- "attempt to self move assign"
+ "attempt to self move assign",
+ "attempt to access container with out-of-bounds bucket index %2;,"
+ " container only holds %3; buckets",
+ "load factor shall be positive"
};
void
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 26608c563..d154b9839 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -58,7 +58,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -286,6 +287,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/libstdc++-v3/testsuite/20_util/forward/c_neg.cc b/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
index 01128245d..1e573ec27 100644
--- a/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2010-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -18,7 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "static assertion failed" "" { target *-*-* } 90 }
+// { dg-error "static assertion failed" "" { target *-*-* } 89 }
#include <list>
diff --git a/libstdc++-v3/testsuite/20_util/forward/f_neg.cc b/libstdc++-v3/testsuite/20_util/forward/f_neg.cc
index 9e5b78a04..d4a9c7a2a 100644
--- a/libstdc++-v3/testsuite/20_util/forward/f_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/forward/f_neg.cc
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2010-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -18,7 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "static assertion failed" "" { target *-*-* } 90 }
+// { dg-error "static assertion failed" "" { target *-*-* } 89 }
#include <utility>
diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc
index adf3af4ab..39117dee5 100644
--- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc
+++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc
@@ -1,5 +1,5 @@
// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums" }
-// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux-* } }
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
index a1465d39f..11e13532d 100644
--- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
+++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
@@ -1,5 +1,5 @@
// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums" }
-// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
+// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux-* } }
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
diff --git a/libstdc++-v3/testsuite/20_util/move_if_noexcept/constexpr.cc b/libstdc++-v3/testsuite/20_util/move_if_noexcept/constexpr.cc
new file mode 100644
index 000000000..4811b17cb
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/move_if_noexcept/constexpr.cc
@@ -0,0 +1,42 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <utility>
+#include <testsuite_hooks.h>
+
+struct simple
+{
+ int i;
+};
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ constexpr simple s { 5 };
+ constexpr auto s2 __attribute__((unused)) = std::move_if_noexcept(s);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/35480_neg.cc b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/35480_neg.cc
index eb2293826..eb4c213ed 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/35480_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/35480_neg.cc
@@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
// { dg-do compile }
-// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2008, 2009, 2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -31,3 +31,4 @@ void test01()
if ( t1 == t2 ) {} // { dg-error "here" }
}
// { dg-prune-output "incomplete type" }
+// { dg-excess-errors "body of constexpr function" }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/constexpr.cc b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/constexpr.cc
new file mode 100644
index 000000000..0efb4c3da
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/constexpr.cc
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <tuple>
+#include <testsuite_common_types.h>
+
+int main()
+{
+ __gnu_test::constexpr_comparison_operators test;
+ test.operator()<std::tuple<int, int>>();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc b/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc
index bf2a8573a..6c260605c 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/creation_functions/constexpr.cc
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2011 Free Software Foundation, Inc.
+// Copyright (C) 2011, 2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -45,6 +45,50 @@ test_make_tuple()
}
}
+#if 0
+// forward_as_tuple
+void
+test_forward_as_tuple()
+{
+ {
+ typedef std::tuple<int, float> tuple_type;
+ constexpr tuple_type p1 __attribute__((unused))
+ = std::forward_as_tuple(22, 22.222);
+ }
+
+ {
+ typedef std::tuple<int, float, int> tuple_type;
+ constexpr tuple_type p1 __attribute__((unused))
+ = std::forward_as_tuple(22, 22.222, 77799);
+ }
+}
+#endif
+
+#if 0
+// tie
+void
+test_tie()
+{
+ {
+ int i(22);
+ float f(22.222);
+ typedef std::tuple<int, float> tuple_type;
+ constexpr tuple_type p1 __attribute__((unused))
+ = std::tie(i, f);
+ }
+
+ {
+ int i(22);
+ float f(22.222);
+ int ii(77799);
+
+ typedef std::tuple<int, float, int> tuple_type;
+ constexpr tuple_type p1 __attribute__((unused))
+ = std::tie(i, f, ii);
+ }
+}
+#endif
+
// get
void
test_get()
diff --git a/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc b/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc
index c2f301adc..ec46ac0d3 100644
--- a/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2011 Free Software Foundation, Inc.
+// Copyright (C) 2011-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -27,5 +27,7 @@ int main()
constexpr array_type a = { { 0, 55, 66, 99, 4115, 2 } };
constexpr auto v1 __attribute__((unused)) = a[1];
constexpr auto v2 __attribute__((unused)) = a.at(2);
+ constexpr auto v3 __attribute__((unused)) = a.front();
+ constexpr auto v4 __attribute__((unused)) = a.back();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index e74af1b4f..7c7a365cb 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -27,6 +27,6 @@ int n1 = std::get<1>(a);
int n2 = std::get<1>(std::move(a));
int n3 = std::get<1>(ca);
-// { dg-error "static assertion failed" "" { target *-*-* } 288 }
-// { dg-error "static assertion failed" "" { target *-*-* } 296 }
-// { dg-error "static assertion failed" "" { target *-*-* } 304 }
+// { dg-error "static assertion failed" "" { target *-*-* } 291 }
+// { dg-error "static assertion failed" "" { target *-*-* } 299 }
+// { dg-error "static assertion failed" "" { target *-*-* } 307 }
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
index b9ce910f6..3c642c800 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
@@ -22,4 +22,4 @@
typedef std::tuple_element<1, std::array<int, 1>>::type type;
-// { dg-error "static assertion failed" "" { target *-*-* } 280 }
+// { dg-error "static assertion failed" "" { target *-*-* } 283 }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
new file mode 100644
index 000000000..c388ef3d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2012 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(0 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy_assign.cc
new file mode 100644
index 000000000..e78856ae8
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy_assign.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2012 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ v2 = v1;
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ v2 = v1;
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc
new file mode 100644
index 000000000..51033f125
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2012 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <forward_list>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+bool operator==(const T& l, const T& r) { return l.i == r.i; }
+bool operator<(const T& l, const T& r) { return l.i < r.i; }
+
+using __gnu_test::SimpleAllocator;
+
+template class std::forward_list<T, SimpleAllocator<T>>;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef SimpleAllocator<T> alloc_type;
+ typedef std::allocator_traits<alloc_type> traits_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v(alloc_type{});
+ VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc
new file mode 100644
index 000000000..18539ffa3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2012 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ v2 = std::move(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ v2 = std::move(v1);
+ VERIFY(0 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/noexcept.cc
new file mode 100644
index 000000000..77d2c21cc
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/noexcept.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2012 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+namespace __gnu_test
+{
+ inline void
+ swap(propagating_allocator<T, true>& l, propagating_allocator<T, true>& r)
+ noexcept(false)
+ {
+ typedef uneq_allocator<T> base_alloc;
+ swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+ }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ typedef std::allocator<T> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1;
+ test_type v2;
+ // this is a GNU extension for std::allocator
+ static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+ static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test02()
+{
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
+ static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test03()
+{
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+ // static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc
new file mode 100644
index 000000000..60d83d450
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2012 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ std::swap(v1, v2);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ test_type v2(alloc_type(2));
+ std::swap(v1, v2);
+ VERIFY(2 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin1_neg.cc
new file mode 100644
index 000000000..63bdb53b0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.begin(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin2_neg.cc
new file mode 100644
index 000000000..5f8c177a2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/begin2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ const std::unordered_map<int, int>& cum = um;
+ cum.begin(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/bucket_size_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/bucket_size_neg.cc
new file mode 100644
index 000000000..17e2875fb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/bucket_size_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.bucket_size(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/cbegin_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/cbegin_neg.cc
new file mode 100644
index 000000000..8147256a7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/cbegin_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.cbegin(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/cend_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/cend_neg.cc
new file mode 100644
index 000000000..0eb4800db
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/cend_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.cend(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/end1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/end1_neg.cc
new file mode 100644
index 000000000..028efed06
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/end1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.end(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/end2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/end2_neg.cc
new file mode 100644
index 000000000..fe25ad6b9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/end2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ const std::unordered_map<int, int>& cum = um;
+ cum.end(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc
new file mode 100644
index 000000000..576648906
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_multimap<int, int> um;
+ um.max_load_factor(-1.0f);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin1_neg.cc
new file mode 100644
index 000000000..bf70732e3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_multimap<int, int> um;
+ um.begin(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc
new file mode 100644
index 000000000..5f8c177a2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ const std::unordered_map<int, int>& cum = um;
+ cum.begin(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc
new file mode 100644
index 000000000..17e2875fb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.bucket_size(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc
new file mode 100644
index 000000000..8147256a7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.cbegin(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cend_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cend_neg.cc
new file mode 100644
index 000000000..0eb4800db
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/cend_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.cend(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end1_neg.cc
new file mode 100644
index 000000000..028efed06
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.end(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end2_neg.cc
new file mode 100644
index 000000000..fe25ad6b9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/end2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ const std::unordered_map<int, int>& cum = um;
+ cum.end(um.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc
new file mode 100644
index 000000000..b4b15decf
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_map>
+
+void test01()
+{
+ std::unordered_map<int, int> um;
+ um.max_load_factor(-1.0f);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin1_neg.cc
new file mode 100644
index 000000000..1f2ee7348
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ us.begin(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin2_neg.cc
new file mode 100644
index 000000000..e768a5480
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/begin2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ const std::unordered_multiset<int>& cus = us;
+ cus.begin(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/bucket_size_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/bucket_size_neg.cc
new file mode 100644
index 000000000..14928c62e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/bucket_size_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ us.bucket_size(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cbegin_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cbegin_neg.cc
new file mode 100644
index 000000000..0e5a26c31
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cbegin_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ us.cbegin(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cend_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cend_neg.cc
new file mode 100644
index 000000000..55d2bb204
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/cend_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ us.cend(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end1_neg.cc
new file mode 100644
index 000000000..4fc054a27
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ us.end(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end2_neg.cc
new file mode 100644
index 000000000..e05782859
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/end2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ const std::unordered_multiset<int>& cus = us;
+ cus.end(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/max_load_factor_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/max_load_factor_neg.cc
new file mode 100644
index 000000000..797eeaafe
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/max_load_factor_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_multiset<int> us;
+ us.max_load_factor(-1.0f);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin1_neg.cc
new file mode 100644
index 000000000..2d3b27428
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ us.begin(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin2_neg.cc
new file mode 100644
index 000000000..7836ec25c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/begin2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ const std::unordered_set<int>& cus = us;
+ cus.begin(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/bucket_size_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/bucket_size_neg.cc
new file mode 100644
index 000000000..5a6f5bbcd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/bucket_size_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ us.bucket_size(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/cbegin_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/cbegin_neg.cc
new file mode 100644
index 000000000..5e444ad72
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/cbegin_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ us.cbegin(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/cend_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/cend_neg.cc
new file mode 100644
index 000000000..9fb847b5c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/cend_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ us.cend(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/end1_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/end1_neg.cc
new file mode 100644
index 000000000..704e61037
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/end1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ us.end(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/end2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/end2_neg.cc
new file mode 100644
index 000000000..ff645b5f1
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/end2_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ const std::unordered_set<int>& cus = us;
+ cus.end(us.bucket_count());
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/max_load_factor_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/max_load_factor_neg.cc
new file mode 100644
index 000000000..b18e6e592
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/max_load_factor_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This 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, or (at your option)
+// any later version.
+//
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=c++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <unordered_set>
+
+void test01()
+{
+ std::unordered_set<int> us;
+ us.max_load_factor(-1.0f);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index d286ce2a5..96b3f9f4b 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -57,7 +57,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/gc++filt.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
CONFIG_HEADER = $(top_builddir)/config.h
@@ -253,6 +254,7 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+thread_header = @thread_header@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@