summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-19 17:43:20 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-19 17:43:20 +0000
commit37145d627f6c5d809ce70612c1d76770e87fae79 (patch)
tree66418851402566a0a427c03b24cfaa624256cfc4
parent039efeddc8cee7b04ec48b3362de97e756b6b7e2 (diff)
parent64a31469469fd2e323427ae6a4f4ad12997b0649 (diff)
downloadgcc-37145d627f6c5d809ce70612c1d76770e87fae79.tar.gz
Merge from trunk rev 192612.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/asan@192621 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog17
-rw-r--r--config/ChangeLog4
-rw-r--r--config/gthr.m427
-rw-r--r--contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail57
-rw-r--r--gcc/ChangeLog1330
-rw-r--r--gcc/ChangeLog.asan9
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/acinclude.m46
-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/builtins.c46
-rw-r--r--gcc/builtins.def11
-rw-r--r--gcc/c-family/ChangeLog46
-rw-r--r--gcc/c-family/c-ada-spec.c83
-rw-r--r--gcc/c-family/c-common.c168
-rw-r--r--gcc/c-family/c-common.h8
-rw-r--r--gcc/c-family/c-opts.c10
-rw-r--r--gcc/c-family/c.opt8
-rw-r--r--gcc/c/ChangeLog13
-rw-r--r--gcc/c/c-parser.c71
-rw-r--r--gcc/calls.c9
-rw-r--r--gcc/cfgbuild.c25
-rw-r--r--gcc/cfgexpand.c2
-rw-r--r--gcc/cfgloop.h7
-rw-r--r--gcc/cfgloopanal.c37
-rw-r--r--gcc/cfgloopmanip.c21
-rw-r--r--gcc/cfgrtl.c29
-rw-r--r--gcc/combine.c30
-rw-r--r--gcc/common.opt13
-rw-r--r--gcc/common/config/rs6000/rs6000-common.c57
-rw-r--r--gcc/config.gcc12
-rw-r--r--gcc/config/alpha/alpha.c18
-rw-r--r--gcc/config/alpha/alpha.md2703
-rw-r--r--gcc/config/alpha/sync.md70
-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-protos.h1
-rw-r--r--gcc/config/arm/arm-tables.opt18
-rw-r--r--gcc/config/arm/arm.c55
-rw-r--r--gcc/config/arm/arm.h15
-rw-r--r--gcc/config/arm/arm.md22
-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/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c13
-rw-r--r--gcc/config/mips/mips.md10
-rw-r--r--gcc/config/mmix/mmix.c26
-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.md7
-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.c247
-rw-r--r--gcc/config/rs6000/rs6000.h61
-rw-r--r--gcc/config/rs6000/rs6000.md35
-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.c131
-rw-r--r--gcc/config/s390/s390.md28
-rw-r--r--gcc/config/sh/iterators.md1
-rw-r--r--gcc/config/sh/predicates.md54
-rw-r--r--gcc/config/sh/sh-protos.h20
-rw-r--r--gcc/config/sh/sh.c243
-rw-r--r--gcc/config/sh/sh.md403
-rw-r--r--gcc/config/spu/spu.md3
-rw-r--r--gcc/config/tilegx/tilegx.md3
-rw-r--r--gcc/config/tilepro/tilepro.md3
-rw-r--r--gcc/config/xtensa/xtensa.c38
-rw-r--r--gcc/config/xtensa/xtensa.md4
-rwxr-xr-xgcc/configure33
-rw-r--r--gcc/configure.ac27
-rw-r--r--gcc/cp/ChangeLog84
-rw-r--r--gcc/cp/call.c52
-rw-r--r--gcc/cp/class.c90
-rw-r--r--gcc/cp/cp-tree.h24
-rw-r--r--gcc/cp/decl.c15
-rw-r--r--gcc/cp/error.c5
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/method.c217
-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/semantics.c28
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cp/typeck.c4
-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.c70
-rw-r--r--gcc/df.h40
-rw-r--r--gcc/doc/arm-neon-intrinsics.texi180
-rw-r--r--gcc/doc/extend.texi44
-rw-r--r--gcc/doc/generic.texi25
-rw-r--r--gcc/doc/gty.texi21
-rw-r--r--gcc/doc/install.texi2
-rw-r--r--gcc/doc/invoke.texi14
-rw-r--r--gcc/doc/md.texi32
-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/fold-const.c34
-rw-r--r--gcc/fortran/ChangeLog36
-rw-r--r--gcc/fortran/interface.c13
-rw-r--r--gcc/fortran/resolve.c71
-rw-r--r--gcc/fortran/trans-expr.c356
-rw-r--r--gcc/fortran/trans-stmt.c18
-rw-r--r--gcc/fortran/trans.h6
-rw-r--r--gcc/gcov.c2
-rw-r--r--gcc/gcse.c386
-rw-r--r--gcc/gengtype-lex.l25
-rw-r--r--gcc/gengtype-parse.c186
-rw-r--r--gcc/gengtype-state.c6
-rw-r--r--gcc/gengtype.c17
-rw-r--r--gcc/gengtype.h65
-rw-r--r--gcc/genoutput.c66
-rw-r--r--gcc/gimplify.c14
-rw-r--r--gcc/haifa-sched.c2
-rw-r--r--gcc/ifcvt.c2
-rw-r--r--gcc/ira-build.c142
-rw-r--r--gcc/ira-color.c8
-rw-r--r--gcc/ira-conflicts.c2
-rw-r--r--gcc/ira-costs.c9
-rw-r--r--gcc/ira-emit.c14
-rw-r--r--gcc/ira-lives.c15
-rw-r--r--gcc/ira.c49
-rw-r--r--gcc/ira.h4
-rw-r--r--gcc/loop-doloop.c14
-rw-r--r--gcc/loop-invariant.c22
-rw-r--r--gcc/loop-iv.c66
-rw-r--r--gcc/loop-unroll.c63
-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/lto/ChangeLog7
-rw-r--r--gcc/lto/lto.c15
-rw-r--r--gcc/opt-functions.awk16
-rw-r--r--gcc/optabs.c65
-rw-r--r--gcc/optabs.def3
-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/regmove.c5
-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/ChangeLog358
-rw-r--r--gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c161
-rw-r--r--gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c482
-rw-r--r--gcc/testsuite/c-c++-common/tm/pr54893.c16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype45.C40
-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/cpp0x/pr52744.C83
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/weak5.C12
-rw-r--r--gcc/testsuite/g++.dg/gomp/tls-5.C3
-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/init/bitfield3.C11
-rw-r--r--gcc/testsuite/g++.dg/opt/pr52643.C64
-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/friend-main.C30
-rw-r--r--gcc/testsuite/g++.dg/parse/pr43765.C14
-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/pr53055.C5
-rw-r--r--gcc/testsuite/g++.dg/template/crash113.C50
-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/static2.C18
-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_local7.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local7g.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C112
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C116
-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/Wsizeof-pointer-memaccess1.c456
-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/hoist-register-pressure.c31
-rw-r--r--gcc/testsuite/gcc.dg/pr44194-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr53060.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr54919.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr54981.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c112
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54877.c23
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54894.c27
-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/cunroll-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c14
-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.dg/unroll_5.c25
-rw-r--r--gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c (renamed from gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c)2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr48765.c5
-rw-r--r--gcc/testsuite/gcc.dg/webizer.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/div64-unwinding.c3
-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/pr54892.c7
-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/mips/mips32-dsp-accinit-2.c3
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-13.c85
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-14.c107
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-15.c71
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-16.c11
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-17.c297
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-1.c15
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-2.c15
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-3.c12
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-4.c15
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54680.c66
-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_allocate_13.f9031
-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/dummy_procedure_9.f9037
-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.exp12
-rw-r--r--gcc/testsuite/obj-c++.dg/tls/init-2.mm6
-rw-r--r--gcc/trans-mem.c87
-rw-r--r--gcc/tree-loop-distribution.c8
-rw-r--r--gcc/tree-ssa-forwprop.c2
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c283
-rw-r--r--gcc/tree-ssa-loop-niter.c4
-rw-r--r--gcc/tree-ssa-pre.c2
-rw-r--r--gcc/tree-ssa-threadupdate.c12
-rw-r--r--gcc/tree-streamer-in.c197
-rw-r--r--gcc/tree-streamer-out.c154
-rw-r--r--gcc/tree-vect-loop.c2
-rw-r--r--gcc/tree-vect-stmts.c37
-rw-r--r--gcc/tree.c9
-rw-r--r--gcc/tree.def7
-rw-r--r--gcc/tree.h10
-rw-r--r--gcc/var-tracking.c44
-rw-r--r--gcc/web.c29
-rw-r--r--libbacktrace/ChangeLog10
-rwxr-xr-xlibbacktrace/configure6
-rw-r--r--libbacktrace/configure.ac6
-rw-r--r--libbacktrace/elf.c122
-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/ChangeLog33
-rw-r--r--libgcc/config.host10
-rw-r--r--libgcc/config/arm/lib1funcs.S4
-rw-r--r--libgcc/config/i386/32/sfp-machine.h15
-rw-r--r--libgcc/config/i386/64/sfp-machine.h15
-rw-r--r--libgcc/config/i386/sfp-exceptions.c4
-rw-r--r--libgcc/config/i386/sfp-machine.h15
-rw-r--r--libgcc/configure4
-rw-r--r--libgcc/configure.ac14
-rw-r--r--libgfortran/ChangeLog5
-rw-r--r--libgfortran/io/unix.c12
-rw-r--r--libjava/ChangeLog5
-rwxr-xr-xlibjava/configure2
-rw-r--r--libjava/configure.ac2
-rw-r--r--libstdc++-v3/ChangeLog229
-rw-r--r--libstdc++-v3/Makefile.in5
-rw-r--r--libstdc++-v3/acinclude.m415
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver5
-rw-r--r--libstdc++-v3/config/os/bsd/darwin/os_defines.h5
-rw-r--r--libstdc++-v3/config/os/bsd/openbsd/ctype_base.h59
-rw-r--r--libstdc++-v3/config/os/bsd/openbsd/ctype_configure_char.cc99
-rw-r--r--libstdc++-v3/config/os/bsd/openbsd/ctype_inline.h74
-rw-r--r--libstdc++-v3/config/os/bsd/openbsd/os_defines.h41
-rwxr-xr-xlibstdc++-v3/configure33
-rw-r--r--libstdc++-v3/configure.host5
-rw-r--r--libstdc++-v3/doc/Makefile.in5
-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.in7
-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/hashtable_policy.h37
-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/ext/random467
-rw-r--r--libstdc++-v3/include/ext/random.tcc172
-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.in13
-rw-r--r--libstdc++-v3/libsupc++/atexit_thread.cc151
-rw-r--r--libstdc++-v3/po/Makefile.in5
-rw-r--r--libstdc++-v3/python/Makefile.in5
-rw-r--r--libstdc++-v3/src/Makefile.in5
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in5
-rw-r--r--libstdc++-v3/src/c++11/debug.cc5
-rw-r--r--libstdc++-v3/src/c++98/Makefile.in5
-rw-r--r--libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc62
-rw-r--r--libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc6
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/sfinae_friendly_1.cc9
-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/bitset/45713.cc11
-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.in5
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc43
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/parms.cc43
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/equal.cc42
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/inequal.cc42
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/serialize.cc48
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/explicit_instantiation/1.cc26
-rw-r--r--libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/typedefs.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/default.cc44
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/parms.cc44
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/equal.cc42
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/inequal.cc42
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/serialize.cc48
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/explicit_instantiation/1.cc26
-rw-r--r--libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/typedefs.cc33
481 files changed, 18557 insertions, 4963 deletions
diff --git a/ChangeLog b/ChangeLog
index 9183d808005..98a81624101 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,20 +1,3 @@
-2012-10-05 Pavel Chupin <pavel.v.chupin@intel.com>
-
- Fix missing gthr-default.h issue on separate libstdc++ configure
- * libstdc++-v3/acinclude.m4: Define glibcxx_thread_h.
- * libstdc++-v3/include/Makefile.am: Use glibcxx_thread_h.
- * libstdc++-v3/Makefile.in: Regenerate.
- * libstdc++-v3/configure: Regenerate.
- * libstdc++-v3/doc/Makefile.in: Regenerate.
- * libstdc++-v3/include/Makefile.in: Regenerate.
- * libstdc++-v3/libsupc++/Makefile.in: Regenerate.
- * libstdc++-v3/po/Makefile.in: Regenerate.
- * libstdc++-v3/python/Makefile.in: Regenerate.
- * libstdc++-v3/src/Makefile.in: Regenerate.
- * libstdc++-v3/src/c++11/Makefile.in: Regenerate.
- * libstdc++-v3/src/c++98/Makefile.in: Regenerate.
- * libstdc++-v3/testsuite/Makefile.in: Regenerate.
-
2012-10-10 Richard Biener <rguenther@suse.de>
* MAINTAINERS: Adjust for changed surename.
diff --git a/config/ChangeLog b/config/ChangeLog
index 7db0c6b04c3..c74839ac3c6 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 00000000000..7b29f1f3327
--- /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/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
index 3345364676e..d1eda691c9f 100644
--- a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
+++ b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
@@ -6,69 +6,60 @@ XPASS: gcc.dg/guality/example.c -O2 -flto -fno-use-linker-plugin -flto-partition
XPASS: gcc.dg/guality/example.c -O2 execution test
XPASS: gcc.dg/guality/example.c -O0 execution test
XPASS: gcc.dg/guality/guality.c -O2 execution test
-XPASS: gcc.dg/guality/guality.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/guality.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/guality.c -O1 execution test
+XPASS: gcc.dg/guality/guality.c -O0 execution test
XPASS: gcc.dg/guality/guality.c -O3 -g execution test
-XPASS: gcc.dg/guality/guality.c -O3 -fomit-frame-pointer execution test
+XPASS: gcc.dg/guality/guality.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/guality.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
-XPASS: gcc.dg/guality/guality.c -O0 execution test
XPASS: gcc.dg/guality/guality.c -Os execution test
XPASS: gcc.dg/guality/inline-params.c -O2 execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -g execution test
XPASS: gcc.dg/guality/inline-params.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/inline-params.c -Os execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O2 execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O1 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -fomit-frame-pointer execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O3 -g execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41447-1.c -Os execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O3 -fomit-frame-pointer execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O3 -g execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
XPASS: gcc.dg/guality/pr41616-1.c -O1 execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/pr41616-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41616-1.c -Os execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O2 execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/pr41616-1.c -O3 -g execution test
XPASS: gcc.dg/inline_3.c (test for excess errors)
XPASS: gcc.dg/inline_4.c (test for excess errors)
+FAIL: gcc.dg/torture/pr51106-2.c -O1 (test for excess errors)
+FAIL: gcc.dg/torture/pr51106-2.c -Os (test for excess errors)
FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors)
FAIL: gcc.dg/torture/pr51106-2.c -O3 -g (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O0 (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -Os (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O1 (internal compiler error)
FAIL: gcc.dg/torture/pr51106-2.c -O0 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -g (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O1 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -Os (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (test for excess errors)
FAIL: gcc.dg/torture/pr51106-2.c -O2 (test for excess errors)
+FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (test for excess errors)
+UNRESOLVED: gcc.dg/tree-ssa/cunroll-4.c scan-tree-dump cunrolli "Last iteration exit edge was proved true."
+UNRESOLVED: gcc.dg/tree-ssa/cunroll-4.c scan-tree-dump cunrolli "Turned loop 1 to non-loop; it never loops."
XPASS: gcc.dg/unroll_2.c (test for excess errors)
XPASS: gcc.dg/unroll_3.c (test for excess errors)
XPASS: gcc.dg/unroll_4.c (test for excess errors)
-UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
-FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
-FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
-FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
-UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
-FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
-FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin (internal compiler error)
-FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
+XPASS: gfortran.dg/do_1.f90 -O0 execution test
+XPASS: gfortran.dg/do_1.f90 -O1 execution test
+FAIL: gnat.dg/array11.adb (test for warnings, line 12)
+FAIL: gnat.dg/object_overflow.adb (test for warnings, line 8)
FAIL: libmudflap.c++/pass55-frag.cxx (-O2) execution test
FAIL: libmudflap.c++/pass55-frag.cxx ( -O) execution test
FAIL: libmudflap.c++/pass55-frag.cxx (-O3) execution test
+FAIL: libmudflap.c/fail37-frag.c (-O3) output pattern test
+FAIL: libmudflap.c/fail37-frag.c (-O2) output pattern test
+FAIL: libmudflap.c/fail37-frag.c (-O3) crash test
+FAIL: libmudflap.c/fail37-frag.c (-O2) crash test
FAIL: libstdc++-prettyprinters/shared_ptr.cc print wp1
FAIL: libstdc++-prettyprinters/shared_ptr.cc print wp2
FAIL: libstdc++-prettyprinters/shared_ptr.cc print sp1
-FAIL: sourcelocation output - source compiled test
FAIL: sourcelocation -findirect-dispatch output - source compiled test
FAIL: sourcelocation -O3 output - source compiled test
+FAIL: sourcelocation output - source compiled test
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 70f089cf0e9..7a82d9fcaf6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,1305 @@
-2012-10-18 Xinliang David Li <davidxl@google.com>
+2012-10-19 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/54981
+ * tree-loop-distribution.c (ssa_name_has_uses_outside_loop_p):
+ Do not consider debug stmts as uses.
+
+2012-10-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/54976
+ * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size):
+ Robustify against odd inner_mode inputs.
+
+2012-10-19 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ PR target/54892
+ * config/arm/arm.c (arm_expand_compare_and_swap): Use SImode to make
+ sure the mode is correct when falling through from above cases.
+
+2012-10-19 Bin Cheng <bin.cheng@arm.com>
+
+ * common.opt (flag_ira_hoist_pressure): New.
+ * doc/invoke.texi (-fira-hoist-pressure): Describe.
+ * ira-costs.c (ira_set_pseudo_classes): New parameter.
+ * ira.h: Update copyright dates.
+ (ira_set_pseudo_classes): Update prototype.
+ * haifa-sched.c (sched_init): Update call.
+ * ira.c (ira): Update call.
+ * regmove.c: Update copyright dates.
+ (regmove_optimize): Update call.
+ * loop-invariant.c: Update copyright dates.
+ (move_loop_invariants): Update call.
+ * gcse.c: (struct bb_data): New structure.
+ (BB_DATA): New macro.
+ (curr_bb, curr_reg_pressure): New static variables.
+ (should_hoist_expr_to_dom): Rename from hoist_expr_reaches_here_p.
+ Change parameter expr_index to expr.
+ New parameters pressure_class, nregs and hoisted_bbs.
+ Use reg pressure to determine the distance expr can be hoisted.
+ (hoist_code): Use reg pressure to direct the hoist process.
+ (get_regno_pressure_class, get_pressure_class_and_nregs)
+ (change_pressure, calculate_bb_reg_pressure): New.
+ (one_code_hoisting_pass): Calculate register pressure. Allocate
+ and free data.
+
+2012-10-19 Bin Cheng <bin.cheng@arm.com>
+
+ * gcse.c: Update copyright dates.
+ (hoist_expr_reaches_here_p): Change parameter type from char *
+ to sbitmap.
+
+2012-10-19 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config.gcc
+ (arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtemseabi*): Rename
+ "arm*-*-rtemseabi*" to "arm*-*-rtems*".
+
+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>
- * asan.c (asan_init_shadow_ptr_types): change shadow type
- to signed type.
+ * 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
+ return-value register too.
+
+2012-10-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR rtl-optimization/38711
+ * df.h (df_get_live_out, df_get_live_in): Make static inline functions.
+ * df-problems.c (df_get_live_out, df_get_live_in): Moved to df.h.
+ * ira-lives.c (process_bb_node_lives): Use df_get_live_out instead of
+ DF_LR_OUT.
+ * ira-build.c (create_bb_allocnos): Likewise.
+ (create_loop_allocnos): Likewise, and use df_get_live_in instead of
+ DF_LR_IN.
+ * ira-emit.c (generate_edge_moves): Likewise.
+ (add_ranges_and_copies): Likewise.
+ * ira-color.c (ira_loop_edge_freq): Use df_get_live_out instead of
+ DF_LR_OUT, and df_get_live_in instead of DF_LR_IN.
+ * ira.c (mark_elimination): Update DF_LR and DF_LIVE.
+ (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
+ * loop-unroll.c (struct var_to_expand): Remove accum_pos field.
+ (analyze_insn_to_expand_var): Do not record accum_pos.
+ (expand_var_during_unrolling): Use validate_replace_rtx_group to
+ perform replacement of all references to SET_DEST (set) with the
+ new register, including references in REG_EQUAL notes.
+ (insert_var_expansion_initialization): Insert initializatio insns
+ at the bottom of the pre-header of the loop.
+
+2012-10-14 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not
+ predict loops with multiple exits realistically.
+ * cfgloopanal.c (single_likely_exit): New function.
+
+2012-10-14 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md: Remove empty predicates and/or constraints.
+ * config/alpha/sync.md: Ditto.
+
+2012-10-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (I24MODE): New mode iterator.
+ (any_divmod): New code iterator.
+ (<code>si3): Macroize expander from {div,mod,udiv,umod}si3 using
+ any_divmod code iterator.
+ (<code>si3): Macroize expander from {div,mod,udiv,umod}di3 using
+ any_divmod code iterator.
+ (extendqi<mode>2): Macroize insn from extendqi{hi,si}2 using
+ I24MODE mode iterator.
+ (unaligned_store<mode>): Macroize expander from unaligned_store{qi,hi}
+ using I12MODE mode iterator.
+ (mov<mode>): Macroize expander from mov{qi,hi} using
+ I12MODE mode iterator.
+
+2012-10-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/54871
+ * loop-iv.c (simplify_using_initial_values): When scanning previous
+ basic blocks, prune the recorded conditions if the current insn was
+ not used to make a replacement.
+
+ * loop-unroll.c (decide_unroll_constant_iterations): Clean up message.
+ (unroll_loop_constant_iterations): Clarify head comment.
+ (decide_unroll_runtime_iterations): Clean up message.
+ (unroll_loop_runtime_iterations): Clarify head comment.
+ (decide_peel_simple): Clean up message.
+ (peel_loop_simple): Clarify head comment.
+ (decide_unroll_stupid): Clean up message.
+ (unroll_loop_stupid): Clarify head comment.
+
+2012-10-13 Andreas Schwab <schwab@linux-m68k.org>
+
+ PR gcov-profile/44728
+ * gcov.c (create_file_names): When stripping extension only look
+ at base name.
+
+2012-10-13 Jan Hubicka <jh@suse.cz>
+
+ * loop-iv.c (determine_max_iter): Fix handling of AND.
+ (iv_number_of_iterations): Record upper bounds as unsigned
+ values.
+
+2012-10-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ira.c (ira): Set current_loops to &ira_loops before recording
+ loop exits. Release recorded exits and loops early.
+
+2012-10-13 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * builtins.c (expand_builtin_set_thread_pointer): Use
+ create_input_operand() instead of create_fixed_operand().
+
+2012-10-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (FMODE): New mode iterator.
+ (modesuffix): Handle SF and DF modes.
+ (opmode): New mode attribute.
+ (abs<mode>2): Macroize insn from abs{sf,df}2 using FMODE mode iterator.
+ (*nabs<mode>2): Macroize insn from *nabs{sf,df}2 using
+ FMODE mode iterator.
+ (neg<mode>2): Macroize insn from neg{sf,df}2 using FMODE mode iterator.
+ (copysign<mode>3): Macroize insn from copysign{sf,df}3 using
+ FMODE mode iterator.
+ (*ncopysign<mode>3): Macroize insn from *ncopysign{sf,df}3 using
+ FMODE mode iterator.
+ (*add<mode>3_ieee): Macroize insn from *add{sf,df}_ieee using
+ FMODE mode iterator.
+ (add<mode>3): Macroize insn from add{sf,df}3 using FMODE mode iterator.
+ (*sub<mode>3_ieee): Macroize insn from *sub{sf,df}3_ieee using
+ FMODE mode iterator.
+ (sub<mode>3): Macroize insn from sub{sf,df}3 using FMODE mode iterator.
+ (*mul<mode>3_ieee): Macroize insn from *mul{sf,df}3_ieee using
+ FMODE mode iterator.
+ (mul<mode>3): Macroize insn from mul{sf,df}3 using FMODE mode iterator.
+ (*div<mode>3_ieee): Macroize insn from *div{sf,df}3_ieee using
+ FMODE mode iterator.
+ (div<mode>3): Macroize insn from div{sf,df}3 using FMODE mode iterator.
+ (*sqrt<mode>2_ieee): Macroize insn from *sqrt{sf,df}2_ieee using
+ FMODE mode iterator.
+ (sqrt<mode>2): Macroize insn from sqrt{sf,df}2
+ using FMODE mode iterator.
+ (*mov<mode>cc_internal): Macroize insn from *mov{sf,df}cc_internal
+ using FMODE mode iterator.
+ (mov<mode>cc): Macroize expander from mov{sf,df}cc
+ using FMODE mode iterator.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54602
+ * config/sh/sh.md: Correct define_delay for return insns.
+ (*movsi_pop): Delete.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54680
+ * config/sh/sh.c (sh_fsca_sf2int, sh_fsca_int2sf): Fix swapped
+ comments.
+ * config/sh/predicates.md (fpul_operand): Add comment.
+ (fpul_fsca_operand, fsca_scale_factor): New predicates.
+ * config/sh/sh.md (fsca): Move below sincossf3 expander. Convert to
+ insn_and_split. Use fpul_fsca_operand and fsca_scale_factor
+ predicates. Simplify fpul operand in splitter.
+
+2012-10-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-threadupdate.c (def_split_header_continue_p): Do not
+ escape the loop.
+
+2012-10-12 Jan Hubicka <jh@suse.cz>
+
+ * web.c (web_main): Do not set DF_RD_PRUNE_DEAD_DEFS flag.
+
+2012-10-12 Aaron Gray <aaronngray.lists@gmail.com>
+ Diego Novillo <dnovillo@google.com>
+
+ * gengtype-lex.l: Support for C++ single line comments.
+ Support for classes.
+ (CXX_KEYWORD): New. Support C++ keywords inline, public,
+ protected, private, template, operator, friend, &, ~.
+ (TYPEDEF): New. Support typedef.
+ * gengtype-parser.c: updated 'token_names[]'
+ (direct_declarator): Add support for parsing functions and ctors.
+
+2012-10-12 Diego Novillo <dnovillo@google.com>
+
+ * doc/gty.texi: Document C++ limitations in gengtype.
+ * gengtype-lex.l (CID): Rename from ID.
+ (ID): Include scoping '::' as part of the identifier name.
+ * gengtype-parse.c (token_names): Update.
+ (token_value_format): Update.
+ (consume_until_eos): Rename from consume_until_semi.
+ Remove unused argument IMMEDIATE. Update all callers.
+ Also consider '}' as a finalizer.
+ (consume_until_comma_or_eos): Rename from
+ consume_until_comma_or_semi.
+ Remove unused argument IMMEDIATE. Update all callers.
+ Also consider '}' as a finalizer.
+ (direct_declarator): Add documentation on ctor support.
+ Add argument IN_STRUCT.
+ If the token following ID is a '(', consider ID a
+ function and return NULL.
+ If the token following '(' is not a '*', and IN_STRUCT is true,
+ conclude that this is a ctor and return NULL.
+ If the token is IGNORABLE_CXX_KEYWORD, return NULL.
+ (inner_declarator): Add argument IN_STRUCT.
+ Update all callers.
+ (declarator): Add argument IN_STRUCT with default value false.
+ Update all callers.
+ (type): Document argument NESTED.
+ Skip over C++ inheritance specifiers.
+ If a token TYPEDEF is found, emit an error.
+ If an enum is found inside a class/structure, emit an error.
+ (typedefs, structures, param_structs, variables): Initialize.
+ (new_structure): Do not complain about duplicate
+ structures if S has a line location set.
+ * gengtype-state.c (write_state_type): Remove default handler.
+ Add handler for TYPE_NONE.
+ (read_state_scalar_char_type):
+ * gengtype.c: Fix spacing.
+ * gengtype.h (enum gty_token): Add name. Add token
+ IGNORABLE_CXX_KEYWORD.
+
+2012-10-12 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * config/arm/arm.md (get_thread_pointersi): Moved to place with
+ other TLS related patterns.
+
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ * tree-streamer-out.c (pack_ts_target_option): Rename from ...
+ (write_ts_target_option): ... this.
+ (pack_ts_optimization): Rename from ...
+ (write_ts_optimization): ... this.
+ (streamer_pack_tree_bitfields): Pack them in the bitfield section ...
+ (streamer_write_tree_body): ... not here.
+ * tree-streamer-in.c (unpack_ts_target_option): Rename from ...
+ (lto_input_ts_target_option): ... this.
+ (unpack_ts_optimization): Rename from ...
+ (lto_input_ts_optimization): ... this.
+ (unpack_value_fields): Unpack them from the bitfield section ...
+ (streamer_read_tree_body): ... not from here.
+
+2012-10-12 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (vecmodesuffix): New mode attribute.
+ (modesuffix): Handle V8QI and V4HI modes.
+ (any_maxmin): New code iterator.
+ (maxmin): New code attribute.
+ (<code><mode>3): Macroize insn from {smax,smin,umax,umin}{qi,hi}3
+ using any_maxmin code iterator and I12MODE mode iterator.
+ (<code><mode>3): Macroize insn from {smax,smin,umax,umin}{v8qi,v4hi}3
+ using any_maxmin code iterator and VEC12 mode iterator.
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ * optabs.c (vector_compare_rtx): Change prototype.
+ (expand_vec_cond_expr): Handle VEC_COND_EXPR whose first operand
+ is not a comparison.
+ * gimplify.c (gimplify_expr): Handle VEC_COND_EXPR.
+
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/54894
+ * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size):
+ Handle over-aligned scalar types properly.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54760
+ * config/sh/sh.c (bdesc): Remove thread pointer built-ins.
+ * config/sh/sh.md (get_thread_pointer, set_thread_pointer): Append mode
+ name 'si'.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * config/sh/sh.md (negsi_cond, negdi_cond, stack_protect_test): Remove
+ get_t_reg_rtx when invoking gen_branch_true or gen_branch_false.
+ (*zero_extend<mode>si2_compact): Convert to insn_and_split. Convert
+ zero extensions of T bit stores to reg moves in splitter. Remove
+ obsolete unnamed peephole2 that caught zero extensions after negc T bit
+ stores.
+ (*branch_true_eq, *branch_false_ne): Delete.
+ (branch_true, branch_false): Convert insn to expander. Move actual
+ insn logic to...
+ (*cbranch_t): ...this new insn_and_split. Try to find preceding
+ redundant T bit stores and tests and combine them with the conditional
+ branch if possible in the splitter.
+ (movrt_xor, *movt_movrt): New insn_and_split.
+ * config/sh/predicates.md (cbranch_treg_value): New predicate.
+ * config/sh/sh-protos.h (sh_eval_treg_value): Forward declare...
+ * config/sh/sh.c (sh_eval_treg_value): ...this new function.
+ (expand_cbranchsi4, expand_cbranchdi4): Remove get_t_reg_rtx
+ when invoking gen_branch_true or gen_branch_false.
+
+2012-10-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (IMODE): New mode iterator.
+ (I124MODE): Ditto.
+ (I248MODE): Ditto.
+ (modesuffix): Handle QI and HI modes.
+ (zero_extendqi<mode>2): Macroize insn from zero_extendqi{hi,si,di}2
+ using I248MODE mode iterator.
+ (zero_extendhi<mode>2): Macroize insn from zero_extendhi{si,di}2
+ using I48MODE mode iterator.
+ (andnot<mode>3): Macroize insn from andnot{si,di}3 using
+ I48MODE mode iterator.
+ (ins<modesuffix>l_const): Macroize insn from ins{b,w,l}l_const
+ using I248MODE mode iterator.
+ (ins<modesuffix>l): Macroize insn from ins{b,w,l}l
+ using I248MODE mode iterator.
+ (*mov<mode>cc_internal): Macroize insn from
+ *mov{qi,hi,si,di}cc_internal using IMODE mode iterator.
+ (*mov<mode>cc_lbc): Macroize insn from
+ *mov{qi,hi,si,di}cc_lbc using IMODE mode iterator.
+ (*mov<mode>cc_lbs): Macroize insn from
+ *mov{qi,hi,si,di}cc_lbs using IMODE mode iterator.
+ (mov<mode>cc): Macroize expander from mov{si,di}cc
+ using I48MODE mode iterator.
+
+2012-10-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ira-build.c (ira_loop_tree_body_rev_postorder): New function.
+ (ira_traverse_loop_tree): Traverse a loop's basic blocks in
+ reverse post-order of the reversed control-flow direction.
+ * ira-conflicts.c (ira_build_conflicts): Pass add_copies as
+ the pre-order function to ira_traverse_loop_tree to preserve
+ the existing semantics.
+
+ * ira-lives.c (remove_some_program_points_and_update_live_ranges):
+ Squeeze out live range chain elements if their program points are
+ connected.
+
+2012-10-11 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.def (REDUC_PLUS_EXPR): Fix up comment.
+
+ * fold-const.c (fold_unary_loc): Handle REDUC_MIN_EXPR,
+ REDUC_MAX_EXPR and REDUC_PLUS_EXPR.
+
+2012-10-11 James Lemke <jwlemke@codesourcery.com>
+
+ * config/rs6000/predicates.md (zero_fp_constant): Fix comment.
+ * config/rs6000/rs6000.md (return_pred): Fix null return.
+ * config/rs6000/rs6000.c (rs6000_emit_set_const): Fix indentation.
+ (print_operand): Make FALLTHRU obvious.
+ (output_cbranch): Correct comment.
+
+2012-10-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (DWI): New mode attribute.
+ (*sadd<modesuffix>): Macroize insn from *saddl and *saddq using
+ I48MODE mode iterator.
+ (addv<mode>3): Macroize insn from addvsi3 and addvdi3 using
+ I48MODE mode iterator.
+ (neg<mode>2): Macroize insn from negsi2 and negdi2 using
+ I48MODE mode iterator.
+ (negv<mode>2): Macroize insn from negvsi2 and negvdi2 using
+ I48MODE mode iterator.
+ (sub<mode>3): Macroize insn from subsi3 and subdi3 using
+ I48MODE mode iterator.
+ (*ssub<modesuffix>): Macroize insn from *ssubl and *ssubq using
+ I48MODE mode iterator.
+ (subv<mode>3): Macroize insn from subvsi3 and subvdi3 using
+ I48MODE mode iterator.
+ (mul<mode>3): Macroize insn from mulsi3 and muldi3 using
+ I48MODE mode iterator.
+ (mulv<mode>3): Macroize insn from mulvsi3 and mulvdi3 using
+ I48MODE mode iterator.
+ (*iornot<mode>3): Macroize insn from *iornotsi3 and *iornotdi3 using
+ I48MODE mode iterator.
+ (*xornot<mode>3): Macroize insn from *xornotsi3 and *xornotdi3 using
+ I48MODE mode iterator.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * configure.ac (gcc_cv_as_aix_ref): Fix typo.
+ * configure: Regenerate.
+
+2012-10-11 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * builtins.c (expand_builtin_thread_pointer): New.
+ (expand_builtin_set_thread_pointer): New.
+ (expand_builtin): Add BUILT_IN_THREAD_POINTER,
+ BUILT_IN_SET_THREAD_POINTER expand cases.
+ * builtins.def (BUILT_IN_THREAD_POINTER):
+ New __builtin_thread_pointer builtin.
+ (BUILT_IN_SET_THREAD_POINTER):
+ New __builtin_set_thread_pointer builtin.
+ * optabs.def (get_thread_pointer,set_thread_pointer):
+ New standard names.
+ * doc/md.texi (Standard Names): Document get_thread_pointer and
+ set_thread_pointer patterns.
+ * config/alpha/alpha.md (get_thread_pointerdi): Rename from load_tp.
+ (set_thread_pointerdi): Rename from set_tp.
+ * config/alpha/alpha.c (alpha_legitimize_address_1): Change
+ gen_load_tp calls to gen_get_thread_pointerdi.
+ (alpha_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER,
+ ALPHA_BUILTIN_SET_THREAD_POINTER.
+ (code_for_builtin): Remove CODE_FOR_load_tp, CODE_FOR_set_tp.
+ (alpha_init_builtins): Remove __builtin_thread_pointer,
+ __builtin_set_thread_pointer machine-specific builtins.
+ (alpha_expand_builtin_thread_pointer): Add hook function for
+ TARGET_EXPAND_BUILTIN_THREAD_POINTER.
+ (alpha_expand_builtin_set_thread_pointer): Add hook function for
+ TARGET_EXPAND_BUILTIN_SET_THREAD_POINTER.
+ (alpha_fold_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER,
+ ALPHA_BUILTIN_SET_THREAD_POINTER cases.
+ * config/arm/arm.md (get_thread_pointersi): New pattern.
+ * config/arm/arm-protos.h (arm_load_tp): Add extern declaration.
+ * config/arm/arm.c (arm_load_tp): Remove static.
+ (arm_builtins): Remove ARM_BUILTIN_THREAD_POINTER.
+ (arm_init_tls_builtins): Remove function.
+ (arm_init_builtins): Remove call to arm_init_tls_builtins().
+ (arm_expand_builtin): Remove ARM_BUILTIN_THREAD_POINTER case.
+ * config/mips/mips.md (get_thread_pointer<mode>): New pattern.
+ * config/mips/mips-protos.h (mips_expand_thread_pointer):
+ Add extern declaration.
+ * config/mips/mips.c (mips_expand_thread_pointer):
+ Renamed from mips_get_tp.
+ (mips_get_tp): New stub calling mips_expand_thread_pointer.
+ * config/s390/s390.c (s390_builtin,code_for_builtin_64,
+ code_for_builtin_31,s390_init_builtins,s390_expand_builtin): Remove.
+ * config/s390/s390.md (get_tp_64,get_tp_31,set_tp_64,set_tp_31):
+ Remove.
+ (get_thread_pointer<mode>,set_thread_pointer<mode>):
+ New, adapted from removed patterns.
+ * config/xtensa/xtensa.md (get_thread_pointersi):
+ Renamed from load_tp.
+ (set_thread_pointersi): Renamed from set_tp.
+ * config/xtensa/xtensa.c (xtensa_legitimize_tls_address):
+ Change gen_load_tp calls to gen_get_thread_pointersi.
+ (xtensa_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER and
+ XTENSA_BUILTIN_SET_THREAD_POINTER.
+ (xtensa_init_builtins): Remove __builtin_thread_pointer,
+ __builtin_set_thread_pointer machine-specific builtins.
+ (xtensa_fold_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER,
+ XTENSA_BUILTIN_SET_THREAD_POINTER cases.
+ (xtensa_expand_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER,
+ XTENSA_BUILTIN_SET_THREAD_POINTER cases.
+
+2012-10-11 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/extend.texi (Vector Extensions): C++ improvements.
+ * doc/generic.texi (LSHIFT_EXPR, RSHIFT_EXPR): Mixed vector-scalar.
+ (LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EQ_EXPR, NE_EXPR): Specify
+ the vector case.
+ (VEC_COND_EXPR): Document it.
+
+2012-10-11 Terry Guo <terry.guo@arm.com>
+
+ * config/arm/arm.c (arm_arch6m): New variable to denote armv6-m
+ architecture.
+ * config/arm/arm.h (TARGET_HAVE_DMB): The armv6-m also has DMB
+ instruction.
+
+2012-10-11 Hans-Peter Nilsson <hp@bitrange.com>
+
+ PR target/54373
+ * configure.ac (out-of-tree linker .hidden support) Set to "no"
+ for mmix-knuth-mmixware.
+ * configure: Regenerate.
+
+ * configure.ac (gcc_cv_as_comdat_group_group): Default to no.
+ * configure: Regenerate.
+
+ * acinclude.m4 (_gcc_COMPUTE_GAS_VERSION): Allow a single
+ character to quote the VERSION= contents. Sanity-check contents.
+ * configure.ac ("what linker to use" ld version extraction): Ditto.
+ * configure: Regenerate.
+
+2012-10-10 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.h (PRINT_OPERAND_PUNCT_VALID_P): Delete '.'.
+
+2012-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/54877
+ * tree-vect-loop.c (vect_is_simple_reduction_1): For MINUS_EXPR
+ use make_ssa_name instead of copy_ssa_name.
2012-10-10 Richard Biener <rguenther@suse.de>
@@ -15,8 +1313,7 @@
(lto_write_tree): Adjust.
(output_eh_region): Likewise.
(output_struct_function_base): Likewise.
- * lto-streamer.c (lto_streamer_hooks_init): Initialize location
- hooks.
+ * lto-streamer.c (lto_streamer_hooks_init): Initialize location hooks.
* lto-streamer.h (lto_input_location): Adjust prototype.
(lto_output_location): Likewise.
* streamer-hooks.h (struct streamer_hooks): Adjust prototype
@@ -97,8 +1394,7 @@
(rs6000_print_options_internal): New function for expanded
-mdebug=reg option printing to print both the ISA options, and the
builtins that are enabled.
- (rs6000_print_isa_options): New function to print the ISA
- options.
+ (rs6000_print_isa_options): New function to print the ISA options.
(rs6000_print_builtin_options): New function to print the builtin
functions enabled.
@@ -137,7 +1433,7 @@
2012-10-10 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config.gcc: Enable zEC12 for with-arch and with-tune
- configure switches.
+ configure switches.
* common/config/s390/s390-common.c (processor_flags_table): Add
zEC12 entry.
* config/s390/2827.md: New file.
@@ -150,8 +1446,7 @@
Set parameter defaults for zEC12.
(legitimate_reload_fp_constant_p): Adjust comment.
(preferred_la_operand_p): Adjust comment.
- (s390_expand_insv): Generate insv pattern without CC clobber for
- zEC12.
+ (s390_expand_insv): Generate insv pattern without CC clobber for zEC12.
(s390_adjust_priority): Add zEC12 check.
(s390_issue_rate): Return 2 for zEC12.
(s390_reorg): Enable code optimizations for zEC12.
@@ -179,8 +1474,10 @@
(*movsf_insn): Likewise.
(*movdf_insn_sp64): Likewise.
(*mov<VM32:mode>_insn): Likewise, use 'fsrc2s' instead of 'fsrc1s'.
- (*mov<VM64:mode>_insn_sp64): Likewise, use 'fsrc2s' instead of 'fsrc1s'.
- (*mov<VM64:mode>_insn_sp32): Likewise, use 'fsrc2s' instead of 'fsrc1s'.
+ (*mov<VM64:mode>_insn_sp64): Likewise, use 'fsrc2s'
+ instead of 'fsrc1s'.
+ (*mov<VM64:mode>_insn_sp32): Likewise, use 'fsrc2s'
+ instead of 'fsrc1s'.
(VIS logical instructions): Mark as visl.
(pdist_vis): Use 'pdist'.
(pditsn<mode>_vis): Use 'pdistn'.
@@ -211,15 +1508,16 @@
* Makefile.in (fold-const.o): Add depencence on hash-table.h.
(dse.o): Likewise.
(cfg.o): Likewise.
- * fold-const.c (fold_checksum_tree): Change to new type-safe hash table.
+ * fold-const.c (fold_checksum_tree): Change to new
+ type-safe hash table.
* (print_fold_checksum): Likewise.
* cfg.c (var bb_original): Likewise.
* (var bb_copy): Likewise.
* (var loop_copy): Likewise.
* hash-table.h (template hash_table): Constify parameters for find...
and remove_elt... member functions.
- (hash_table::empty) Correct size expression.
- (hash_table::clear_slot) Correct deleted entry assignment.
+ (hash_table::empty) Correct size expression.
+ (hash_table::clear_slot) Correct deleted entry assignment.
* dse.c (var rtx_group_table): Change to new type-safe hash table.
2012-10-09 Steven Bosscher <steven@gcc.gnu.org>
@@ -18606,7 +19904,7 @@
2012-04-26 Bernd Schmidt <bernds@codesourcery.com>
- * PR middle-end/52997
+ PR middle-end/52997
* ira.c (find_moveable_pseudos): Call resize_reg_info.
PR middle-end/52940
diff --git a/gcc/ChangeLog.asan b/gcc/ChangeLog.asan
index 3da0a0b4303..8b9fd58a42c 100644
--- a/gcc/ChangeLog.asan
+++ b/gcc/ChangeLog.asan
@@ -1,3 +1,12 @@
+2012-10-19 Diego Novillo <dnovillo@google.com>
+
+ Merge from trunk rev 192612.
+
+2012-10-18 Xinliang David Li <davidxl@google.com>
+
+ * asan.c (asan_init_shadow_ptr_types): change shadow type
+ to signed type.
+
2012-10-18 Jakub Jelinek <jakub@redhat.com>
* asan.c (build_check_stmt): Unshare base.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index d89fa2927fe..68ed05b6a70 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20121010
+20121019
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3edabcfbad5..73a714189e8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3106,7 +3106,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/acinclude.m4 b/gcc/acinclude.m4
index c24464b5977..fe7c5b699d0 100644
--- a/gcc/acinclude.m4
+++ b/gcc/acinclude.m4
@@ -393,11 +393,15 @@ for f in $gcc_cv_as_bfd_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure.in \
$gcc_cv_as_gas_srcdir/Makefile.in ; do
- gcc_cv_gas_version=`sed -n -e 's/^[[ ]]*\(VERSION=[[0-9]]*\.[[0-9]]*.*\)/\1/p' < $f`
+ gcc_cv_gas_version=`sed -n -e 's/^[[ ]]*VERSION=[[^0-9A-Za-z_]]*\([[0-9]]*\.[[0-9]]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gas_version != x; then
break
fi
done
+case $gcc_cv_gas_version in
+ VERSION=[[0-9]]*) ;;
+ *) AC_MSG_ERROR([[cannot find version of in-tree assembler]]);;
+esac
gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([[0-9]]*\)"`
gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.\([[0-9]]*\)"`
gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)"`
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 1a9ff91cf3f..6aa07b00c9c 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 18446e0c79b..3b2b2a789d7 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 0c6a7442b84..c5e64176313 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 61351fb248d..d9bd3b7e550 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/builtins.c b/gcc/builtins.c
index e6b10ea43b9..c309566919e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5744,6 +5744,45 @@ expand_builtin_sync_synchronize (void)
expand_mem_thread_fence (MEMMODEL_SEQ_CST);
}
+static rtx
+expand_builtin_thread_pointer (tree exp, rtx target)
+{
+ enum insn_code icode;
+ if (!validate_arglist (exp, VOID_TYPE))
+ return const0_rtx;
+ icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand op;
+ if (!REG_P (target) || GET_MODE (target) != Pmode)
+ target = gen_reg_rtx (Pmode);
+ create_output_operand (&op, target, Pmode);
+ expand_insn (icode, 1, &op);
+ return target;
+ }
+ error ("__builtin_thread_pointer is not supported on this target");
+ return const0_rtx;
+}
+
+static void
+expand_builtin_set_thread_pointer (tree exp)
+{
+ enum insn_code icode;
+ if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
+ return;
+ icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand op;
+ rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+ Pmode, EXPAND_NORMAL);
+ create_input_operand (&op, val, Pmode);
+ expand_insn (icode, 1, &op);
+ return;
+ }
+ error ("__builtin_set_thread_pointer is not supported on this target");
+}
+
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -6809,6 +6848,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
maybe_emit_free_warning (exp);
break;
+ case BUILT_IN_THREAD_POINTER:
+ return expand_builtin_thread_pointer (exp, target);
+
+ case BUILT_IN_SET_THREAD_POINTER:
+ expand_builtin_set_thread_pointer (exp);
+ return const0_rtx;
+
default: /* just do library call, if unknown builtin */
break;
}
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 69000bcfc04..177bf4963aa 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -782,6 +782,17 @@ DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_N
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
false, false, false, ATTR_NULL, true, true)
+/* TLS thread pointer related builtins. */
+DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer",
+ BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST,
+ false, false, true, ATTR_CONST_NOTHROW_LIST, true,
+ targetm.have_tls)
+
+DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer",
+ BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST,
+ false, false, true, ATTR_NOTHROW_LIST, true,
+ targetm.have_tls)
+
/* TLS emulation. */
DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address,
BUILT_IN_NORMAL,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 9a438f038f0..454196fb632 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,6 +1,50 @@
+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
+ * c-common.h (sizeof_pointer_memaccess_warning): Adjust prototype.
+ * c-common.c (sizeof_pointer_memaccess_warning): Take array of 3
+ locs and array of 3 trees instead of just single loc and single
+ sizeof_arg tree. Handle __builtin___*_chk builtins too, and
+ also stpncpy, bcopy, bcmp, bzero, snprintf and vsnprintf builtins.
+ For *cmp* builtins that take two sources strings report warnings
+ about first and second source, not about destination and source.
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * c-common.h (enum ref_operator) [RO_ARROW_STAR]: New.
+
+2012-10-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (dump_ada_template): Bail out for template declarations
+ declaring something coming from another file.
+
2012-10-10 Arnaud Charlet <charlet@adacore.com>
-PR ada/54845
+ PR ada/54845
* c-ada-spec.c (print_ada_struct_decl): Increase buf size.
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 36a86e5abd5..4c47ed44a54 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;
@@ -1700,10 +1723,18 @@ static int
dump_ada_template (pretty_printer *buffer, tree t,
int (*cpp_check)(tree, cpp_operation), int spc)
{
- tree inst = DECL_VINDEX (t);
/* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
+ tree inst = DECL_VINDEX (t);
+ /* DECL_RESULT_FLD is DECL_TEMPLATE_RESULT in this context. */
+ tree result = DECL_RESULT_FLD (t);
int num_inst = 0;
+ /* Don't look at template declarations declaring something coming from
+ another file. This can occur for template friend declarations. */
+ if (LOCATION_FILE (decl_sloc (result, false))
+ != LOCATION_FILE (decl_sloc (t, false)))
+ return 0;
+
while (inst && inst != error_mark_node)
{
tree types = TREE_PURPOSE (inst);
@@ -2167,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);
@@ -2185,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-common.c b/gcc/c-family/c-common.c
index b9186489a40..34cfb98f85b 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1847,52 +1847,105 @@ strict_aliasing_warning (tree otype, tree type, tree expr)
sizeof as last operand of certain builtins. */
void
-sizeof_pointer_memaccess_warning (location_t loc, tree callee,
- VEC(tree, gc) *params, tree sizeof_arg,
+sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
+ VEC(tree, gc) *params, tree *sizeof_arg,
bool (*comp_types) (tree, tree))
{
tree type, dest = NULL_TREE, src = NULL_TREE, tem;
- bool strop = false;
+ bool strop = false, cmp = false;
+ unsigned int idx = ~0;
+ location_t loc;
if (TREE_CODE (callee) != FUNCTION_DECL
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
- || sizeof_arg == error_mark_node
|| VEC_length (tree, params) <= 1)
return;
- type = TYPE_P (sizeof_arg) ? sizeof_arg : TREE_TYPE (sizeof_arg);
- if (!POINTER_TYPE_P (type))
- return;
-
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_STRNCMP:
case BUILT_IN_STRNCASECMP:
+ cmp = true;
+ /* FALLTHRU */
case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_STRNCAT:
+ case BUILT_IN_STRNCAT_CHK:
+ case BUILT_IN_STPNCPY:
+ case BUILT_IN_STPNCPY_CHK:
strop = true;
/* FALLTHRU */
case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMMOVE_CHK:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 1);
+ dest = VEC_index (tree, params, 0);
+ idx = 2;
+ break;
+ case BUILT_IN_BCOPY:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 0);
+ dest = VEC_index (tree, params, 1);
+ idx = 2;
+ break;
case BUILT_IN_MEMCMP:
+ case BUILT_IN_BCMP:
if (VEC_length (tree, params) < 3)
return;
src = VEC_index (tree, params, 1);
dest = VEC_index (tree, params, 0);
+ idx = 2;
+ cmp = true;
break;
case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMSET_CHK:
if (VEC_length (tree, params) < 3)
return;
dest = VEC_index (tree, params, 0);
+ idx = 2;
+ break;
+ case BUILT_IN_BZERO:
+ dest = VEC_index (tree, params, 0);
+ idx = 1;
break;
case BUILT_IN_STRNDUP:
src = VEC_index (tree, params, 0);
strop = true;
+ idx = 1;
+ break;
+ case BUILT_IN_MEMCHR:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 0);
+ idx = 2;
+ break;
+ case BUILT_IN_SNPRINTF:
+ case BUILT_IN_SNPRINTF_CHK:
+ case BUILT_IN_VSNPRINTF:
+ case BUILT_IN_VSNPRINTF_CHK:
+ dest = VEC_index (tree, params, 0);
+ idx = 1;
+ strop = true;
break;
default:
break;
}
+ if (idx >= 3)
+ return;
+
+ if (sizeof_arg[idx] == NULL || sizeof_arg[idx] == error_mark_node)
+ return;
+
+ type = TYPE_P (sizeof_arg[idx])
+ ? sizeof_arg[idx] : TREE_TYPE (sizeof_arg[idx]);
+ if (!POINTER_TYPE_P (type))
+ return;
+
if (dest
&& (tem = tree_strip_nop_conversions (dest))
&& POINTER_TYPE_P (TREE_TYPE (tem))
@@ -1905,13 +1958,15 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee,
&& comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
return;
- if (dest)
+ loc = sizeof_arg_loc[idx];
+
+ if (dest && !cmp)
{
- if (!TYPE_P (sizeof_arg)
- && operand_equal_p (dest, sizeof_arg, 0)
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (dest, sizeof_arg[idx], 0)
&& comp_types (TREE_TYPE (dest), type))
{
- if (TREE_CODE (sizeof_arg) == ADDR_EXPR && !strop)
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
warning_at (loc, OPT_Wsizeof_pointer_memaccess,
"argument to %<sizeof%> in %qD call is the same "
"expression as the destination; did you mean to "
@@ -1945,13 +2000,13 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee,
}
}
- if (src)
+ if (src && !cmp)
{
- if (!TYPE_P (sizeof_arg)
- && operand_equal_p (src, sizeof_arg, 0)
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (src, sizeof_arg[idx], 0)
&& comp_types (TREE_TYPE (src), type))
{
- if (TREE_CODE (sizeof_arg) == ADDR_EXPR && !strop)
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
warning_at (loc, OPT_Wsizeof_pointer_memaccess,
"argument to %<sizeof%> in %qD call is the same "
"expression as the source; did you mean to "
@@ -1984,6 +2039,87 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee,
return;
}
}
+
+ if (dest)
+ {
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (dest, sizeof_arg[idx], 0)
+ && comp_types (TREE_TYPE (dest), type))
+ {
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the first source; did you mean to "
+ "remove the addressof?", callee);
+ else if ((TYPE_PRECISION (TREE_TYPE (type))
+ == TYPE_PRECISION (char_type_node))
+ || strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the first source; did you mean to "
+ "provide an explicit length?", callee);
+ else
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the first source; did you mean to "
+ "dereference it?", callee);
+ return;
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (dest))
+ && !strop
+ && comp_types (TREE_TYPE (dest), type)
+ && !VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "pointer type %qT as the first source; expected %qT "
+ "or an explicit length", callee, TREE_TYPE (dest),
+ TREE_TYPE (TREE_TYPE (dest)));
+ return;
+ }
+ }
+
+ if (src)
+ {
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (src, sizeof_arg[idx], 0)
+ && comp_types (TREE_TYPE (src), type))
+ {
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the second source; did you mean to "
+ "remove the addressof?", callee);
+ else if ((TYPE_PRECISION (TREE_TYPE (type))
+ == TYPE_PRECISION (char_type_node))
+ || strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the second source; did you mean to "
+ "provide an explicit length?", callee);
+ else
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the second source; did you mean to "
+ "dereference it?", callee);
+ return;
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (src))
+ && !strop
+ && comp_types (TREE_TYPE (src), type)
+ && !VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "pointer type %qT as the second source; expected %qT "
+ "or an explicit length", callee, TREE_TYPE (src),
+ TREE_TYPE (TREE_TYPE (src)));
+ return;
+ }
+ }
+
}
/* Warn for unlikely, improbable, or stupid DECL declarations
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index cb18b4e0747..94449a5f3f3 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -477,7 +477,9 @@ typedef enum ref_operator {
/* -> */
RO_ARROW,
/* implicit conversion */
- RO_IMPLICIT_CONVERSION
+ RO_IMPLICIT_CONVERSION,
+ /* ->* */
+ RO_ARROW_STAR
} ref_operator;
/* Information about a statement tree. */
@@ -767,8 +769,8 @@ extern tree fix_string_type (tree);
extern void constant_expression_warning (tree);
extern void constant_expression_error (tree);
extern bool strict_aliasing_warning (tree, tree, tree);
-extern void sizeof_pointer_memaccess_warning (location_t, tree,
- VEC(tree, gc) *, tree,
+extern void sizeof_pointer_memaccess_warning (location_t *, tree,
+ VEC(tree, gc) *, tree *,
bool (*) (tree, tree));
extern void warnings_for_convert_and_check (tree, tree, tree);
extern tree convert_and_check (tree, tree);
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 29121b5d474..ebbf7d91c67 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 b02c515327c..316698468c1 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/c/ChangeLog b/gcc/c/ChangeLog
index dfe76e63fda..89d89f7aca2 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * c-parser.c (struct c_tree_loc_pair): Removed.
+ (c_parser_expr_list): Remove struct c_tree_loc_pair * argument,
+ add location_t * and tree * arguments, fill in array of 3
+ sizeof_arg trees and corresponding locs.
+ (c_parser_attributes, c_parser_objc_keywordexpr): Adjust
+ c_parser_expr_list callers.
+ (c_parser_postfix_expression_after_primary): Likewise. Pass
+ array of 3 sizeof_arg trees and locs (corresponding to first
+ 3 arguments) to sizeof_pointer_memaccess_warning.
+
2012-10-09 Lawrence Crowl <crowl@google.com>
* Make-lang.in (c-decl.o): Add dependence on hash-table.h.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index bea9791925c..bfa98afef01 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1111,12 +1111,6 @@ enum c_parser_prec {
NUM_PRECS
};
-/* Expression and its location. */
-struct c_tree_loc_pair {
- tree expr;
- location_t loc;
-};
-
static void c_parser_external_declaration (c_parser *);
static void c_parser_asm_definition (c_parser *);
static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
@@ -1185,8 +1179,8 @@ static tree c_parser_transaction_cancel (c_parser *);
static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
- VEC(tree,gc) **,
- struct c_tree_loc_pair *);
+ VEC(tree,gc) **, location_t *,
+ tree *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@@ -3586,7 +3580,7 @@ c_parser_attributes (c_parser *parser)
tree tree_list;
c_parser_consume_token (parser);
expr_list = c_parser_expr_list (parser, false, true,
- NULL, NULL);
+ NULL, NULL, NULL);
tree_list = build_tree_list_vec (expr_list);
attr_args = tree_cons (NULL_TREE, arg1, tree_list);
release_tree_vector (expr_list);
@@ -3599,7 +3593,7 @@ c_parser_attributes (c_parser *parser)
else
{
expr_list = c_parser_expr_list (parser, false, true,
- NULL, NULL);
+ NULL, NULL, NULL);
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
}
@@ -6875,7 +6869,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
{
struct c_expr orig_expr;
tree ident, idx;
- struct c_tree_loc_pair sizeof_arg;
+ location_t sizeof_arg_loc[3];
+ tree sizeof_arg[3];
+ unsigned int i;
VEC(tree,gc) *exprlist;
VEC(tree,gc) *origtypes;
while (true)
@@ -6896,21 +6892,24 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_OPEN_PAREN:
/* Function call. */
c_parser_consume_token (parser);
- sizeof_arg.expr = NULL_TREE;
+ for (i = 0; i < 3; i++)
+ {
+ sizeof_arg[i] = NULL_TREE;
+ sizeof_arg_loc[i] = UNKNOWN_LOCATION;
+ }
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
exprlist = NULL;
else
exprlist = c_parser_expr_list (parser, true, false, &origtypes,
- &sizeof_arg);
+ sizeof_arg_loc, sizeof_arg);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
mark_exp_read (expr.value);
- if (warn_sizeof_pointer_memaccess
- && sizeof_arg.expr != NULL_TREE)
- sizeof_pointer_memaccess_warning (sizeof_arg.loc,
+ if (warn_sizeof_pointer_memaccess)
+ sizeof_pointer_memaccess_warning (sizeof_arg_loc,
expr.value, exprlist,
- sizeof_arg.expr,
+ sizeof_arg,
sizeof_ptr_memacc_comptypes);
/* FIXME diagnostics: Ideally we want the FUNCNAME, not the
"(" after the FUNCNAME, which is what we have now. */
@@ -7072,14 +7071,15 @@ c_parser_expression_conv (c_parser *parser)
static VEC(tree,gc) *
c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
- VEC(tree,gc) **p_orig_types,
- struct c_tree_loc_pair *sizeof_arg)
+ VEC(tree,gc) **p_orig_types, location_t *sizeof_arg_loc,
+ tree *sizeof_arg)
{
VEC(tree,gc) *ret;
VEC(tree,gc) *orig_types;
struct c_expr expr;
location_t loc = c_parser_peek_token (parser)->location;
- location_t sizeof_arg_loc = UNKNOWN_LOCATION;
+ location_t cur_sizeof_arg_loc = UNKNOWN_LOCATION;
+ unsigned int idx = 0;
ret = make_tree_vector ();
if (p_orig_types == NULL)
@@ -7089,7 +7089,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
if (sizeof_arg != NULL
&& c_parser_next_token_is_keyword (parser, RID_SIZEOF))
- sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
+ cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_read_conversion (loc, expr);
@@ -7098,15 +7098,22 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC_quick_push (tree, ret, expr.value);
if (orig_types != NULL)
VEC_quick_push (tree, orig_types, expr.original_type);
+ if (sizeof_arg != NULL
+ && cur_sizeof_arg_loc != UNKNOWN_LOCATION
+ && expr.original_code == SIZEOF_EXPR)
+ {
+ sizeof_arg[0] = c_last_sizeof_arg;
+ sizeof_arg_loc[0] = cur_sizeof_arg_loc;
+ }
while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
loc = c_parser_peek_token (parser)->location;
if (sizeof_arg != NULL
&& c_parser_next_token_is_keyword (parser, RID_SIZEOF))
- sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
+ cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
else
- sizeof_arg_loc = UNKNOWN_LOCATION;
+ cur_sizeof_arg_loc = UNKNOWN_LOCATION;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_read_conversion (loc, expr);
@@ -7115,19 +7122,13 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC_safe_push (tree, gc, ret, expr.value);
if (orig_types != NULL)
VEC_safe_push (tree, gc, orig_types, expr.original_type);
- }
- if (sizeof_arg != NULL)
- {
- if (sizeof_arg_loc != UNKNOWN_LOCATION
+ if (++idx < 3
+ && sizeof_arg != NULL
+ && cur_sizeof_arg_loc != UNKNOWN_LOCATION
&& expr.original_code == SIZEOF_EXPR)
{
- sizeof_arg->expr = c_last_sizeof_arg;
- sizeof_arg->loc = sizeof_arg_loc;
- }
- else
- {
- sizeof_arg->expr = NULL_TREE;
- sizeof_arg->loc = UNKNOWN_LOCATION;
+ sizeof_arg[idx] = c_last_sizeof_arg;
+ sizeof_arg_loc[idx] = cur_sizeof_arg_loc;
}
}
if (orig_types != NULL)
@@ -8209,7 +8210,7 @@ c_parser_objc_keywordexpr (c_parser *parser)
{
tree ret;
VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true,
- NULL, NULL);
+ NULL, NULL, NULL);
if (VEC_length (tree, expr_list) == 1)
{
/* Just return the expression, remove a level of
diff --git a/gcc/calls.c b/gcc/calls.c
index 2180a622002..d4ef639dc10 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 07ef949d20e..6e5c6ef75a7 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 ebd50c62735..987e9d99be1 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -636,6 +636,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 80af7d8dbc4..a48550445a3 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -254,7 +254,8 @@ extern basic_block *get_loop_body_in_custom_order (const struct loop *,
int (*) (const void *, const void *));
extern VEC (edge, heap) *get_loop_exit_edges (const struct loop *);
-edge single_exit (const struct loop *);
+extern edge single_exit (const struct loop *);
+extern edge single_likely_exit (struct loop *loop);
extern unsigned num_loop_branches (const struct loop *);
extern edge loop_preheader_edge (const struct loop *);
@@ -309,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,
@@ -319,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/cfgloopanal.c b/gcc/cfgloopanal.c
index cec33fbb97e..c3cf3edf9b9 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -446,3 +446,40 @@ mark_loop_exit_edges (void)
}
}
+/* Return exit edge if loop has only one exit that is likely
+ to be executed on runtime (i.e. it is not EH or leading
+ to noreturn call. */
+
+edge
+single_likely_exit (struct loop *loop)
+{
+ edge found = single_exit (loop);
+ VEC (edge, heap) *exits;
+ unsigned i;
+ edge ex;
+
+ if (found)
+ return found;
+ exits = get_loop_exit_edges (loop);
+ FOR_EACH_VEC_ELT (edge, exits, i, ex)
+ {
+ if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
+ continue;
+ /* The constant of 5 is set in a way so noreturn calls are
+ ruled out by this test. The static branch prediction algorithm
+ will not assign such a low probability to conditionals for usual
+ reasons. */
+ if (profile_status != PROFILE_ABSENT
+ && ex->probability < 5 && !ex->count)
+ continue;
+ if (!found)
+ found = ex;
+ else
+ {
+ VEC_free (edge, heap, exits);
+ return NULL;
+ }
+ }
+ VEC_free (edge, heap, exits);
+ return found;
+}
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 8a44a0b6f93..97a90bbff1d 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 1b578d7feeb..b58562fcc5f 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 c13d00408ad..bf06d4c118f 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 5f8005eb826..eca0740a703 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
@@ -1396,6 +1396,11 @@ Enum(ira_region) String(all) Value(IRA_REGION_ALL)
EnumValue
Enum(ira_region) String(mixed) Value(IRA_REGION_MIXED)
+fira-hoist-pressure
+Common Report Var(flag_ira_hoist_pressure) Init(1) Optimization
+Use IRA based register pressure calculation
+in RTL hoist optimizations.
+
fira-loop-pressure
Common Report Var(flag_ira_loop_pressure)
Use IRA based register pressure calculation
diff --git a/gcc/common/config/rs6000/rs6000-common.c b/gcc/common/config/rs6000/rs6000-common.c
index c903ba3983d..c1764bc93ac 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 ed7474ad68c..38041e63755 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -270,7 +270,6 @@ case ${target} in
| arm*-*-elf \
| arm*-*-freebsd* \
| arm*-*-linux* \
- | arm*-*-rtems* \
| arm*-*-uclinux* \
| i[34567]86-go32-* \
| i[34567]86-*-go32* \
@@ -829,7 +828,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*)
@@ -863,7 +862,7 @@ arm*-*-uclinux*eabi*) # ARM ucLinux
# The EABI requires the use of __cxa_atexit.
default_use_cxa_atexit=yes
;;
-arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtemseabi*)
+arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
# The BPABI long long divmod functions return a 128-bit value in
# registers r0-r3. Correctly modeling that requires the use of
# TImode.
@@ -877,7 +876,7 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtemseabi*)
tmake_file="${tmake_file} arm/t-bpabi"
use_gcc_stdint=wrap
;;
- arm*-*-rtemseabi*)
+ arm*-*-rtems*)
tm_file="${tm_file} rtems.h arm/rtems-eabi.h newlib-stdint.h"
tmake_file="${tmake_file} arm/t-bpabi t-rtems arm/t-rtems-eabi"
;;
@@ -3040,7 +3039,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
;;
@@ -3066,7 +3065,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/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d726b5acca7..82135ffda3d 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -963,7 +963,7 @@ alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
scratch = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointerdi (tp));
emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
emit_insn (gen_adddi3 (dest, tp, scratch));
return dest;
@@ -973,7 +973,7 @@ alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
eqv = gen_rtx_CONST (Pmode, eqv);
tp = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointerdi (tp));
if (alpha_tls_size == 32)
{
insn = gen_rtx_HIGH (Pmode, eqv);
@@ -6328,8 +6328,6 @@ enum alpha_builtin
ALPHA_BUILTIN_AMASK,
ALPHA_BUILTIN_IMPLVER,
ALPHA_BUILTIN_RPCC,
- ALPHA_BUILTIN_THREAD_POINTER,
- ALPHA_BUILTIN_SET_THREAD_POINTER,
ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
@@ -6385,8 +6383,6 @@ static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
CODE_FOR_builtin_amask,
CODE_FOR_builtin_implver,
CODE_FOR_builtin_rpcc,
- CODE_FOR_load_tp,
- CODE_FOR_set_tp,
CODE_FOR_builtin_establish_vms_condition_handler,
CODE_FOR_builtin_revert_vms_condition_handler,
@@ -6544,14 +6540,6 @@ alpha_init_builtins (void)
alpha_dimode_u, NULL_TREE);
alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype);
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- alpha_builtin_function ("__builtin_thread_pointer", ftype,
- ALPHA_BUILTIN_THREAD_POINTER, ECF_NOTHROW);
-
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- alpha_builtin_function ("__builtin_set_thread_pointer", ftype,
- ALPHA_BUILTIN_SET_THREAD_POINTER, ECF_NOTHROW);
-
if (TARGET_ABI_OPEN_VMS)
{
ftype = build_function_type_list (ptr_type_node, ptr_type_node,
@@ -7088,8 +7076,6 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
case ALPHA_BUILTIN_AMASK:
case ALPHA_BUILTIN_IMPLVER:
case ALPHA_BUILTIN_RPCC:
- case ALPHA_BUILTIN_THREAD_POINTER:
- case ALPHA_BUILTIN_SET_THREAD_POINTER:
/* None of these are foldable at compile-time. */
default:
return NULL;
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 21c4d2e0554..1aa8a6714ae 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -90,9 +90,23 @@
(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
;; Other mode iterators
+(define_mode_iterator IMODE [QI HI SI DI])
(define_mode_iterator I12MODE [QI HI])
+(define_mode_iterator I124MODE [QI HI SI])
+(define_mode_iterator I24MODE [HI SI])
+(define_mode_iterator I248MODE [HI SI DI])
(define_mode_iterator I48MODE [SI DI])
-(define_mode_attr modesuffix [(SI "l") (DI "q")])
+
+(define_mode_attr DWI [(SI "DI") (DI "TI")])
+(define_mode_attr modesuffix [(QI "b") (HI "w") (SI "l") (DI "q")
+ (V8QI "b8") (V4HI "w4")
+ (SF "%,") (DF "%-")])
+(define_mode_attr vecmodesuffix [(QI "b8") (HI "w4")])
+
+(define_code_iterator any_maxmin [smax smin umax umin])
+
+(define_code_attr maxmin [(smax "maxs") (smin "mins")
+ (umax "maxu") (umin "minu")])
;; Where necessary, the suffixes _le and _be are used to distinguish between
;; little-endian and big-endian patterns.
@@ -220,10 +234,8 @@
;; code for that case. But we don't reject the possibility.
(define_expand "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
- ""
- "")
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
(define_insn "*cvtlq"
[(set (match_operand:DI 0 "register_operand" "=f")
@@ -246,8 +258,8 @@
(set_attr "length" "*,*,8")])
(define_split
- [(set (match_operand:DI 0 "hard_fp_register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
+ [(set (match_operand:DI 0 "hard_fp_register_operand")
+ (sign_extend:DI (match_operand:SI 1 "memory_operand")))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
@@ -260,15 +272,14 @@
;; reload when converting fp->int.
(define_peephole2
- [(set (match_operand:SI 0 "hard_int_register_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
+ [(set (match_operand:SI 0 "hard_int_register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_operand:DI 2 "hard_int_register_operand")
(sign_extend:DI (match_dup 0)))]
"true_regnum (operands[0]) == true_regnum (operands[2])
|| peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
+ (sign_extend:DI (match_dup 1)))])
(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -282,9 +293,9 @@
ldah %0,%h2(%r1)")
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"! add_operand (operands[2], SImode)"
[(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
@@ -319,11 +330,11 @@
subl %r1,%n2,%0")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
- (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
- (match_operand:SI 2 "const_int_operand" ""))))
- (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
+ (plus:SI (match_operand:SI 1 "reg_not_elim_operand")
+ (match_operand:SI 2 "const_int_operand"))))
+ (clobber (match_operand:SI 3 "reg_not_elim_operand"))]
"! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
&& INTVAL (operands[2]) % 4 == 0"
[(set (match_dup 3) (match_dup 4))
@@ -342,13 +353,13 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
(plus:SI (match_operator:SI 1 "comparison_operator"
- [(match_operand 2 "" "")
- (match_operand 3 "" "")])
- (match_operand:SI 4 "add_operand" ""))))
- (clobber (match_operand:DI 5 "register_operand" ""))]
+ [(match_operand 2)
+ (match_operand 3)])
+ (match_operand:SI 4 "add_operand"))))
+ (clobber (match_operand:DI 5 "register_operand"))]
""
[(set (match_dup 5) (match_dup 6))
(set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
@@ -358,80 +369,64 @@
operands[7] = gen_lowpart (SImode, operands[5]);
})
-(define_insn "addvsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
- (match_operand:SI 2 "sext_add_operand" "rI,O")))
- (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2)))
- (sign_extend:DI (plus:SI (match_dup 1)
- (match_dup 2))))
- (const_int 0))]
- ""
- "@
- addlv %r1,%2,%0
- sublv %r1,%n2,%0")
-
(define_expand "adddi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "add_operand" "")))]
- ""
- "")
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "add_operand")))])
(define_insn "*adddi_er_lo16_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "dtp16_symbolic_operand" "")))]
+ (match_operand:DI 2 "dtp16_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!dtprel")
(define_insn "*adddi_er_hi32_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
- (high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
+ (high:DI (match_operand:DI 2 "dtp32_symbolic_operand"))))]
"HAVE_AS_TLS"
"ldah %0,%2(%1)\t\t!dtprelhi")
(define_insn "*adddi_er_lo32_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "dtp32_symbolic_operand" "")))]
+ (match_operand:DI 2 "dtp32_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!dtprello")
(define_insn "*adddi_er_lo16_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "tp16_symbolic_operand" "")))]
+ (match_operand:DI 2 "tp16_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!tprel")
(define_insn "*adddi_er_hi32_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
- (high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
+ (high:DI (match_operand:DI 2 "tp32_symbolic_operand"))))]
"HAVE_AS_TLS"
"ldah %0,%2(%1)\t\t!tprelhi")
(define_insn "*adddi_er_lo32_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "tp32_symbolic_operand" "")))]
+ (match_operand:DI 2 "tp32_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!tprello")
(define_insn "*adddi_er_high_l"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
- (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
+ (high:DI (match_operand:DI 2 "local_symbolic_operand"))))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
"ldah %0,%2(%1)\t\t!gprelhigh"
[(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (high:DI (match_operand:DI 1 "local_symbolic_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (high:DI (match_operand:DI 1 "local_symbolic_operand")))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(plus:DI (match_dup 2) (high:DI (match_dup 1))))]
@@ -493,9 +488,9 @@
;; Don't do this if we are adjusting SP since we don't want to do it
;; in two steps. Don't split FP sources for the reason listed above.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "const_int_operand")))]
"! add_operand (operands[2], DImode)
&& operands[0] != stack_pointer_rtx
&& operands[1] != frame_pointer_rtx
@@ -522,15 +517,16 @@
FAIL;
})
-(define_insn "*saddl"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
- (match_operand:SI 2 "const48_operand" "I,I"))
- (match_operand:SI 3 "sext_add_operand" "rI,O")))]
+(define_insn "*sadd<modesuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (plus:I48MODE
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r")
+ (match_operand:I48MODE 2 "const48_operand" "I,I"))
+ (match_operand:I48MODE 3 "sext_add_operand" "rI,O")))]
""
"@
- s%2addl %1,%3,%0
- s%2subl %1,%n3,%0")
+ s%2add<modesuffix> %1,%3,%0
+ s%2sub<modesuffix> %1,%n3,%0")
(define_insn "*saddl_se"
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -544,14 +540,14 @@
s%2subl %1,%n3,%0")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
(plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
- [(match_operand 2 "" "")
- (match_operand 3 "" "")])
- (match_operand:SI 4 "const48_operand" ""))
- (match_operand:SI 5 "sext_add_operand" ""))))
- (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
+ [(match_operand 2)
+ (match_operand 3)])
+ (match_operand:SI 4 "const48_operand"))
+ (match_operand:SI 5 "sext_add_operand"))))
+ (clobber (match_operand:DI 6 "reg_not_elim_operand"))]
""
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
@@ -563,35 +559,25 @@
operands[8] = gen_lowpart (SImode, operands[6]);
})
-(define_insn "*saddq"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
- (match_operand:DI 2 "const48_operand" "I,I"))
- (match_operand:DI 3 "sext_add_operand" "rI,O")))]
- ""
- "@
- s%2addq %1,%3,%0
- s%2subq %1,%n3,%0")
-
-(define_insn "addvdi3"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
- (match_operand:DI 2 "sext_add_operand" "rI,O")))
- (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
- (sign_extend:TI (match_dup 2)))
- (sign_extend:TI (plus:DI (match_dup 1)
- (match_dup 2))))
+(define_insn "addv<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:I48MODE 2 "sext_add_operand" "rI,O")))
+ (trap_if (ne (plus:<DWI> (sign_extend:<DWI> (match_dup 1))
+ (sign_extend:<DWI> (match_dup 2)))
+ (sign_extend:<DWI> (plus:I48MODE (match_dup 1)
+ (match_dup 2))))
(const_int 0))]
""
"@
- addqv %r1,%2,%0
- subqv %r1,%n2,%0")
+ add<modesuffix>v %r1,%2,%0
+ sub<modesuffix>v %r1,%n2,%0")
-(define_insn "negsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
+(define_insn "neg<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (neg:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")))]
""
- "subl $31,%1,%0")
+ "sub<modesuffix> $31,%1,%0")
(define_insn "*negsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -600,41 +586,27 @@
""
"subl $31,%1,%0")
-(define_insn "negvsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "register_operand" "r")))
- (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
- (sign_extend:DI (neg:SI (match_dup 1))))
+(define_insn "negv<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (neg:I48MODE (match_operand:I48MODE 1 "register_operand" "r")))
+ (trap_if (ne (neg:<DWI> (sign_extend:<DWI> (match_dup 1)))
+ (sign_extend:<DWI> (neg:I48MODE (match_dup 1))))
(const_int 0))]
""
- "sublv $31,%1,%0")
+ "sub<modesuffix>v $31,%1,%0")
-(define_insn "negdi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
+(define_insn "sub<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
""
- "subq $31,%1,%0")
-
-(define_insn "negvdi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "register_operand" "r")))
- (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
- (sign_extend:TI (neg:DI (match_dup 1))))
- (const_int 0))]
- ""
- "subqv $31,%1,%0")
-
-(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
- ""
- "subl %r1,%2,%0")
+ "sub<modesuffix> %r1,%2,%0")
(define_insn "*subsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
+ (sign_extend:DI
+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+ (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
""
"subl %r1,%2,%0")
@@ -647,32 +619,14 @@
""
"subl %r1,%2,%0")
-(define_insn "subvsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2)))
- (sign_extend:DI (minus:SI (match_dup 1)
- (match_dup 2))))
- (const_int 0))]
- ""
- "sublv %r1,%2,%0")
-
-(define_insn "subdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
+(define_insn "*ssub<modesuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r")
+ (match_operand:I48MODE 2 "const48_operand" "I"))
+ (match_operand:I48MODE 3 "reg_or_8bit_operand" "rI")))]
""
- "subq %r1,%2,%0")
-
-(define_insn "*ssubl"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
- (match_operand:SI 2 "const48_operand" "I"))
- (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
- ""
- "s%2subl %1,%3,%0")
+ "s%2sub<modesuffix> %1,%3,%0")
(define_insn "*ssubl_se"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -683,34 +637,26 @@
""
"s%2subl %1,%3,%0")
-(define_insn "*ssubq"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
- (match_operand:DI 2 "const48_operand" "I"))
- (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
- ""
- "s%2subq %1,%3,%0")
-
-(define_insn "subvdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
- (sign_extend:TI (match_dup 2)))
- (sign_extend:TI (minus:DI (match_dup 1)
- (match_dup 2))))
+(define_insn "subv<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (minus:<DWI> (sign_extend:<DWI> (match_dup 1))
+ (sign_extend:<DWI> (match_dup 2)))
+ (sign_extend:<DWI> (minus:I48MODE (match_dup 1)
+ (match_dup 2))))
(const_int 0))]
""
- "subqv %r1,%2,%0")
+ "sub<modesuffix>v %r1,%2,%0")
-(define_insn "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
+(define_insn "mul<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
""
- "mull %r1,%2,%0"
+ "mul<modesuffix> %r1,%2,%0"
[(set_attr "type" "imul")
- (set_attr "opsize" "si")])
+ (set_attr "opsize" "<mode>")])
(define_insn "*mulsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -722,48 +668,27 @@
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
-(define_insn "mulvsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2)))
- (sign_extend:DI (mult:SI (match_dup 1)
- (match_dup 2))))
+(define_insn "mulv<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (mult:<DWI> (sign_extend:<DWI> (match_dup 1))
+ (sign_extend:<DWI> (match_dup 2)))
+ (sign_extend:<DWI> (mult:I48MODE (match_dup 1)
+ (match_dup 2))))
(const_int 0))]
""
- "mullv %r1,%2,%0"
+ "mul<modesuffix>v %r1,%2,%0"
[(set_attr "type" "imul")
- (set_attr "opsize" "si")])
-
-(define_insn "muldi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
- ""
- "mulq %r1,%2,%0"
- [(set_attr "type" "imul")])
-
-(define_insn "mulvdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
- (sign_extend:TI (match_dup 2)))
- (sign_extend:TI (mult:DI (match_dup 1)
- (match_dup 2))))
- (const_int 0))]
- ""
- "mulqv %r1,%2,%0"
- [(set_attr "type" "imul")])
+ (set_attr "opsize" "<mode>")])
(define_expand "umuldi3_highpart"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(truncate:DI
(lshiftrt:TI
(mult:TI (zero_extend:TI
- (match_operand:DI 1 "register_operand" ""))
- (match_operand:DI 2 "reg_or_8bit_operand" ""))
+ (match_operand:DI 1 "register_operand"))
+ (match_operand:DI 2 "reg_or_8bit_operand"))
(const_int 64))))]
""
{
@@ -806,34 +731,19 @@
;; problem. Is it worth the complication here to eliminate the sign
;; extension?
-(define_expand "divsi3"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (match_dup 5)
- (sign_extend:DI (div:SI (match_dup 3) (match_dup 4))))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
- (subreg:SI (match_dup 5) 0))]
- "TARGET_ABI_OSF"
-{
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
-})
+(define_code_iterator any_divmod [div mod udiv umod])
-(define_expand "udivsi3"
+(define_expand "<code>si3"
[(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))
(set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand")))
(parallel [(set (match_dup 5)
- (sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4))))
+ (sign_extend:DI
+ (any_divmod:SI (match_dup 3) (match_dup 4))))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
+ (set (match_operand:SI 0 "nonimmediate_operand")
(subreg:SI (match_dup 5) 0))]
"TARGET_ABI_OSF"
{
@@ -842,77 +752,14 @@
operands[5] = gen_reg_rtx (DImode);
})
-(define_expand "modsi3"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (match_dup 5)
- (sign_extend:DI (mod:SI (match_dup 3) (match_dup 4))))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
- (subreg:SI (match_dup 5) 0))]
- "TARGET_ABI_OSF"
-{
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
-})
-
-(define_expand "umodsi3"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (match_dup 5)
- (sign_extend:DI (umod:SI (match_dup 3) (match_dup 4))))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
- (subreg:SI (match_dup 5) 0))]
- "TARGET_ABI_OSF"
-{
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
-})
-
-(define_expand "divdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (div:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
+(define_expand "<code>di3"
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (any_divmod:DI
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
-
-(define_expand "udivdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (udiv:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
-
-(define_expand "moddi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (mod:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
-
-(define_expand "umoddi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (umod:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
+ "TARGET_ABI_OSF")
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
;; expanded by the assembler.
@@ -966,7 +813,7 @@
[(match_operand:DI 1 "register_operand" "a")
(match_operand:DI 2 "register_operand" "b")])))
(use (match_operand:DI 4 "register_operand" "c"))
- (use (match_operand 5 "const_int_operand" ""))
+ (use (match_operand 5 "const_int_operand"))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -1034,7 +881,7 @@
[(match_operand:DI 1 "register_operand" "a")
(match_operand:DI 2 "register_operand" "b")]))
(use (match_operand:DI 4 "register_operand" "c"))
- (use (match_operand 5 "const_int_operand" ""))
+ (use (match_operand 5 "const_int_operand"))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -1087,9 +934,9 @@
;; too messy otherwise.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (and:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (and:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "const_int_operand")))]
"HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
[(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
@@ -1110,31 +957,9 @@
operands[4] = GEN_INT (mask2);
})
-(define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (zero_extend:HI
- (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
- ""
- "@
- and %1,0xff,%0
- ldbu %0,%1"
- [(set_attr "type" "ilog,ild")
- (set_attr "isa" "*,bwx")])
-
-(define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
- ""
- "@
- and %1,0xff,%0
- ldbu %0,%1"
- [(set_attr "type" "ilog,ild")
- (set_attr "isa" "*,bwx")])
-
-(define_insn "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
+(define_insn "zero_extendqi<mode>2"
+ [(set (match_operand:I248MODE 0 "register_operand" "=r,r")
+ (zero_extend:I248MODE
(match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
""
"@
@@ -1143,20 +968,9 @@
[(set_attr "type" "ilog,ild")
(set_attr "isa" "*,bwx")])
-(define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
- ""
- "@
- zapnot %1,3,%0
- ldwu %0,%1"
- [(set_attr "type" "shift,ild")
- (set_attr "isa" "*,bwx")])
-
-(define_insn "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
+(define_insn "zero_extendhi<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (zero_extend:I48MODE
(match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
""
"@
@@ -1172,18 +986,11 @@
"zapnot %1,15,%0"
[(set_attr "type" "shift")])
-(define_insn "*andnotsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
- ""
- "bic %r2,%1,%0"
- [(set_attr "type" "ilog")])
-
-(define_insn "andnotdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
+(define_insn "andnot<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (and:I48MODE
+ (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
""
"bic %r2,%1,%0"
[(set_attr "type" "ilog")])
@@ -1222,18 +1029,11 @@
"ornot $31,%1,%0"
[(set_attr "type" "ilog")])
-(define_insn "*iornotsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
- ""
- "ornot %r2,%1,%0"
- [(set_attr "type" "ilog")])
-
-(define_insn "*iornotdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
+(define_insn "*iornot<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (ior:I48MODE
+ (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
""
"ornot %r2,%1,%0"
[(set_attr "type" "ilog")])
@@ -1258,18 +1058,11 @@
eqv %r1,%N2,%0"
[(set_attr "type" "ilog")])
-(define_insn "*xornotsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
- (match_operand:SI 2 "register_operand" "rI"))))]
- ""
- "eqv %r1,%2,%0"
- [(set_attr "type" "ilog")])
-
-(define_insn "*xornotdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
- (match_operand:DI 2 "register_operand" "rI"))))]
+(define_insn "*xornot<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (not:I48MODE (xor:I48MODE
+ (match_operand:I48MODE 1 "register_operand" "%rJ")
+ (match_operand:I48MODE 2 "register_operand" "rI"))))]
""
"eqv %r1,%2,%0"
[(set_attr "type" "ilog")])
@@ -1278,10 +1071,10 @@
(define_expand "ffsdi2"
[(set (match_dup 2)
- (ctz:DI (match_operand:DI 1 "register_operand" "")))
+ (ctz:DI (match_operand:DI 1 "register_operand")))
(set (match_dup 3)
(plus:DI (match_dup 2) (const_int 1)))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (eq (match_dup 1) (const_int 0))
(const_int 0) (match_dup 3)))]
"TARGET_CIX"
@@ -1312,8 +1105,8 @@
[(set_attr "type" "mvi")])
(define_expand "bswapsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (bswap:SI (match_operand:SI 1 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (bswap:SI (match_operand:SI 1 "register_operand")))]
"!optimize_size"
{
rtx t0, t1;
@@ -1334,8 +1127,8 @@
})
(define_expand "bswapdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (bswap:DI (match_operand:DI 1 "register_operand")))]
"!optimize_size"
{
rtx t0, t1;
@@ -1418,23 +1211,17 @@
"sra %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- "TARGET_BWX"
- "sextb %1,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
+(define_insn "extendqi<mode>2"
+ [(set (match_operand:I24MODE 0 "register_operand" "=r")
+ (sign_extend:I24MODE
+ (match_operand:QI 1 "register_operand" "r")))]
"TARGET_BWX"
"sextb %1,%0"
[(set_attr "type" "shift")])
(define_expand "extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:QI 1 "some_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:QI 1 "some_operand")))]
""
{
if (TARGET_BWX)
@@ -1478,8 +1265,8 @@
[(set_attr "type" "shift")])
(define_expand "extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:HI 1 "some_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:HI 1 "some_operand")))]
""
{
if (TARGET_BWX)
@@ -1523,14 +1310,14 @@
(define_expand "unaligned_extendqidi"
[(set (match_dup 3)
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") (const_int -8))))
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (match_operand:QI 0 "register_operand" "")
+ (set (match_operand:QI 0 "register_operand")
(ashiftrt:DI (match_dup 4) (const_int 56)))]
""
{
@@ -1542,14 +1329,14 @@
(define_expand "unaligned_extendhidi"
[(set (match_dup 3)
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") (const_int -8))))
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (match_operand:HI 0 "register_operand" "")
+ (set (match_operand:HI 0 "register_operand")
(ashiftrt:DI (match_dup 4) (const_int 48)))]
""
{
@@ -1570,10 +1357,11 @@
(define_insn "extxl"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "mode_width_operand" "n")
- (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
- (const_int 3))))]
+ (zero_extract:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (match_operand:DI 2 "mode_width_operand" "n")
+ (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
+ (const_int 3))))]
""
"ext%M2l %r1,%3,%0"
[(set_attr "type" "shift")])
@@ -1615,11 +1403,11 @@
"extqh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extlh"
+(define_insn "extwh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (const_int 2147483647))
+ (const_int 65535))
(minus:DI (const_int 64)
(ashift:DI
(and:DI
@@ -1627,14 +1415,14 @@
(const_int 7))
(const_int 3)))))]
""
- "extlh %r1,%2,%0"
+ "extwh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extwh"
+(define_insn "extlh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (const_int 65535))
+ (const_int 2147483647))
(minus:DI (const_int 64)
(ashift:DI
(and:DI
@@ -1642,20 +1430,20 @@
(const_int 7))
(const_int 3)))))]
""
- "extwh %r1,%2,%0"
+ "extlh %r1,%2,%0"
[(set_attr "type" "shift")])
;; This converts an extXl into an extXh with an appropriate adjustment
;; to the address calculation.
;;(define_split
-;; [(set (match_operand:DI 0 "register_operand" "")
-;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
-;; (match_operand:DI 2 "mode_width_operand" "")
-;; (ashift:DI (match_operand:DI 3 "" "")
+;; [(set (match_operand:DI 0 "register_operand")
+;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand")
+;; (match_operand:DI 2 "mode_width_operand")
+;; (ashift:DI (match_operand:DI 3)
;; (const_int 3)))
-;; (match_operand:DI 4 "const_int_operand" "")))
-;; (clobber (match_operand:DI 5 "register_operand" ""))]
+;; (match_operand:DI 4 "const_int_operand")))
+;; (clobber (match_operand:DI 5 "register_operand"))]
;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
;; [(set (match_dup 5) (match_dup 6))
;; (set (match_dup 0)
@@ -1671,55 +1459,23 @@
;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
;;}")
-(define_insn "*insbl_const"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
- (match_operand:DI 2 "mul8_operand" "I")))]
- ""
- "insbl %1,%s2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "inswl_const"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
- (match_operand:DI 2 "mul8_operand" "I")))]
- ""
- "inswl %1,%s2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "*insll_const"
+(define_insn "ins<modesuffix>l_const"
[(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (ashift:DI (zero_extend:DI
+ (match_operand:I124MODE 1 "register_operand" "r"))
(match_operand:DI 2 "mul8_operand" "I")))]
""
- "insll %1,%s2,%0"
+ "ins<modesuffix>l %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn "insbl"
+(define_insn "ins<modesuffix>l"
[(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
+ (ashift:DI (zero_extend:DI
+ (match_operand:I124MODE 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
- "insbl %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "inswl"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3))))]
- ""
- "inswl %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "insll"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3))))]
- ""
- "insll %1,%2,%0"
+ "ins<modesuffix>l %1,%2,%0"
[(set_attr "type" "shift")])
(define_insn "insql"
@@ -1825,37 +1581,28 @@
;; from single, so indicate that. The exception are the ones that simply
;; play with the sign bits; it's not clear what to do there.
-(define_insn "abssf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "cpys $f31,%R1,%0"
- [(set_attr "type" "fcpys")])
+(define_mode_iterator FMODE [SF DF])
-(define_insn "*nabssf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
- "TARGET_FP"
- "cpysn $f31,%R1,%0"
- [(set_attr "type" "fadd")])
+(define_mode_attr opmode [(SF "si") (DF "di")])
-(define_insn "absdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+(define_insn "abs<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
"TARGET_FP"
"cpys $f31,%R1,%0"
[(set_attr "type" "fcpys")])
-(define_insn "*nabsdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))]
+(define_insn "*nabs<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (neg:FMODE
+ (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG"))))]
"TARGET_FP"
"cpysn $f31,%R1,%0"
[(set_attr "type" "fadd")])
(define_expand "abstf2"
- [(parallel [(set (match_operand:TF 0 "register_operand" "")
- (abs:TF (match_operand:TF 1 "reg_or_0_operand" "")))
+ [(parallel [(set (match_operand:TF 0 "register_operand")
+ (abs:TF (match_operand:TF 1 "reg_or_0_operand")))
(use (match_dup 2))])]
"TARGET_HAS_XFLOATING_LIBS"
{
@@ -1876,23 +1623,16 @@
[(const_int 0)]
"alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
-(define_insn "negsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "cpysn %R1,%R1,%0"
- [(set_attr "type" "fadd")])
-
-(define_insn "negdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+(define_insn "neg<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (neg:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
"TARGET_FP"
"cpysn %R1,%R1,%0"
[(set_attr "type" "fadd")])
(define_expand "negtf2"
- [(parallel [(set (match_operand:TF 0 "register_operand" "")
- (neg:TF (match_operand:TF 1 "reg_or_0_operand" "")))
+ [(parallel [(set (match_operand:TF 0 "register_operand")
+ (neg:TF (match_operand:TF 1 "reg_or_0_operand")))
(use (match_dup 2))])]
"TARGET_HAS_XFLOATING_LIBS"
{
@@ -1913,117 +1653,287 @@
[(const_int 0)]
"alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
-(define_insn "copysignsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN))]
+(define_insn "copysign<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN))]
"TARGET_FP"
"cpys %R2,%R1,%0"
[(set_attr "type" "fadd")])
-(define_insn "*ncopysignsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN)))]
+(define_insn "*ncopysign<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (neg:FMODE
+ (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN)))]
"TARGET_FP"
"cpysn %R2,%R1,%0"
[(set_attr "type" "fadd")])
-(define_insn "copysigndf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN))]
+(define_insn "*add<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "add<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "add<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
"TARGET_FP"
- "cpys %R2,%R1,%0"
- [(set_attr "type" "fadd")])
+ "add<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*ncopysigndf3"
+(define_insn "*adddf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN)))]
- "TARGET_FP"
- "cpysn %R2,%R1,%0"
- [(set_attr "type" "fadd")])
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (match_operand:DF 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*addsf_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
+(define_insn "*adddf_ext2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "%fG"))
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "addtf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
+
+(define_insn "*sub<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "add%,%/ %R1,%R2,%0"
+ "sub<modesuffix>%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
+(define_insn "sub<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
"TARGET_FP"
- "add%,%/ %R1,%R2,%0"
+ "sub<modesuffix>%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*adddf_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "add%-%/ %R1,%R2,%0"
+(define_insn "*subdf_ext1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (match_operand:DF 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "adddf3"
+(define_insn "*subdf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "add%-%/ %R1,%R2,%0"
+ (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*adddf_ext1"
+(define_insn "*subdf_ext3"
[(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (float_extend:DF
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "subtf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
+
+(define_insn "*mul<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "mul<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP"
+ "mul<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*muldf_ext1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (mult:DF (float_extend:DF
(match_operand:SF 1 "reg_or_0_operand" "fG"))
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "add%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
+ "mul%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*adddf_ext2"
+(define_insn "*muldf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (float_extend:DF
+ (mult:DF (float_extend:DF
(match_operand:SF 1 "reg_or_0_operand" "%fG"))
(float_extend:DF
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "add%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
+ "mul%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_expand "addtf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
+(define_expand "multf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
+ "alpha_emit_xfloating_arith (MULT, operands); DONE;")
+
+(define_insn "*div<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "div<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP"
+ "div<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*divdf_ext1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (match_operand:DF 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*divdf_ext2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*divdf_ext3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (div:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "divtf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (DIV, operands); DONE;")
+
+(define_insn "*sqrt<mode>2_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
+ "sqrt<modesuffix>%/ %R1,%0"
+ [(set_attr "type" "fsqrt")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "sqrt<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && TARGET_FIX"
+ "sqrt<modesuffix>%/ %R1,%0"
+ [(set_attr "type" "fsqrt")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
;; Define conversion operators between DFmode and SImode, using the cvtql
;; instruction. To allow combine et al to do useful things, we keep the
@@ -2105,16 +2015,14 @@
(set_attr "trap_suffix" "v_sv_svi")])
(define_expand "fix_truncdfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
- "TARGET_FP"
- "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
+ (fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
+ "TARGET_FP")
(define_expand "fixuns_truncdfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
- (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
- "TARGET_FP"
- "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
+ (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
+ "TARGET_FP")
;; Likewise between SFmode and SImode.
@@ -2132,9 +2040,7 @@
[(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
(set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
(set (match_dup 5) (match_dup 3))]
-{
- operands[5] = adjust_address (operands[0], SFmode, 0);
-}
+ "operands[5] = adjust_address (operands[0], SFmode, 0);"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
@@ -2181,27 +2087,25 @@
(set_attr "trap_suffix" "v_sv_svi")])
(define_expand "fix_truncsfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
- (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
- "TARGET_FP"
- "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
+ (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
+ "TARGET_FP")
(define_expand "fixuns_truncsfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
(unsigned_fix:DI
- (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
- "TARGET_FP"
- "")
+ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
+ "TARGET_FP")
(define_expand "fix_trunctfdi2"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:DI 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
(define_expand "fixuns_trunctfdi2"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:DI 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
@@ -2236,9 +2140,7 @@
[(set (match_dup 3) (match_dup 1))
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
(set (match_dup 0) (float:SF (match_dup 2)))]
-{
- operands[1] = adjust_address (operands[1], SFmode, 0);
-})
+ "operands[1] = adjust_address (operands[1], SFmode, 0);")
(define_insn_and_split "*floatsisf2"
[(set (match_operand:SF 0 "register_operand" "=f")
@@ -2285,9 +2187,7 @@
[(set (match_dup 3) (match_dup 1))
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
(set (match_dup 0) (float:DF (match_dup 2)))]
-{
- operands[1] = adjust_address (operands[1], SFmode, 0);
-})
+ "operands[1] = adjust_address (operands[1], SFmode, 0);")
(define_insn_and_split "*floatsidf2"
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -2305,32 +2205,32 @@
})
(define_expand "floatditf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DI 1 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:DI 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
(define_expand "floatunsdisf2"
- [(use (match_operand:SF 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))]
+ [(use (match_operand:SF 0 "register_operand"))
+ (use (match_operand:DI 1 "register_operand"))]
"TARGET_FP"
"alpha_emit_floatuns (operands); DONE;")
(define_expand "floatunsdidf2"
- [(use (match_operand:DF 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))]
+ [(use (match_operand:DF 0 "register_operand"))
+ (use (match_operand:DI 1 "register_operand"))]
"TARGET_FP"
"alpha_emit_floatuns (operands); DONE;")
(define_expand "floatunsditf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DI 1 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:DI 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
(define_expand "extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:DF 0 "register_operand")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand")))]
"TARGET_FP"
{
if (alpha_fptm >= ALPHA_FPTM_SU)
@@ -2362,8 +2262,8 @@
;; from doing something silly. When optimizing we'll put things back
;; together anyway.
(define_expand "extendsftf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:SF 1 "register_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:SF 1 "register_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
{
rtx tmp = gen_reg_rtx (DFmode);
@@ -2373,8 +2273,8 @@
})
(define_expand "extenddftf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DF 1 "register_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:DF 1 "register_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
@@ -2399,14 +2299,14 @@
(set_attr "trap_suffix" "u_su_sui")])
(define_expand "trunctfdf2"
- [(use (match_operand:DF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:DF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
(define_expand "trunctfsf2"
- [(use (match_operand:SF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:SF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
{
rtx tmpf, sticky, arg, lo, hi;
@@ -2429,299 +2329,6 @@
emit_insn (gen_truncdfsf2 (operands[0], tmpf));
DONE;
})
-
-(define_insn "*divsf3_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "div%,%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "divsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "div%,%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf3_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "divdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf_ext1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf_ext2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf_ext3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_expand "divtf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
- "TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (DIV, operands); DONE;")
-
-(define_insn "*mulsf3_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "mul%,%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "mul%,%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*muldf3_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "muldf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*muldf_ext1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*muldf_ext2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "%fG"))
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_expand "multf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
- "TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (MULT, operands); DONE;")
-
-(define_insn "*subsf3_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "sub%,%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "sub%,%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf3_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "subdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf_ext1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf_ext2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf_ext3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_expand "subtf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
- "TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
-
-(define_insn "*sqrtsf2_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
- "sqrt%,%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX"
- "sqrt%,%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*sqrtdf2_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
- "sqrt%-%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX"
- "sqrt%-%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
;; Next are all the integer comparisons, and conditional moves and branches
;; and some of the related define_expand's and define_split's.
@@ -2772,14 +2379,14 @@
;; in order to create more pairs of constants. As long as we're allowing
;; two constants at the same time, and will have to reload one of them...
-(define_insn "*movqicc_internal"
- [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
- (if_then_else:QI
+(define_insn "*mov<mode>cc_internal"
+ [(set (match_operand:IMODE 0 "register_operand" "=r,r,r,r")
+ (if_then_else:IMODE
(match_operator 2 "signed_comparison_operator"
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:QI 1 "add_operand" "rI,0,rI,0")
- (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
+ (match_operand:IMODE 1 "add_operand" "rI,0,rI,0")
+ (match_operand:IMODE 5 "add_operand" "0,rI,0,rI")))]
"(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
@@ -2788,168 +2395,30 @@
cmov%d2 %r4,%5,%0"
[(set_attr "type" "icmov")])
-(define_insn "*movhicc_internal"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
- (if_then_else:HI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
- (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:HI 1 "add_operand" "rI,0,rI,0")
- (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
- "@
- cmov%C2 %r3,%1,%0
- cmov%D2 %r3,%5,%0
- cmov%c2 %r4,%1,%0
- cmov%d2 %r4,%5,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movsicc_internal"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (if_then_else:SI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
- (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:SI 1 "add_operand" "rI,0,rI,0")
- (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
- "@
- cmov%C2 %r3,%1,%0
- cmov%D2 %r3,%5,%0
- cmov%c2 %r4,%1,%0
- cmov%d2 %r4,%5,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movdicc_internal"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
- (if_then_else:DI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
- (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:DI 1 "add_operand" "rI,0,rI,0")
- (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
- "@
- cmov%C2 %r3,%1,%0
- cmov%D2 %r3,%5,%0
- cmov%c2 %r4,%1,%0
- cmov%d2 %r4,%5,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movqicc_lbc"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI
- (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbc %r2,%1,%0
- cmovlbs %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movhicc_lbc"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (if_then_else:HI
+(define_insn "*mov<mode>cc_lbc"
+ [(set (match_operand:IMODE 0 "register_operand" "=r,r")
+ (if_then_else:IMODE
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
(const_int 1)
(const_int 0))
(const_int 0))
- (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
+ (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
""
"@
cmovlbc %r2,%1,%0
cmovlbs %r2,%3,%0"
[(set_attr "type" "icmov")])
-(define_insn "*movsicc_lbc"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI
- (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbc %r2,%1,%0
- cmovlbs %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movdicc_lbc"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (if_then_else:DI
- (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbc %r2,%1,%0
- cmovlbs %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movqicc_lbs"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI
- (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbs %r2,%1,%0
- cmovlbc %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movhicc_lbs"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (if_then_else:HI
- (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbs %r2,%1,%0
- cmovlbc %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movsicc_lbs"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI
- (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbs %r2,%1,%0
- cmovlbc %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movdicc_lbs"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (if_then_else:DI
+(define_insn "*mov<mode>cc_lbs"
+ [(set (match_operand:IMODE 0 "register_operand" "=r,r")
+ (if_then_else:IMODE
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
(const_int 1)
(const_int 0))
(const_int 0))
- (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
+ (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
""
"@
cmovlbs %r2,%1,%0
@@ -2959,8 +2428,8 @@
;; For ABS, we have two choices, depending on whether the input and output
;; registers are the same or not.
(define_expand "absdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (abs:DI (match_operand:DI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (abs:DI (match_operand:DI 1 "register_operand")))]
""
{
if (rtx_equal_p (operands[0], operands[1]))
@@ -2971,147 +2440,83 @@
})
(define_expand "absdi2_same"
- [(set (match_operand:DI 1 "register_operand" "")
- (neg:DI (match_operand:DI 0 "register_operand" "")))
+ [(set (match_operand:DI 1 "register_operand")
+ (neg:DI (match_operand:DI 0 "register_operand")))
(set (match_dup 0)
(if_then_else:DI (ge (match_dup 0) (const_int 0))
(match_dup 0)
- (match_dup 1)))]
- ""
- "")
+ (match_dup 1)))])
(define_expand "absdi2_diff"
- [(set (match_operand:DI 0 "register_operand" "")
- (neg:DI (match_operand:DI 1 "register_operand" "")))
+ [(set (match_operand:DI 0 "register_operand")
+ (neg:DI (match_operand:DI 1 "register_operand")))
(set (match_dup 0)
(if_then_else:DI (lt (match_dup 1) (const_int 0))
(match_dup 0)
- (match_dup 1)))]
- ""
- "")
+ (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(abs:DI (match_dup 0)))
- (clobber (match_operand:DI 1 "register_operand" ""))]
+ (clobber (match_operand:DI 1 "register_operand"))]
""
[(set (match_dup 1) (neg:DI (match_dup 0)))
(set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
+ (match_dup 0) (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (abs:DI (match_operand:DI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (abs:DI (match_operand:DI 1 "register_operand")))]
"! rtx_equal_p (operands[0], operands[1])"
[(set (match_dup 0) (neg:DI (match_dup 1)))
(set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
+ (match_dup 0) (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(neg:DI (abs:DI (match_dup 0))))
- (clobber (match_operand:DI 1 "register_operand" ""))]
+ (clobber (match_operand:DI 1 "register_operand"))]
""
[(set (match_dup 1) (neg:DI (match_dup 0)))
(set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
+ (match_dup 0) (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
+ [(set (match_operand:DI 0 "register_operand")
+ (neg:DI (abs:DI (match_operand:DI 1 "register_operand"))))]
"! rtx_equal_p (operands[0], operands[1])"
[(set (match_dup 0) (neg:DI (match_dup 1)))
(set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
-
-(define_insn "sminqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minsb8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "uminqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minub8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "maxsb8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "maxub8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
+ (match_dup 0) (match_dup 1)))])
-(define_insn "sminhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minsw4 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "uminhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minuw4 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "maxsw4 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
+(define_insn "<code><mode>3"
+ [(set (match_operand:I12MODE 0 "register_operand" "=r")
+ (any_maxmin:I12MODE
+ (match_operand:I12MODE 1 "reg_or_0_operand" "%rJ")
+ (match_operand:I12MODE 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
- "maxuw4 %r1,%2,%0"
+ "<maxmin><vecmodesuffix> %r1,%2,%0"
[(set_attr "type" "mvi")])
(define_expand "smaxdi3"
[(set (match_dup 3)
- (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (le:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (eq (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- { operands[3] = gen_reg_rtx (DImode); })
+ "operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (smax:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_insn "*smax_const0"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -3123,24 +2528,23 @@
(define_expand "smindi3"
[(set (match_dup 3)
- (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (lt:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (ne (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- { operands[3] = gen_reg_rtx (DImode); })
+ "operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (smin:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_insn "*smin_const0"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -3152,45 +2556,43 @@
(define_expand "umaxdi3"
[(set (match_dup 3)
- (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (leu:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (eq (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
"operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (umax:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_expand "umindi3"
[(set (match_dup 3)
- (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (ltu:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (ne (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
"operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (umin:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_insn "*bcc_normal"
[(set (pc)
@@ -3198,7 +2600,7 @@
(match_operator 1 "signed_comparison_operator"
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
(const_int 0)])
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
""
"b%C1 %r2,%0"
@@ -3212,7 +2614,7 @@
(const_int 0)])
(pc)
- (label_ref (match_operand 0 "" ""))))]
+ (label_ref (match_operand 0))))]
""
"b%c1 %2,%0"
[(set_attr "type" "ibr")])
@@ -3224,7 +2626,7 @@
(const_int 1)
(const_int 0))
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
""
"blbs %r1,%0"
@@ -3237,7 +2639,7 @@
(const_int 1)
(const_int 0))
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
""
"blbc %r1,%0"
@@ -3248,13 +2650,13 @@
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator"
- [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
- (const_int 1)
- (match_operand:DI 3 "const_int_operand" ""))
- (const_int 0)])
- (label_ref (match_operand 0 "" ""))
+ [(zero_extract:DI (match_operand:DI 2 "register_operand")
+ (const_int 1)
+ (match_operand:DI 3 "const_int_operand"))
+ (const_int 0)])
+ (label_ref (match_operand 0))
(pc)))
- (clobber (match_operand:DI 4 "register_operand" ""))])]
+ (clobber (match_operand:DI 4 "register_operand"))])]
"INTVAL (operands[3]) != 0"
[(set (match_dup 4)
(lshiftrt:DI (match_dup 2) (match_dup 3)))
@@ -3266,7 +2668,7 @@
(const_int 0)])
(label_ref (match_dup 0))
(pc)))]
- "")
+ )
;; The following are the corresponding floating-point insns. Recall
;; we need to have variants that expand the arguments from SFmode
@@ -3331,28 +2733,14 @@
(set_attr "trap" "yes")
(set_attr "trap_suffix" "su")])
-(define_insn "*movdfcc_internal"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (if_then_else:DF
- (match_operator 3 "signed_comparison_operator"
- [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
- (match_operand:DF 2 "const0_operand" "G,G")])
- (match_operand:DF 1 "reg_or_0_operand" "fG,0")
- (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
- "TARGET_FP"
- "@
- fcmov%C3 %R4,%R1,%0
- fcmov%D3 %R4,%R5,%0"
- [(set_attr "type" "fcmov")])
-
-(define_insn "*movsfcc_internal"
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (if_then_else:SF
+(define_insn "*mov<mode>cc_internal"
+ [(set (match_operand:FMODE 0 "register_operand" "=f,f")
+ (if_then_else:FMODE
(match_operator 3 "signed_comparison_operator"
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
(match_operand:DF 2 "const0_operand" "G,G")])
- (match_operand:SF 1 "reg_or_0_operand" "fG,0")
- (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
+ (match_operand:FMODE 1 "reg_or_0_operand" "fG,0")
+ (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))]
"TARGET_FP"
"@
fcmov%C3 %R4,%R1,%0
@@ -3420,9 +2808,9 @@
(define_expand "smaxdf3"
[(set (match_dup 3)
- (le:DF (match_operand:DF 1 "reg_or_0_operand" "")
- (match_operand:DF 2 "reg_or_0_operand" "")))
- (set (match_operand:DF 0 "register_operand" "")
+ (le:DF (match_operand:DF 1 "reg_or_0_operand")
+ (match_operand:DF 2 "reg_or_0_operand")))
+ (set (match_operand:DF 0 "register_operand")
(if_then_else:DF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
@@ -3433,9 +2821,9 @@
(define_expand "smindf3"
[(set (match_dup 3)
- (lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
- (match_operand:DF 2 "reg_or_0_operand" "")))
- (set (match_operand:DF 0 "register_operand" "")
+ (lt:DF (match_operand:DF 1 "reg_or_0_operand")
+ (match_operand:DF 2 "reg_or_0_operand")))
+ (set (match_operand:DF 0 "register_operand")
(if_then_else:DF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
@@ -3446,9 +2834,9 @@
(define_expand "smaxsf3"
[(set (match_dup 3)
- (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
- (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
- (set (match_operand:SF 0 "register_operand" "")
+ (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
+ (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
+ (set (match_operand:SF 0 "register_operand")
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
@@ -3459,9 +2847,9 @@
(define_expand "sminsf3"
[(set (match_dup 3)
- (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
- (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
- (set (match_operand:SF 0 "register_operand" "")
+ (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
+ (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
+ (set (match_operand:SF 0 "register_operand")
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
@@ -3476,7 +2864,7 @@
(match_operator 1 "signed_comparison_operator"
[(match_operand:DF 2 "reg_or_0_operand" "fG")
(match_operand:DF 3 "const0_operand" "G")])
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
"TARGET_FP"
"fb%C1 %R2,%0"
@@ -3489,7 +2877,7 @@
[(float_extend:DF
(match_operand:SF 2 "reg_or_0_operand" "fG"))
(match_operand:DF 3 "const0_operand" "G")])
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
"TARGET_FP"
"fb%C1 %R2,%0"
@@ -3500,27 +2888,27 @@
(define_expand "cbranchdf4"
[(use (match_operator 0 "alpha_cbranch_operator"
- [(match_operand:DF 1 "reg_or_0_operand" "")
- (match_operand:DF 2 "reg_or_0_operand" "")]))
- (use (match_operand 3 ""))]
+ [(match_operand:DF 1 "reg_or_0_operand")
+ (match_operand:DF 2 "reg_or_0_operand")]))
+ (use (match_operand 3))]
"TARGET_FP"
- { alpha_emit_conditional_branch (operands, DFmode); DONE; })
+ "alpha_emit_conditional_branch (operands, DFmode); DONE;")
(define_expand "cbranchtf4"
[(use (match_operator 0 "alpha_cbranch_operator"
[(match_operand:TF 1 "general_operand")
(match_operand:TF 2 "general_operand")]))
- (use (match_operand 3 ""))]
+ (use (match_operand 3))]
"TARGET_HAS_XFLOATING_LIBS"
- { alpha_emit_conditional_branch (operands, TFmode); DONE; })
+ "alpha_emit_conditional_branch (operands, TFmode); DONE;")
(define_expand "cbranchdi4"
[(use (match_operator 0 "alpha_cbranch_operator"
[(match_operand:DI 1 "some_operand")
(match_operand:DI 2 "some_operand")]))
- (use (match_operand 3 ""))]
+ (use (match_operand 3))]
""
- { alpha_emit_conditional_branch (operands, DImode); DONE; })
+ "alpha_emit_conditional_branch (operands, DImode); DONE;")
(define_expand "cstoredf4"
[(use (match_operator:DI 1 "alpha_cbranch_operator"
@@ -3528,7 +2916,12 @@
(match_operand:DF 3 "reg_or_0_operand")]))
(clobber (match_operand:DI 0 "register_operand"))]
"TARGET_FP"
- { if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
+{
+ if (alpha_emit_setcc (operands, DFmode))
+ DONE;
+ else
+ FAIL;
+})
(define_expand "cstoretf4"
[(use (match_operator:DI 1 "alpha_cbranch_operator"
@@ -3536,7 +2929,12 @@
(match_operand:TF 3 "general_operand")]))
(clobber (match_operand:DI 0 "register_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
- { if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
+{
+ if (alpha_emit_setcc (operands, TFmode))
+ DONE;
+ else
+ FAIL;
+})
(define_expand "cstoredi4"
[(use (match_operator:DI 1 "alpha_cbranch_operator"
@@ -3544,51 +2942,38 @@
(match_operand:DI 3 "some_operand")]))
(clobber (match_operand:DI 0 "register_operand"))]
""
- { if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
-
-;; These are the main define_expand's used to make conditional moves.
-
-(define_expand "movsicc"
- [(set (match_operand:SI 0 "register_operand" "")
- (if_then_else:SI (match_operand 1 "comparison_operator" "")
- (match_operand:SI 2 "reg_or_8bit_operand" "")
- (match_operand:SI 3 "reg_or_8bit_operand" "")))]
- ""
-{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
- FAIL;
-})
-
-(define_expand "movdicc"
- [(set (match_operand:DI 0 "register_operand" "")
- (if_then_else:DI (match_operand 1 "comparison_operator" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")
- (match_operand:DI 3 "reg_or_8bit_operand" "")))]
- ""
{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
+ if (alpha_emit_setcc (operands, DImode))
+ DONE;
+ else
FAIL;
})
+
+;; These are the main define_expand's used to make conditional moves.
-(define_expand "movsfcc"
- [(set (match_operand:SF 0 "register_operand" "")
- (if_then_else:SF (match_operand 1 "comparison_operator" "")
- (match_operand:SF 2 "reg_or_8bit_operand" "")
- (match_operand:SF 3 "reg_or_8bit_operand" "")))]
+(define_expand "mov<mode>cc"
+ [(set (match_operand:I48MODE 0 "register_operand")
+ (if_then_else:I48MODE
+ (match_operand 1 "comparison_operator")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand")
+ (match_operand:I48MODE 3 "reg_or_8bit_operand")))]
""
{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
+ operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
+ if (operands[1] == 0)
FAIL;
})
-(define_expand "movdfcc"
- [(set (match_operand:DF 0 "register_operand" "")
- (if_then_else:DF (match_operand 1 "comparison_operator" "")
- (match_operand:DF 2 "reg_or_8bit_operand" "")
- (match_operand:DF 3 "reg_or_8bit_operand" "")))]
+(define_expand "mov<mode>cc"
+ [(set (match_operand:FMODE 0 "register_operand")
+ (if_then_else:FMODE
+ (match_operand 1 "comparison_operator")
+ (match_operand:FMODE 2 "reg_or_8bit_operand")
+ (match_operand:FMODE 3 "reg_or_8bit_operand")))]
""
{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
+ operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
+ if (operands[1] == 0)
FAIL;
})
@@ -3610,14 +2995,14 @@
;; operation could have been generated.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(if_then_else:DI
(match_operator 1 "comparison_operator"
- [(match_operand:DI 2 "reg_or_0_operand" "")
- (match_operand:DI 3 "reg_or_cint_operand" "")])
- (match_operand:DI 4 "reg_or_cint_operand" "")
- (match_operand:DI 5 "reg_or_cint_operand" "")))
- (clobber (match_operand:DI 6 "register_operand" ""))]
+ [(match_operand:DI 2 "reg_or_0_operand")
+ (match_operand:DI 3 "reg_or_cint_operand")])
+ (match_operand:DI 4 "reg_or_cint_operand")
+ (match_operand:DI 5 "reg_or_cint_operand")))
+ (clobber (match_operand:DI 6 "register_operand"))]
"operands[3] != const0_rtx"
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
@@ -3667,14 +3052,14 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(if_then_else:DI
(match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "reg_or_0_operand" "")
- (match_operand:SI 3 "reg_or_cint_operand" "")])
- (match_operand:DI 4 "reg_or_8bit_operand" "")
- (match_operand:DI 5 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 6 "register_operand" ""))]
+ [(match_operand:SI 2 "reg_or_0_operand")
+ (match_operand:SI 3 "reg_or_cint_operand")])
+ (match_operand:DI 4 "reg_or_8bit_operand")
+ (match_operand:DI 5 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 6 "register_operand"))]
"operands[3] != const0_rtx
&& (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
[(set (match_dup 6) (match_dup 7))
@@ -3704,12 +3089,12 @@
;; Prefer to use cmp and arithmetic when possible instead of a cmove.
(define_split
- [(set (match_operand 0 "register_operand" "")
+ [(set (match_operand 0 "register_operand")
(if_then_else (match_operator 1 "signed_comparison_operator"
- [(match_operand:DI 2 "reg_or_0_operand" "")
+ [(match_operand:DI 2 "reg_or_0_operand")
(const_int 0)])
- (match_operand 3 "const_int_operand" "")
- (match_operand 4 "const_int_operand" "")))]
+ (match_operand 3 "const_int_operand")
+ (match_operand 4 "const_int_operand")))]
""
[(const_int 0)]
{
@@ -3723,12 +3108,12 @@
;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
;; Oh well, we match it in movcc, so it must be partially our fault.
(define_split
- [(set (match_operand 0 "register_operand" "")
+ [(set (match_operand 0 "register_operand")
(if_then_else (match_operator 1 "signed_comparison_operator"
[(const_int 0)
- (match_operand:DI 2 "reg_or_0_operand" "")])
- (match_operand 3 "const_int_operand" "")
- (match_operand 4 "const_int_operand" "")))]
+ (match_operand:DI 2 "reg_or_0_operand")])
+ (match_operand 3 "const_int_operand")
+ (match_operand 4 "const_int_operand")))]
""
[(const_int 0)]
{
@@ -3904,10 +3289,10 @@
;; work differently, so we have different patterns for each.
(define_expand "call"
- [(use (match_operand:DI 0 "" ""))
- (use (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))]
+ [(use (match_operand:DI 0))
+ (use (match_operand 1))
+ (use (match_operand 2))
+ (use (match_operand 3))]
""
{
if (TARGET_ABI_OPEN_VMS)
@@ -3918,8 +3303,8 @@
})
(define_expand "sibcall"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand 0))
+ (match_operand 1))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
"TARGET_ABI_OSF"
{
@@ -3928,8 +3313,8 @@
})
(define_expand "call_osf"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand 0))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
""
@@ -3947,8 +3332,8 @@
;; op 1: next_arg_reg (argument information value for R25)
;;
(define_expand "call_vms"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand 0))
+ (match_operand 1))
(use (match_dup 2))
(use (reg:DI 25))
(use (reg:DI 26))
@@ -3975,15 +3360,14 @@
operands[0], 8)));
operands[2] = operands[0];
}
-
})
(define_expand "call_value"
- [(use (match_operand 0 "" ""))
- (use (match_operand:DI 1 "" ""))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))]
+ [(use (match_operand 0))
+ (use (match_operand:DI 1))
+ (use (match_operand 2))
+ (use (match_operand 3))
+ (use (match_operand 4))]
""
{
if (TARGET_ABI_OPEN_VMS)
@@ -3996,9 +3380,9 @@
})
(define_expand "sibcall_value"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand 1 "" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand 1))
+ (match_operand 2)))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
"TARGET_ABI_OSF"
{
@@ -4007,9 +3391,9 @@
})
(define_expand "call_value_osf"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand 1 "" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand 1))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
""
@@ -4022,9 +3406,9 @@
})
(define_expand "call_value_vms"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1))
+ (match_operand 2)))
(use (match_dup 3))
(use (reg:DI 25))
(use (reg:DI 26))
@@ -4055,7 +3439,7 @@
(define_insn "*call_osf_1_er_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -4069,7 +3453,7 @@
(define_insn "*call_osf_1_er"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -4083,8 +3467,8 @@
;; We must use peep2 instead of a split because we need accurate life
;; information for $gp. Consider the case of { bar(); while (1); }.
(define_peephole2
- [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -4114,8 +3498,8 @@
})
(define_peephole2
- [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -4151,10 +3535,10 @@
(define_insn "*call_osf_2_er_nogp"
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "const_int_operand" ""))
+ (use (match_operand 2))
+ (use (match_operand 3 "const_int_operand"))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
@@ -4162,12 +3546,12 @@
(define_insn "*call_osf_2_er"
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
+ (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")]
UNSPEC_LDGP1))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "const_int_operand" ""))
+ (use (match_operand 2))
+ (use (match_operand 3 "const_int_operand"))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
@@ -4177,7 +3561,7 @@
(define_insn "*call_osf_1_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -4191,7 +3575,7 @@
(define_insn "*call_osf_1"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -4204,7 +3588,7 @@
(define_insn "*sibcall_osf_1_er"
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -4217,7 +3601,7 @@
;; doesn't do what we want.
(define_insn "*sibcall_osf_1"
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -4231,7 +3615,7 @@
; Please do not molest.
(define_insn "*call_vms_1"
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (match_operand:DI 2 "nonmemory_operand" "r,n"))
(use (reg:DI 25))
(use (reg:DI 26))
@@ -4256,10 +3640,10 @@
;; Call subroutine returning any type.
(define_expand "untyped_call"
- [(parallel [(call (match_operand 0 "" "")
+ [(parallel [(call (match_operand 0)
(const_int 0))
- (match_operand 1 "" "")
- (match_operand 2 "" "")])]
+ (match_operand 1)
+ (match_operand 2)])]
""
{
int i;
@@ -4293,15 +3677,14 @@
(define_insn "jump"
[(set (pc)
- (label_ref (match_operand 0 "" "")))]
+ (label_ref (match_operand 0)))]
""
"br $31,%l0"
[(set_attr "type" "ibr")])
(define_expand "return"
[(return)]
- "direct_return ()"
- "")
+ "direct_return ()")
(define_insn "*return_internal"
[(return)]
@@ -4317,8 +3700,8 @@
(define_expand "tablejump"
[(parallel [(set (pc)
- (match_operand 0 "register_operand" ""))
- (use (label_ref:DI (match_operand 1 "" "")))])]
+ (match_operand 0 "register_operand"))
+ (use (label_ref:DI (match_operand 1)))])]
""
{
if (TARGET_ABI_OSF)
@@ -4333,7 +3716,7 @@
(define_insn "*tablejump_internal"
[(set (pc)
(match_operand:DI 0 "register_operand" "r"))
- (use (label_ref (match_operand 1 "" "")))]
+ (use (label_ref (match_operand 1)))]
""
"jmp $31,(%0),0"
[(set_attr "type" "ibr")])
@@ -4347,8 +3730,8 @@
[(set_attr "type" "callpal")])
(define_expand "clear_cache"
- [(match_operand:DI 0 "") ; region start
- (match_operand:DI 1 "")] ; region end
+ [(match_operand:DI 0) ; region start
+ (match_operand:DI 1)] ; region end
""
{
emit_insn (gen_imb ());
@@ -4365,7 +3748,7 @@
;; For userland, we load the thread pointer from the TCB.
;; For the kernel, we load the per-cpu private value.
-(define_insn "load_tp"
+(define_insn "get_thread_pointerdi"
[(set (match_operand:DI 0 "register_operand" "=v")
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_ABI_OSF"
@@ -4382,11 +3765,10 @@
;; quantity for CSE, we have to use a volatile unspec, and then there's
;; not much point in creating an R16_REG register class.
-(define_expand "set_tp"
- [(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
+(define_expand "set_thread_pointerdi"
+ [(set (reg:DI 16) (match_operand:DI 0 "input_operand"))
(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
- "TARGET_ABI_OSF"
- "")
+ "TARGET_ABI_OSF")
(define_insn "*set_tp"
[(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
@@ -4402,8 +3784,8 @@
;; Special builtins for establishing and reverting VMS condition handlers.
(define_expand "builtin_establish_vms_condition_handler"
- [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:DI 1 "address_operand" ""))]
+ [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))
+ (use (match_operand:DI 1 "address_operand"))]
"TARGET_ABI_OPEN_VMS"
{
alpha_expand_builtin_establish_vms_condition_handler (operands[0],
@@ -4411,19 +3793,17 @@
})
(define_expand "builtin_revert_vms_condition_handler"
- [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))]
+ [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))]
"TARGET_ABI_OPEN_VMS"
-{
- alpha_expand_builtin_revert_vms_condition_handler (operands[0]);
-})
+ "alpha_expand_builtin_revert_vms_condition_handler (operands[0]);")
;; Finally, we have the basic data motion insns. The byte and word insns
;; are done via define_expand. Start with the floating-point insns, since
;; they are simpler.
(define_expand "movsf"
- [(set (match_operand:SF 0 "nonimmediate_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
+ [(set (match_operand:SF 0 "nonimmediate_operand")
+ (match_operand:SF 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4449,8 +3829,8 @@
(set_attr "isa" "*,*,*,*,*,*,fix,fix")])
(define_expand "movdf"
- [(set (match_operand:DF 0 "nonimmediate_operand" "")
- (match_operand:DF 1 "general_operand" ""))]
+ [(set (match_operand:DF 0 "nonimmediate_operand")
+ (match_operand:DF 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4480,8 +3860,8 @@
;; ??? Is this still true now that we have the lower-subreg pass?
(define_expand "movtf"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (match_operand:TF 1 "general_operand" ""))]
+ [(set (match_operand:TF 0 "nonimmediate_operand")
+ (match_operand:TF 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4498,16 +3878,14 @@
"reload_completed"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
-{
- alpha_split_tmode_pair (operands, TFmode, true);
-})
+ "alpha_split_tmode_pair (operands, TFmode, true);")
;; We do two major things here: handle mem->mem and construct long
;; constants.
(define_expand "movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
+ [(set (match_operand:SI 0 "nonimmediate_operand")
+ (match_operand:SI 1 "general_operand"))]
""
{
if (alpha_expand_mov (SImode, operands))
@@ -4534,8 +3912,8 @@
;; sequence.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "non_add_const_operand" ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "non_add_const_operand"))]
""
[(const_int 0)]
{
@@ -4548,7 +3926,7 @@
(define_insn "*movdi_er_low_l"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "local_symbolic_operand" "")))]
+ (match_operand:DI 2 "local_symbolic_operand")))]
"TARGET_EXPLICIT_RELOCS"
{
if (true_regnum (operands[1]) == 29)
@@ -4559,16 +3937,16 @@
[(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "small_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "small_symbolic_operand"))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(lo_sum:DI (match_dup 2) (match_dup 1)))]
"operands[2] = pic_offset_table_rtx;")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "local_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "local_symbolic_operand"))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(plus:DI (match_dup 2) (high:DI (match_dup 1))))
@@ -4577,7 +3955,7 @@
"operands[2] = pic_offset_table_rtx;")
(define_split
- [(match_operand 0 "some_small_symbolic_operand" "")]
+ [(match_operand 0 "some_small_symbolic_operand")]
""
[(match_dup 0)]
"operands[0] = split_small_symbolic_operand (operands[0]);")
@@ -4587,8 +3965,8 @@
(define_insn "movdi_er_high_g"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")
- (match_operand 3 "const_int_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")
+ (match_operand 3 "const_int_operand")]
UNSPEC_LITERAL))]
"TARGET_EXPLICIT_RELOCS"
{
@@ -4600,8 +3978,8 @@
[(set_attr "type" "ldsym")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "global_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "global_symbolic_operand"))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
@@ -4612,8 +3990,8 @@
(define_insn "movdi_er_tlsgd"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")
- (match_operand 3 "const_int_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")
+ (match_operand 3 "const_int_operand")]
UNSPEC_TLSGD))]
"HAVE_AS_TLS"
{
@@ -4626,7 +4004,7 @@
(define_insn "movdi_er_tlsldm"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPEC_TLSLDM))]
"HAVE_AS_TLS"
{
@@ -4639,7 +4017,7 @@
(define_insn "*movdi_er_gotdtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")]
UNSPEC_DTPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gotdtprel"
@@ -4647,8 +4025,8 @@
(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "gotdtp_symbolic_operand"))]
"HAVE_AS_TLS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
@@ -4661,7 +4039,7 @@
(define_insn "*movdi_er_gottp"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")]
UNSPEC_TPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gottprel"
@@ -4669,8 +4047,8 @@
(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "gottp_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "gottp_symbolic_operand"))]
"HAVE_AS_TLS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
@@ -4722,8 +4100,8 @@
;; memory, and construct long 32-bit constants.
(define_expand "movdi"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
+ [(set (match_operand:DI 0 "nonimmediate_operand")
+ (match_operand:DI 1 "general_operand"))]
""
{
if (alpha_expand_mov (DImode, operands))
@@ -4734,8 +4112,8 @@
;; sequence.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "non_add_const_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "non_add_const_operand"))]
""
[(const_int 0)]
{
@@ -4761,13 +4139,11 @@
"reload_completed"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
-{
- alpha_split_tmode_pair (operands, TImode, true);
-})
+ "alpha_split_tmode_pair (operands, TImode, true);")
(define_expand "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "general_operand" ""))]
+ [(set (match_operand:TI 0 "nonimmediate_operand")
+ (match_operand:TI 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4829,26 +4205,20 @@
;; same register. It is allowed to conflict with operand 1 as well.
(define_expand "aligned_loadqi"
- [(set (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 8)
- (match_operand:DI 2 "const_int_operand" "")))]
-
- ""
- "")
+ (match_operand:DI 2 "const_int_operand")))])
(define_expand "aligned_loadhi"
- [(set (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 16)
- (match_operand:DI 2 "const_int_operand" "")))]
-
- ""
- "")
+ (match_operand:DI 2 "const_int_operand")))])
;; Similar for unaligned loads, where we use the sequence from the
;; Alpha Architecture manual. We have to distinguish between little-endian
@@ -4858,30 +4228,26 @@
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
- [(set (match_operand:DI 2 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
+ [(set (match_operand:DI 2 "register_operand")
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand")
(const_int -8))))
- (set (match_operand:DI 3 "register_operand" "")
+ (set (match_operand:DI 3 "register_operand")
(match_dup 1))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (match_dup 2)
(const_int 8)
- (ashift:DI (match_dup 3) (const_int 3))))]
- ""
- "")
+ (ashift:DI (match_dup 3) (const_int 3))))])
(define_expand "unaligned_loadhi"
- [(set (match_operand:DI 2 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
+ [(set (match_operand:DI 2 "register_operand")
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand")
(const_int -8))))
- (set (match_operand:DI 3 "register_operand" "")
+ (set (match_operand:DI 3 "register_operand")
(match_dup 1))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (match_dup 2)
(const_int 16)
- (ashift:DI (match_dup 3) (const_int 3))))]
- ""
- "")
+ (ashift:DI (match_dup 3) (const_int 3))))])
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
;; aligned SImode MEM. Operand 1 is the register containing the
@@ -4889,13 +4255,13 @@
;; the value should be placed. Operands 3 and 4 are SImode temporaries.
(define_expand "aligned_store"
- [(set (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 0 "memory_operand" ""))
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 0 "memory_operand"))
(set (subreg:DI (match_dup 3) 0)
(and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
- (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
- (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
- (match_operand:DI 2 "const_int_operand" "")))
+ (set (subreg:DI (match_operand:SI 4 "register_operand") 0)
+ (ashift:DI (zero_extend:DI (match_operand 1 "register_operand"))
+ (match_operand:DI 2 "const_int_operand")))
(set (subreg:DI (match_dup 4) 0)
(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
(set (match_dup 0) (match_dup 4))]
@@ -4912,56 +4278,38 @@
;; be the same temporary, if desired. If the address is in a register,
;; operand 2 can be that register.
-(define_expand "unaligned_storeqi"
- [(set (match_operand:DI 3 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
+(define_expand "unaligned_store<mode>"
+ [(set (match_operand:DI 3 "register_operand")
+ (mem:DI (and:DI (match_operand:DI 0 "address_operand")
(const_int -8))))
- (set (match_operand:DI 2 "register_operand" "")
+ (set (match_operand:DI 2 "register_operand")
(match_dup 0))
(set (match_dup 3)
- (and:DI (not:DI (ashift:DI (const_int 255)
+ (and:DI (not:DI (ashift:DI (match_dup 5)
(ashift:DI (match_dup 2) (const_int 3))))
(match_dup 3)))
- (set (match_operand:DI 4 "register_operand" "")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
+ (set (match_operand:DI 4 "register_operand")
+ (ashift:DI (zero_extend:DI
+ (match_operand:I12MODE 1 "register_operand"))
(ashift:DI (match_dup 2) (const_int 3))))
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
""
- "")
-
-(define_expand "unaligned_storehi"
- [(set (match_operand:DI 3 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
- (const_int -8))))
- (set (match_operand:DI 2 "register_operand" "")
- (match_dup 0))
- (set (match_dup 3)
- (and:DI (not:DI (ashift:DI (const_int 65535)
- (ashift:DI (match_dup 2) (const_int 3))))
- (match_dup 3)))
- (set (match_operand:DI 4 "register_operand" "")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
- (ashift:DI (match_dup 2) (const_int 3))))
- (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
- (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
- (match_dup 4))]
- ""
- "")
+ "operands[5] = GEN_INT (GET_MODE_MASK (<MODE>mode));")
;; Here are the define_expand's for QI and HI moves that use the above
;; patterns. We have the normal sets, plus the ones that need scratch
;; registers for reload.
-(define_expand "movqi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
+(define_expand "mov<mode>"
+ [(set (match_operand:I12MODE 0 "nonimmediate_operand")
+ (match_operand:I12MODE 1 "general_operand"))]
""
{
if (TARGET_BWX
- ? alpha_expand_mov (QImode, operands)
- : alpha_expand_mov_nobwx (QImode, operands))
+ ? alpha_expand_mov (<MODE>mode, operands)
+ : alpha_expand_mov_nobwx (<MODE>mode, operands))
DONE;
})
@@ -4978,17 +4326,6 @@
[(set_attr "type" "ilog,iadd,ild,ist")
(set_attr "isa" "*,*,bwx,bwx")])
-(define_expand "movhi"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
-{
- if (TARGET_BWX
- ? alpha_expand_mov (HImode, operands)
- : alpha_expand_mov_nobwx (HImode, operands))
- DONE;
-})
-
(define_insn "*movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
(match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
@@ -5005,8 +4342,8 @@
;; We need to hook into the extra support that we have for HImode
;; reloads when BWX insns are not available.
(define_expand "movcqi"
- [(set (match_operand:CQI 0 "nonimmediate_operand" "")
- (match_operand:CQI 1 "general_operand" ""))]
+ [(set (match_operand:CQI 0 "nonimmediate_operand")
+ (match_operand:CQI 1 "general_operand"))]
"!TARGET_BWX"
{
if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
@@ -5162,10 +4499,11 @@
;; Vector operations
(define_mode_iterator VEC [V8QI V4HI V2SI])
+(define_mode_iterator VEC12 [V8QI V4HI])
(define_expand "mov<mode>"
- [(set (match_operand:VEC 0 "nonimmediate_operand" "")
- (match_operand:VEC 1 "general_operand" ""))]
+ [(set (match_operand:VEC 0 "nonimmediate_operand")
+ (match_operand:VEC 1 "general_operand"))]
""
{
if (alpha_expand_mov (<MODE>mode, operands))
@@ -5173,8 +4511,8 @@
})
(define_split
- [(set (match_operand:VEC 0 "register_operand" "")
- (match_operand:VEC 1 "non_zero_const_operand" ""))]
+ [(set (match_operand:VEC 0 "register_operand")
+ (match_operand:VEC 1 "non_zero_const_operand"))]
""
[(const_int 0)]
{
@@ -5186,8 +4524,8 @@
(define_expand "movmisalign<mode>"
- [(set (match_operand:VEC 0 "nonimmediate_operand" "")
- (match_operand:VEC 1 "general_operand" ""))]
+ [(set (match_operand:VEC 0 "nonimmediate_operand")
+ (match_operand:VEC 1 "general_operand"))]
""
{
alpha_expand_movmisalign (<MODE>mode, operands);
@@ -5212,68 +4550,13 @@
[(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
(set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
-(define_insn "uminv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minub8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "sminv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minsb8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "uminv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minuw4 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "sminv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minsw4 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "maxub8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
+(define_insn "<code><mode>3"
+ [(set (match_operand:VEC12 0 "register_operand" "=r")
+ (any_maxmin:VEC12
+ (match_operand:VEC12 1 "reg_or_0_operand" "rW")
+ (match_operand:VEC12 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
- "maxsb8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "maxuw4 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "maxsw4 %r1,%r2,%0"
+ "<maxmin><modesuffix> %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "one_cmpl<mode>2"
@@ -5332,9 +4615,9 @@
[(set_attr "type" "ilog")])
(define_expand "vec_shl_<mode>"
- [(set (match_operand:VEC 0 "register_operand" "")
- (ashift:DI (match_operand:VEC 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+ [(set (match_operand:VEC 0 "register_operand")
+ (ashift:DI (match_operand:VEC 1 "register_operand")
+ (match_operand:DI 2 "reg_or_6bit_operand")))]
""
{
operands[0] = gen_lowpart (DImode, operands[0]);
@@ -5342,9 +4625,9 @@
})
(define_expand "vec_shr_<mode>"
- [(set (match_operand:VEC 0 "register_operand" "")
- (lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+ [(set (match_operand:VEC 0 "register_operand")
+ (lshiftrt:DI (match_operand:VEC 1 "register_operand")
+ (match_operand:DI 2 "reg_or_6bit_operand")))]
""
{
operands[0] = gen_lowpart (DImode, operands[0]);
@@ -5354,10 +4637,10 @@
;; Bit field extract patterns which use ext[wlq][lh]
(define_expand "extv"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
- (match_operand:DI 2 "immediate_operand" "")
- (match_operand:DI 3 "immediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extract:DI (match_operand:QI 1 "memory_operand")
+ (match_operand:DI 2 "immediate_operand")
+ (match_operand:DI 3 "immediate_operand")))]
""
{
int ofs;
@@ -5384,10 +4667,10 @@
})
(define_expand "extzv"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "immediate_operand" "")
- (match_operand:DI 3 "immediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand")
+ (match_operand:DI 2 "immediate_operand")
+ (match_operand:DI 3 "immediate_operand")))]
""
{
/* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
@@ -5417,10 +4700,10 @@
})
(define_expand "insv"
- [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
- (match_operand:DI 1 "immediate_operand" "")
- (match_operand:DI 2 "immediate_operand" ""))
- (match_operand:DI 3 "register_operand" ""))]
+ [(set (zero_extract:DI (match_operand:QI 0 "memory_operand")
+ (match_operand:DI 1 "immediate_operand")
+ (match_operand:DI 2 "immediate_operand"))
+ (match_operand:DI 3 "register_operand"))]
""
{
int ofs;
@@ -5452,10 +4735,10 @@
;; Argument 3 is the alignment
(define_expand "movmemqi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))])]
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand:BLK 1 "memory_operand"))
+ (use (match_operand:DI 2 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))])]
""
{
if (alpha_expand_block_move (operands))
@@ -5465,10 +4748,10 @@
})
(define_expand "movmemdi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand:BLK 1 "memory_operand"))
+ (use (match_operand:DI 2 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))
(use (match_dup 4))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5479,15 +4762,13 @@
(clobber (reg:DI 26))
(clobber (reg:DI 27))])]
"TARGET_ABI_OPEN_VMS"
-{
- operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE");
-})
+ "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
(define_insn "*movmemdi_1"
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
(match_operand:BLK 1 "memory_operand" "m,m"))
(use (match_operand:DI 2 "nonmemory_operand" "r,i"))
- (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_operand:DI 3 "immediate_operand"))
(use (match_operand:DI 4 "call_operand" "i,i"))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5514,10 +4795,10 @@
(set_attr "length" "28")])
(define_expand "setmemqi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand 2 "const_int_operand" ""))
- (use (match_operand:DI 1 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))])]
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand 2 "const_int_operand"))
+ (use (match_operand:DI 1 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))])]
""
{
/* If value to set is not zero, use the library routine. */
@@ -5531,10 +4812,10 @@
})
(define_expand "setmemdi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand 2 "const_int_operand" ""))
- (use (match_operand:DI 1 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand 2 "const_int_operand"))
+ (use (match_operand:DI 1 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))
(use (match_dup 4))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5554,7 +4835,7 @@
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
(const_int 0))
(use (match_operand:DI 1 "nonmemory_operand" "r,i"))
- (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_operand:DI 2 "immediate_operand"))
(use (match_operand:DI 3 "call_operand" "i,i"))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5580,7 +4861,7 @@
;; Subroutine of stack space allocation. Perform a stack probe.
(define_expand "probe_stack"
- [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
+ [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))]
""
{
operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx,
@@ -5599,7 +4880,7 @@
(define_expand "allocate_stack"
[(set (reg:DI 30)
(plus:DI (reg:DI 30)
- (match_operand:DI 1 "reg_or_cint_operand" "")))
+ (match_operand:DI 1 "reg_or_cint_operand")))
(set (match_operand:DI 0 "register_operand" "=r")
(match_dup 2))]
""
@@ -5687,7 +4968,7 @@
(set_attr "type" "multi")])
(define_expand "prologue"
- [(clobber (const_int 0))]
+ [(const_int 0)]
""
{
alpha_expand_prologue ();
@@ -5718,7 +4999,7 @@
(define_insn "*ldgp_er_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"ldah %0,0(%1)\t\t!gpdisp!%2"
@@ -5727,7 +5008,7 @@
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"lda %0,0(%1)\t\t!gpdisp!%2"
@@ -5736,7 +5017,7 @@
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
@@ -5745,7 +5026,7 @@
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_LDGP1))]
""
"ldgp %0,0(%1)\n$%~..ng:"
@@ -5754,10 +5035,10 @@
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_PLDGP2))]
""
- "")
+ )
;; The _mcount profiling hook has special calling conventions, and
;; does not clobber all the registers that a normal call would. So
@@ -5787,9 +5068,7 @@
(define_expand "epilogue"
[(return)]
""
-{
- alpha_expand_epilogue ();
-})
+ "alpha_expand_epilogue ();")
(define_expand "sibcall_epilogue"
[(return)]
@@ -5835,12 +5114,11 @@
[(set_attr "type" "ibr")])
(define_expand "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
- "TARGET_ABI_OSF"
- "")
+ [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)]
+ "TARGET_ABI_OSF")
(define_insn_and_split "*builtin_setjmp_receiver_1"
- [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
+ [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)]
"TARGET_ABI_OSF"
{
if (TARGET_EXPLICIT_RELOCS)
@@ -5865,7 +5143,7 @@
(set_attr "type" "multi")])
(define_insn "*builtin_setjmp_receiver_er_sl_1"
- [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
+ [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)]
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
@@ -5919,8 +5197,7 @@
(set (reg:DI 27) (mem:DI (reg:DI 29)))
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(use (reg:DI 27))]
- "TARGET_ABI_OPEN_VMS"
- "")
+ "TARGET_ABI_OPEN_VMS")
(define_insn "arg_home"
[(unspec [(const_int 0)] UNSPEC_ARG_HOME)
@@ -6035,9 +5312,9 @@
[(set_attr "type" "icmp")])
(define_expand "extbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
@@ -6045,9 +5322,9 @@
})
(define_expand "extwl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
@@ -6055,9 +5332,9 @@
})
(define_expand "extll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
@@ -6065,9 +5342,9 @@
})
(define_expand "extql"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
@@ -6075,9 +5352,9 @@
})
(define_expand "builtin_insbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
operands[1] = gen_lowpart (QImode, operands[1]);
@@ -6086,9 +5363,9 @@
})
(define_expand "builtin_inswl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
operands[1] = gen_lowpart (HImode, operands[1]);
@@ -6097,9 +5374,9 @@
})
(define_expand "builtin_insll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
operands[1] = gen_lowpart (SImode, operands[1]);
@@ -6108,9 +5385,9 @@
})
(define_expand "inswh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
@@ -6118,9 +5395,9 @@
})
(define_expand "inslh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
@@ -6128,9 +5405,9 @@
})
(define_expand "insqh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
@@ -6138,9 +5415,9 @@
})
(define_expand "mskbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = GEN_INT (0xff);
@@ -6149,9 +5426,9 @@
})
(define_expand "mskwl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = GEN_INT (0xffff);
@@ -6160,9 +5437,9 @@
})
(define_expand "mskll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = immed_double_const (0xffffffff, 0, DImode);
@@ -6171,9 +5448,9 @@
})
(define_expand "mskql"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = constm1_rtx;
@@ -6182,9 +5459,9 @@
})
(define_expand "mskwh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
@@ -6192,9 +5469,9 @@
})
(define_expand "msklh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
@@ -6202,9 +5479,9 @@
})
(define_expand "mskqh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
@@ -6212,11 +5489,11 @@
})
(define_expand "builtin_zap"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(match_operand:DI 2 "reg_or_cint_operand" "")]
+ [(match_operand:DI 2 "reg_or_cint_operand")]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_cint_operand" "")))]
+ (match_operand:DI 1 "reg_or_cint_operand")))]
""
{
if (CONST_INT_P (operands[2]))
@@ -6258,11 +5535,11 @@
[(set_attr "type" "shift,shift,ilog,shift")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(match_operand:QI 2 "const_int_operand" "")]
+ [(match_operand:QI 2 "const_int_operand")]
UNSPEC_ZAP)
- (match_operand:DI 1 "const_int_operand" "")))]
+ (match_operand:DI 1 "const_int_operand")))]
""
[(const_int 0)]
{
@@ -6282,11 +5559,11 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(match_operand:QI 2 "const_int_operand" "")]
+ [(match_operand:QI 2 "const_int_operand")]
UNSPEC_ZAP)
- (match_operand:DI 1 "register_operand" "")))]
+ (match_operand:DI 1 "register_operand")))]
""
[(set (match_dup 0)
(and:DI (match_dup 1) (match_dup 2)))]
@@ -6305,11 +5582,11 @@
})
(define_expand "builtin_zapnot"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
+ [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_cint_operand" "")))]
+ (match_operand:DI 1 "reg_or_cint_operand")))]
""
{
if (CONST_INT_P (operands[2]))
@@ -6369,9 +5646,9 @@
[(set_attr "type" "ilog")])
(define_expand "builtin_minub8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
@@ -6380,9 +5657,9 @@
})
(define_expand "builtin_minsb8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
@@ -6391,9 +5668,9 @@
})
(define_expand "builtin_minuw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
@@ -6402,9 +5679,9 @@
})
(define_expand "builtin_minsw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
@@ -6413,9 +5690,9 @@
})
(define_expand "builtin_maxub8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
@@ -6424,9 +5701,9 @@
})
(define_expand "builtin_maxsb8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
@@ -6435,9 +5712,9 @@
})
(define_expand "builtin_maxuw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
@@ -6446,9 +5723,9 @@
})
(define_expand "builtin_maxsw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
@@ -6466,10 +5743,10 @@
[(set_attr "type" "mvi")])
(define_expand "builtin_pklb"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(vec_concat:V8QI
(vec_concat:V4QI
- (truncate:V2QI (match_operand:DI 1 "register_operand" ""))
+ (truncate:V2QI (match_operand:DI 1 "register_operand"))
(match_dup 2))
(match_dup 3)))]
"TARGET_MAX"
@@ -6485,16 +5762,16 @@
(vec_concat:V8QI
(vec_concat:V4QI
(truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
- (match_operand:V2QI 2 "const0_operand" ""))
- (match_operand:V4QI 3 "const0_operand" "")))]
+ (match_operand:V2QI 2 "const0_operand"))
+ (match_operand:V4QI 3 "const0_operand")))]
"TARGET_MAX"
"pklb %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_pkwb"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(vec_concat:V8QI
- (truncate:V4QI (match_operand:DI 1 "register_operand" ""))
+ (truncate:V4QI (match_operand:DI 1 "register_operand"))
(match_dup 2)))]
"TARGET_MAX"
{
@@ -6507,15 +5784,15 @@
[(set (match_operand:V8QI 0 "register_operand" "=r")
(vec_concat:V8QI
(truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
- (match_operand:V4QI 2 "const0_operand" "")))]
+ (match_operand:V4QI 2 "const0_operand")))]
"TARGET_MAX"
"pkwb %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_unpkbl"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(zero_extend:V2SI
- (vec_select:V2QI (match_operand:DI 1 "register_operand" "")
+ (vec_select:V2QI (match_operand:DI 1 "register_operand")
(parallel [(const_int 0) (const_int 1)]))))]
"TARGET_MAX"
{
@@ -6533,9 +5810,9 @@
[(set_attr "type" "mvi")])
(define_expand "builtin_unpkbw"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(zero_extend:V4HI
- (vec_select:V4QI (match_operand:DI 1 "register_operand" "")
+ (vec_select:V4QI (match_operand:DI 1 "register_operand")
(parallel [(const_int 0)
(const_int 1)
(const_int 2)
@@ -6564,9 +5841,9 @@
;; wildcard operand0 interferes with nice recognition.
(define_insn "*call_value_osf_1_er_noreturn"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -6579,9 +5856,9 @@
(set_attr "length" "*,*,8")])
(define_insn "*call_value_osf_1_er"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -6595,9 +5872,9 @@
;; We must use peep2 instead of a split because we need accurate life
;; information for $gp. Consider the case of { bar(); while (1); }.
(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "call_operand"))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -6628,9 +5905,9 @@
})
(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "call_operand"))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -6666,26 +5943,26 @@
})
(define_insn "*call_value_osf_2_er_nogp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
- (use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))
+ (use (match_operand 3))
+ (use (match_operand 4))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
[(set_attr "type" "jsr")])
(define_insn "*call_value_osf_2_er"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
+ (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")]
UNSPEC_LDGP1))
- (use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))
+ (use (match_operand 3))
+ (use (match_operand 4))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
@@ -6694,9 +5971,9 @@
(set_attr "length" "8")])
(define_insn "*call_value_osf_1_noreturn"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -6709,10 +5986,10 @@
(set_attr "length" "*,*,8")])
(define_insn_and_split "call_value_osf_tlsgd"
- [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
+ [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
(const_int 0)))
- (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
+ (unspec [(match_operand:DI 2 "const_int_operand")] UNSPEC_TLSGD_CALL)
(use (reg:DI 29))
(clobber (reg:DI 26))]
"HAVE_AS_TLS"
@@ -6740,10 +6017,10 @@
[(set_attr "type" "multi")])
(define_insn_and_split "call_value_osf_tlsldm"
- [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
+ [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
(const_int 0)))
- (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
+ (unspec [(match_operand:DI 2 "const_int_operand")] UNSPEC_TLSLDM_CALL)
(use (reg:DI 29))
(clobber (reg:DI 26))]
"HAVE_AS_TLS"
@@ -6771,9 +6048,9 @@
[(set_attr "type" "multi")])
(define_insn "*call_value_osf_1"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -6785,9 +6062,9 @@
(set_attr "length" "12,*,16")])
(define_insn "*sibcall_value_osf_1_er"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -6797,9 +6074,9 @@
(set_attr "length" "*,8")])
(define_insn "*sibcall_value_osf_1"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -6812,9 +6089,9 @@
; to generate relocs for VMS link to potentially optimize the call.
; Please do not molest.
(define_insn "*call_value_vms_1"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (match_operand:DI 3 "nonmemory_operand" "r,n"))
(use (reg:DI 25))
(use (reg:DI 26))
diff --git a/gcc/config/alpha/sync.md b/gcc/config/alpha/sync.md
index bde99c456cf..cdde7256506 100644
--- a/gcc/config/alpha/sync.md
+++ b/gcc/config/alpha/sync.md
@@ -37,7 +37,7 @@
})
(define_insn "*memory_barrier"
- [(set (match_operand:BLK 0 "" "")
+ [(set (match_operand:BLK 0)
(unspec:BLK [(match_dup 0)] UNSPEC_MB))]
""
"mb"
@@ -71,18 +71,18 @@
(define_expand "atomic_compare_and_swap<mode>"
[(parallel
- [(set (match_operand:DI 0 "register_operand" "") ;; bool out
+ [(set (match_operand:DI 0 "register_operand") ;; bool out
(unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG))
- (set (match_operand:I48MODE 1 "register_operand" "") ;; val out
+ (set (match_operand:I48MODE 1 "register_operand") ;; val out
(unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG))
- (set (match_operand:I48MODE 2 "memory_operand" "") ;; memory
+ (set (match_operand:I48MODE 2 "memory_operand") ;; memory
(unspec_volatile:I48MODE
[(match_dup 2)
- (match_operand:I48MODE 3 "reg_or_8bit_operand" "") ;; expected
- (match_operand:I48MODE 4 "add_operand" "") ;; desired
- (match_operand:SI 5 "const_int_operand" "") ;; is_weak
- (match_operand:SI 6 "const_int_operand" "") ;; succ model
- (match_operand:SI 7 "const_int_operand" "")] ;; fail model
+ (match_operand:I48MODE 3 "reg_or_8bit_operand") ;; expected
+ (match_operand:I48MODE 4 "add_operand") ;; desired
+ (match_operand:SI 5 "const_int_operand") ;; is_weak
+ (match_operand:SI 6 "const_int_operand") ;; succ model
+ (match_operand:SI 7 "const_int_operand")] ;; fail model
UNSPECV_CMPXCHG))])]
""
{
@@ -103,9 +103,9 @@
[(match_dup 2)
(match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected
(match_operand:DI 4 "add_operand" "rKL") ;; desired
- (match_operand:SI 5 "const_int_operand" "") ;; is_weak
- (match_operand:SI 6 "const_int_operand" "") ;; succ model
- (match_operand:SI 7 "const_int_operand" "")] ;; fail model
+ (match_operand:SI 5 "const_int_operand") ;; is_weak
+ (match_operand:SI 6 "const_int_operand") ;; succ model
+ (match_operand:SI 7 "const_int_operand")] ;; fail model
UNSPECV_CMPXCHG))]
""
"#"
@@ -118,14 +118,14 @@
[(set_attr "type" "multi")])
(define_expand "atomic_compare_and_swap<mode>"
- [(match_operand:DI 0 "register_operand" "") ;; bool out
- (match_operand:I12MODE 1 "register_operand" "") ;; val out
- (match_operand:I12MODE 2 "mem_noofs_operand" "") ;; memory
- (match_operand:I12MODE 3 "register_operand" "") ;; expected
- (match_operand:I12MODE 4 "add_operand" "") ;; desired
- (match_operand:SI 5 "const_int_operand" "") ;; is_weak
- (match_operand:SI 6 "const_int_operand" "") ;; succ model
- (match_operand:SI 7 "const_int_operand" "")] ;; fail model
+ [(match_operand:DI 0 "register_operand") ;; bool out
+ (match_operand:I12MODE 1 "register_operand") ;; val out
+ (match_operand:I12MODE 2 "mem_noofs_operand") ;; memory
+ (match_operand:I12MODE 3 "register_operand") ;; expected
+ (match_operand:I12MODE 4 "add_operand") ;; desired
+ (match_operand:SI 5 "const_int_operand") ;; is_weak
+ (match_operand:SI 6 "const_int_operand") ;; succ model
+ (match_operand:SI 7 "const_int_operand")] ;; fail model
""
{
alpha_expand_compare_and_swap_12 (operands);
@@ -144,9 +144,9 @@
(match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected
(match_operand:DI 4 "reg_or_0_operand" "rJ") ;; desired
(match_operand:DI 5 "register_operand" "r") ;; align
- (match_operand:SI 6 "const_int_operand" "") ;; is_weak
- (match_operand:SI 7 "const_int_operand" "") ;; succ model
- (match_operand:SI 8 "const_int_operand" "")] ;; fail model
+ (match_operand:SI 6 "const_int_operand") ;; is_weak
+ (match_operand:SI 7 "const_int_operand") ;; succ model
+ (match_operand:SI 8 "const_int_operand")] ;; fail model
UNSPECV_CMPXCHG))
(clobber (match_scratch:DI 9 "=&r"))]
""
@@ -165,7 +165,7 @@
(set (match_dup 1)
(unspec:I48MODE
[(match_operand:I48MODE 2 "add_operand" "rKL") ;; input
- (match_operand:SI 3 "const_int_operand" "")] ;; model
+ (match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_XCHG))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -179,10 +179,10 @@
[(set_attr "type" "multi")])
(define_expand "atomic_exchange<mode>"
- [(match_operand:I12MODE 0 "register_operand" "") ;; output
- (match_operand:I12MODE 1 "mem_noofs_operand" "") ;; memory
- (match_operand:I12MODE 2 "reg_or_0_operand" "") ;; input
- (match_operand:SI 3 "const_int_operand" "")] ;; model
+ [(match_operand:I12MODE 0 "register_operand") ;; output
+ (match_operand:I12MODE 1 "mem_noofs_operand") ;; memory
+ (match_operand:I12MODE 2 "reg_or_0_operand") ;; input
+ (match_operand:SI 3 "const_int_operand")] ;; model
""
{
alpha_expand_atomic_exchange_12 (operands);
@@ -197,7 +197,7 @@
(unspec:I12MODE
[(match_operand:DI 2 "reg_or_8bit_operand" "rI") ;; input
(match_operand:DI 3 "register_operand" "r") ;; align
- (match_operand:SI 4 "const_int_operand" "")] ;; model
+ (match_operand:SI 4 "const_int_operand")] ;; model
UNSPEC_XCHG))
(clobber (match_scratch:DI 5 "=&r"))]
""
@@ -215,7 +215,7 @@
(unspec:I48MODE
[(FETCHOP:I48MODE (match_dup 0)
(match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))
- (match_operand:SI 2 "const_int_operand" "")]
+ (match_operand:SI 2 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 3 "=&r"))]
""
@@ -236,7 +236,7 @@
[(not:I48MODE
(and:I48MODE (match_dup 0)
(match_operand:I48MODE 1 "register_operand" "r")))
- (match_operand:SI 2 "const_int_operand" "")]
+ (match_operand:SI 2 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 3 "=&r"))]
""
@@ -258,7 +258,7 @@
(unspec:I48MODE
[(FETCHOP:I48MODE (match_dup 1)
(match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -281,7 +281,7 @@
[(not:I48MODE
(and:I48MODE (match_dup 1)
(match_operand:I48MODE 2 "register_operand" "r")))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -304,7 +304,7 @@
(set (match_dup 1)
(unspec:I48MODE
[(FETCHOP:I48MODE (match_dup 1) (match_dup 2))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -327,7 +327,7 @@
(set (match_dup 1)
(unspec:I48MODE
[(not:I48MODE (and:I48MODE (match_dup 1) (match_dup 2)))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
diff --git a/gcc/config/arm/arm-arches.def b/gcc/config/arm/arm-arches.def
index f83639df83b..d0b968f88a4 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 d0fbfd3704b..377e5e14552 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-protos.h b/gcc/config/arm/arm-protos.h
index c590ef420eb..010e7fc1c15 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -163,6 +163,7 @@ extern int arm_attr_length_push_multi(rtx, rtx);
extern void arm_expand_compare_and_swap (rtx op[]);
extern void arm_split_compare_and_swap (rtx op[]);
extern void arm_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
+extern rtx arm_load_tp (rtx);
#if defined TREE_CODE
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index 5f9369553e0..1616d9da27e 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 1470602a215..11f793d5d77 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. */
@@ -753,6 +756,9 @@ int arm_arch6 = 0;
/* Nonzero if this chip supports the ARM 6K extensions. */
int arm_arch6k = 0;
+/* Nonzero if instructions present in ARMv6-M can be used. */
+int arm_arch6m = 0;
+
/* Nonzero if this chip supports the ARM 7 extensions. */
int arm_arch7 = 0;
@@ -762,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;
@@ -1056,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
};
@@ -1737,8 +1746,10 @@ arm_option_override (void)
arm_arch6 = (insn_flags & FL_ARCH6) != 0;
arm_arch6k = (insn_flags & FL_ARCH6K) != 0;
arm_arch_notm = (insn_flags & FL_NOTM) != 0;
+ 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;
@@ -1955,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
@@ -6275,7 +6287,7 @@ get_tls_get_addr (void)
return tls_get_addr_libfunc;
}
-static rtx
+rtx
arm_load_tp (rtx target)
{
if (!target)
@@ -16728,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
@@ -18714,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),
@@ -19151,8 +19165,6 @@ enum arm_builtins
ARM_BUILTIN_WMERGE,
- ARM_BUILTIN_THREAD_POINTER,
-
ARM_BUILTIN_NEON_BASE,
ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data)
@@ -20192,20 +20204,6 @@ arm_init_iwmmxt_builtins (void)
}
static void
-arm_init_tls_builtins (void)
-{
- tree ftype, decl;
-
- ftype = build_function_type (ptr_type_node, void_list_node);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- ARM_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- TREE_READONLY (decl) = 1;
- arm_builtin_decls[ARM_BUILTIN_THREAD_POINTER] = decl;
-}
-
-static void
arm_init_fp16_builtins (void)
{
tree fp16_type = make_node (REAL_TYPE);
@@ -20217,8 +20215,6 @@ arm_init_fp16_builtins (void)
static void
arm_init_builtins (void)
{
- arm_init_tls_builtins ();
-
if (TARGET_REALLY_IWMMXT)
arm_init_iwmmxt_builtins ();
@@ -21330,9 +21326,6 @@ arm_expand_builtin (tree exp,
}
return arm_expand_binop_builtin (icode, exp, target);
- case ARM_BUILTIN_THREAD_POINTER:
- return arm_load_tp (target);
-
default:
break;
}
@@ -22638,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 ());
@@ -22862,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
{
@@ -22880,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
@@ -22898,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));
}
}
@@ -25454,8 +25447,8 @@ arm_expand_compare_and_swap (rtx operands[])
case SImode:
/* Force the value into a register if needed. We waited until after
the zero-extension above to do this properly. */
- if (!arm_add_operand (oldval, mode))
- oldval = force_reg (mode, oldval);
+ if (!arm_add_operand (oldval, SImode))
+ oldval = force_reg (SImode, oldval);
break;
case DImode:
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 5f34f2a8100..4ac5de70862 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
@@ -325,7 +328,7 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
#define TARGET_UNIFIED_ASM TARGET_THUMB2
/* Nonzero if this chip provides the DMB instruction. */
-#define TARGET_HAVE_DMB (arm_arch7)
+#define TARGET_HAVE_DMB (arm_arch6m || arm_arch7)
/* Nonzero if this chip implements a memory barrier via CP15. */
#define TARGET_HAVE_DMB_MCR (arm_arch6 && ! TARGET_HAVE_DMB \
@@ -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. */
@@ -470,6 +475,9 @@ extern int arm_arch6;
/* Nonzero if this chip supports the ARM Architecture 6k extensions. */
extern int arm_arch6k;
+/* Nonzero if instructions present in ARMv6-M can be used. */
+extern int arm_arch6m;
+
/* Nonzero if this chip supports the ARM Architecture 7 extensions. */
extern int arm_arch7;
@@ -479,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 43a9f1fef3f..7c80f91fb94 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")]
)
@@ -11355,6 +11355,16 @@
(set_attr "length" "4")]
)
+;; For thread pointer builtin
+(define_expand "get_thread_pointersi"
+ [(match_operand:SI 0 "s_register_operand" "=r")]
+ ""
+ "
+ {
+ arm_load_tp (operands[0]);
+ DONE;
+ }")
+
;;
;; We only care about the lower 16 bits of the constant
diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h
index b486d57be9c..8fec83f287d 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 f6d1a3df72c..67e17a1b08f 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 00000000000..afb67a58752
--- /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 ccab7cbe906..b86c6e70690 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 23e37b49809..043b1e06a2a 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 29679aaca0f..6c4e2726af0 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 a69a53917b1..4645f390150 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 b89d5383a93..92e03b09760 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 56869c03c40..101f8f654fe 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 57d1539ee3d..a5302f479f5 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 b28bec9b86b..a2a1a51c271 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 6eb0ebaed5a..6e7f8c7119f 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 1c5bab2baf0..9ae52663668 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 1774d3adff6..63ad1755020 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 99f02d5dc98..e612ef68293 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 83da2932512..46f20b15e40 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 2d8ad40c07a..1a8c0fba13d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16067,7 +16067,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))
@@ -16076,39 +16077,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
@@ -16203,7 +16217,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)
{
@@ -16215,7 +16229,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;
}
@@ -16253,7 +16267,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;
}
@@ -16278,7 +16292,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)
{
@@ -16287,7 +16301,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);
@@ -16307,7 +16321,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
{
@@ -26762,8 +26776,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 */
@@ -26773,9 +26787,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 },
@@ -26789,14 +26803,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 },
@@ -26821,12 +26835,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 },
@@ -26881,7 +26895,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 },
@@ -30446,7 +30460,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);
@@ -30627,6 +30641,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 2e709526eab..16db3ca1056 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 fa10cb4a427..299115d4ac4 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 a73c815eb56..299b0d936d7 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 aa5e78636ea..f84f1ad6332 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 130acc9b384..5d91c037d7e 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 acbc6627f95..e74e261d780 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 773a9a0aa14..35b6e1490bc 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/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 708d6bb9402..f2c5c0d1823 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -351,6 +351,8 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx));
extern void mips_expand_vec_minmax (rtx, rtx, rtx,
rtx (*) (rtx, rtx, rtx), bool);
+extern rtx mips_expand_thread_pointer (rtx);
+
extern bool mips_eh_uses (unsigned int);
extern bool mips_epilogue_uses (unsigned int);
extern void mips_final_prescan_insn (rtx, rtx *, int);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 4073a15d05d..bbd0fc429dc 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2884,12 +2884,11 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
/* Return a pseudo register that contains the current thread pointer. */
-static rtx
-mips_get_tp (void)
+rtx
+mips_expand_thread_pointer (rtx tp)
{
- rtx tp, fn;
+ rtx fn;
- tp = gen_reg_rtx (Pmode);
if (TARGET_MIPS16)
{
mips_need_mips16_rdhwr_p = true;
@@ -2904,6 +2903,12 @@ mips_get_tp (void)
return tp;
}
+static rtx
+mips_get_tp (void)
+{
+ return mips_expand_thread_pointer (gen_reg_rtx (Pmode));
+}
+
/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
its address. The return value will be both a valid address and a valid
SET_SRC (either a REG or a LO_SUM). */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 570e7851096..c7dd87512ee 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -6880,6 +6880,16 @@
[(set_attr "type" "call")
(set_attr "length" "12")
(set_attr "mode" "<MODE>")])
+
+;; Named pattern for expanding thread pointer reference.
+(define_expand "get_thread_pointer<mode>"
+ [(match_operand:P 0 "register_operand" "=d")]
+ "HAVE_AS_TLS"
+{
+ mips_expand_thread_pointer (operands[0]);
+ DONE;
+})
+
;; Synchronization instructions.
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 26668e76da8..1ce88001277 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -392,15 +392,33 @@ mmix_conditional_register_usage (void)
/* INCOMING_REGNO and OUTGOING_REGNO worker function.
Those two macros must only be applied to function argument
- registers. FIXME: for their current use in gcc, it'd be better
- with an explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P
- a'la TARGET_FUNCTION_ARG / TARGET_FUNCTION_INCOMING_ARG instead of
+ registers and the function return value register for the opposite
+ use. FIXME: for their current use in gcc, it'd be better with an
+ explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P a'la
+ TARGET_FUNCTION_ARG / TARGET_FUNCTION_INCOMING_ARG instead of
forcing the target to commit to a fixed mapping and for any
- unspecified register use. */
+ unspecified register use. Particularly when thinking about the
+ return-value, it is better to imagine INCOMING_REGNO and
+ OUTGOING_REGNO as named CALLEE_TO_CALLER_REGNO and INNER_REGNO as
+ named CALLER_TO_CALLEE_REGNO because the direction. The "incoming"
+ and "outgoing" is from the perspective of the parameter-registers,
+ but the same macro is (must be, lacking an alternative like
+ suggested above) used to map the return-value-register from the
+ same perspective. To make directions even more confusing, the macro
+ MMIX_OUTGOING_RETURN_VALUE_REGNUM holds the number of the register
+ in which to return a value, i.e. INCOMING_REGNO for the return-value-
+ register as received from a called function; the return-value on the
+ way out. */
int
mmix_opposite_regno (int regno, int incoming)
{
+ if (incoming && regno == MMIX_OUTGOING_RETURN_VALUE_REGNUM)
+ return MMIX_RETURN_VALUE_REGNUM;
+
+ if (!incoming && regno == MMIX_RETURN_VALUE_REGNUM)
+ return MMIX_OUTGOING_RETURN_VALUE_REGNUM;
+
if (!mmix_function_arg_regno_p (regno, incoming))
return regno;
diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h
index 8ff211107ec..091a462d194 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 d62d3fb5d90..099c4dfd8ce 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 02b966d1f5b..a37ce622d4b 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 870eb0618d4..7faba731846 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 f0a09e6c514..8de6fee3fd9 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 9a10b200e81..2dabd809806 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 8c168c85daf..7ca496f937a 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 3787511b660..2abba3482f7 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 50c6697a768..ee447195f2d 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 d434ace28f3..69e150705bd 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 336727428bc..02477df7199 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 8c32301a71d..28ba8f8f6a8 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 0ecbe75c0cf..aaa9b3dde46 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 12b75275a32..fc20a5e5761 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -490,7 +490,6 @@
(match_test "op == CONST0_RTX (mode)")))
;; Return 1 if operand is 0.0.
-;; or non-special register register field no cr0
(define_predicate "zero_fp_constant"
(and (match_code "const_double")
(match_test "SCALAR_FLOAT_MODE_P (mode)
@@ -941,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 4c265665ce0..295015f6fd0 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 cfac0e732e0..fd43146495d 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 ced06508e87..81dc6f32daa 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;
}
@@ -6751,7 +6727,7 @@ rs6000_emit_set_const (rtx dest, enum machine_mode mode,
switch (mode)
{
- case QImode:
+ case QImode:
case HImode:
if (dest == NULL)
dest = gen_reg_rtx (mode);
@@ -14990,11 +14966,10 @@ print_operand (FILE *file, rtx x, int code)
return;
case 'Q':
- if (TARGET_MFCRF)
- fputc (',', file);
- /* FALLTHRU */
- else
+ if (! TARGET_MFCRF)
return;
+ fputc (',', file);
+ /* FALLTHRU */
case 'R':
/* X is a CR register. Print the mask for `mtcrf'. */
@@ -15939,7 +15914,7 @@ rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
}
/* Return the string to output a conditional branch to LABEL, which is
- the operand number of the label, or -1 if the branch is really a
+ the operand template of the label, or NULL if the branch is really a
conditional return.
OP is the conditional expression. XEXP (OP, 0) is assumed to be a
@@ -25331,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);
@@ -27432,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. */
@@ -27584,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;
}
@@ -27852,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))
{
@@ -27962,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 */
@@ -27970,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);
}
@@ -27981,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. */
@@ -28094,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 b968802d9fb..d299e631370 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
@@ -2229,8 +2287,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
/* Define which CODE values are valid. */
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
- ((CODE) == '.' || (CODE) == '&')
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '&')
/* Print a memory address as an operand to reference that memory location. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4265cb67b0f..2625bd72c07 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -266,7 +266,7 @@
; Conditional returns.
(define_code_iterator any_return [return simple_return])
(define_code_attr return_pred [(return "direct_return ()")
- (simple_return "")])
+ (simple_return "1")])
(define_code_attr return_str [(return "") (simple_return "simple_")])
; Various instructions that come in SI and DI forms.
@@ -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 58b7694382c..0f38e179200 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 ab60cbcd483..42ac90373e5 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 978ba31ab6b..70a5908fbea 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 474203d6adb..60ca4fd8615 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 a96c0d2a74c..6135f52aefe 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.c b/gcc/config/s390/s390.c
index a9a1af5e516..4ce1dc9542c 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9294,132 +9294,6 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
return build_va_arg_indirect_ref (addr);
}
-
-/* Builtins. */
-
-enum s390_builtin
-{
- S390_BUILTIN_THREAD_POINTER,
- S390_BUILTIN_SET_THREAD_POINTER,
-
- S390_BUILTIN_max
-};
-
-static enum insn_code const code_for_builtin_64[S390_BUILTIN_max] = {
- CODE_FOR_get_tp_64,
- CODE_FOR_set_tp_64
-};
-
-static enum insn_code const code_for_builtin_31[S390_BUILTIN_max] = {
- CODE_FOR_get_tp_31,
- CODE_FOR_set_tp_31
-};
-
-static void
-s390_init_builtins (void)
-{
- tree ftype;
-
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- add_builtin_function ("__builtin_thread_pointer", ftype,
- S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
-
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- add_builtin_function ("__builtin_set_thread_pointer", ftype,
- S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
-}
-
-/* Expand an expression EXP that calls a built-in function,
- with result going to TARGET if that's convenient
- (and in mode MODE if that's convenient).
- SUBTARGET may be used as the target for computing one of EXP's operands.
- IGNORE is nonzero if the value is to be ignored. */
-
-static rtx
-s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
-{
-#define MAX_ARGS 2
-
- enum insn_code const *code_for_builtin =
- TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
-
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
- enum insn_code icode;
- rtx op[MAX_ARGS], pat;
- int arity;
- bool nonvoid;
- tree arg;
- call_expr_arg_iterator iter;
-
- if (fcode >= S390_BUILTIN_max)
- internal_error ("bad builtin fcode");
- icode = code_for_builtin[fcode];
- if (icode == 0)
- internal_error ("bad builtin fcode");
-
- nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
-
- arity = 0;
- FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
- {
- const struct insn_operand_data *insn_op;
-
- if (arg == error_mark_node)
- return NULL_RTX;
- if (arity > MAX_ARGS)
- return NULL_RTX;
-
- insn_op = &insn_data[icode].operand[arity + nonvoid];
-
- op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
-
- if (!(*insn_op->predicate) (op[arity], insn_op->mode))
- op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
- arity++;
- }
-
- if (nonvoid)
- {
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- if (!target
- || GET_MODE (target) != tmode
- || !(*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
- }
-
- switch (arity)
- {
- case 0:
- pat = GEN_FCN (icode) (target);
- break;
- case 1:
- if (nonvoid)
- pat = GEN_FCN (icode) (target, op[0]);
- else
- pat = GEN_FCN (icode) (op[0]);
- break;
- case 2:
- pat = GEN_FCN (icode) (target, op[0], op[1]);
- break;
- default:
- gcc_unreachable ();
- }
- if (!pat)
- return NULL_RTX;
- emit_insn (pat);
-
- if (nonvoid)
- return target;
- else
- return const0_rtx;
-}
-
-
/* Output assembly code for the trampoline template to
stdio stream FILE.
@@ -11075,11 +10949,6 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS s390_init_builtins
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN s390_expand_builtin
-
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 439d78ce4c8..9279a9876c4 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)
@@ -8710,26 +8711,15 @@
;;- Thread-local storage support.
;;
-(define_expand "get_tp_64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))]
- "TARGET_64BIT"
- "")
-
-(define_expand "get_tp_31"
- [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))]
- "!TARGET_64BIT"
- "")
-
-(define_expand "set_tp_64"
- [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" ""))
- (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))]
- "TARGET_64BIT"
+(define_expand "get_thread_pointer<mode>"
+ [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
+ ""
"")
-(define_expand "set_tp_31"
- [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" ""))
- (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))]
- "!TARGET_64BIT"
+(define_expand "set_thread_pointer<mode>"
+ [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
+ (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
+ ""
"")
(define_insn "*set_tp"
diff --git a/gcc/config/sh/iterators.md b/gcc/config/sh/iterators.md
index ec95013b2c3..e118c3ef1cd 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 89b4d0fc5a3..83508e895ae 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -345,8 +345,10 @@
&& GET_MODE (op) == PSImode);
})
-;; TODO: Add a comment here.
-
+;; Returns true if OP is an operand that is either the fpul hard reg or
+;; a pseudo. This prevents combine from propagating function arguments
+;; in hard regs into insns that need the operand in fpul. If it's a pseudo
+;; reload can fix it up.
(define_predicate "fpul_operand"
(match_code "reg")
{
@@ -358,6 +360,29 @@
&& GET_MODE (op) == mode);
})
+;; Returns true if OP is a valid fpul input operand for the fsca insn.
+;; The value in fpul is a fixed-point value and its scaling is described
+;; in the fsca insn by a mult:SF. To allow pre-scaled fixed-point inputs
+;; in fpul we have to permit things like
+;; (reg:SI)
+;; (fix:SF (float:SF (reg:SI)))
+(define_predicate "fpul_fsca_operand"
+ (match_code "fix,reg")
+{
+ if (fpul_operand (op, SImode))
+ return true;
+ if (GET_CODE (op) == FIX && GET_MODE (op) == SImode
+ && GET_CODE (XEXP (op, 0)) == FLOAT && GET_MODE (XEXP (op, 0)) == SFmode)
+ return fpul_fsca_operand (XEXP (XEXP (op, 0), 0),
+ GET_MODE (XEXP (XEXP (op, 0), 0)));
+ return false;
+})
+
+;; Returns true if OP is a valid constant scale factor for the fsca insn.
+(define_predicate "fsca_scale_factor"
+ (and (match_code "const_double")
+ (match_test "op == sh_fsca_int2sf ()")))
+
;; TODO: Add a comment here.
(define_predicate "general_extend_operand"
@@ -1048,6 +1073,14 @@
}
})
+;; A predicate that returns true if OP is a valid construct around the T bit
+;; that can be used as an operand for conditional branches.
+(define_predicate "cbranch_treg_value"
+ (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
+{
+ return sh_eval_treg_value (op) >= 0;
+})
+
;; Returns true of OP is arith_reg_operand or t_reg_operand.
(define_predicate "arith_reg_or_t_reg_operand"
(ior (match_operand 0 "arith_reg_operand")
@@ -1106,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 61d4eabfde9..d4e97db8902 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -162,6 +162,26 @@ extern bool sh_cfun_trap_exit_p (void);
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 d1ab28afd81..4d65685a857 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -2059,7 +2059,7 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
void
expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
{
- rtx (*branch_expander) (rtx, rtx) = gen_branch_true;
+ rtx (*branch_expander) (rtx) = gen_branch_true;
comparison = prepare_cbranch_operands (operands, SImode, comparison);
switch (comparison)
{
@@ -2071,7 +2071,7 @@ expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
emit_insn (gen_rtx_SET (VOIDmode, get_t_reg_rtx (),
gen_rtx_fmt_ee (comparison, SImode,
operands[1], operands[2])));
- rtx jump = emit_jump_insn (branch_expander (operands[3], get_t_reg_rtx ()));
+ rtx jump = emit_jump_insn (branch_expander (operands[3]));
if (probability >= 0)
add_reg_note (jump, REG_BR_PROB, GEN_INT (probability));
}
@@ -2123,7 +2123,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
if (TARGET_CMPEQDI_T)
{
emit_insn (gen_cmpeqdi_t (operands[1], operands[2]));
- emit_jump_insn (gen_branch_true (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (operands[3]));
return true;
}
msw_skip = NE;
@@ -2150,7 +2150,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
if (TARGET_CMPEQDI_T)
{
emit_insn (gen_cmpeqdi_t (operands[1], operands[2]));
- emit_jump_insn (gen_branch_false (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_false (operands[3]));
return true;
}
msw_taken = NE;
@@ -2281,6 +2281,43 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
return true;
}
+/* Given an operand, return 1 if the evaluated operand plugged into an
+ if_then_else will result in a branch_true, 0 if branch_false, or
+ -1 if neither nor applies. The truth table goes like this:
+
+ op | cmpval | code | result
+ ---------+--------+---------+--------------------
+ T (0) | 0 | EQ (1) | 0 = 0 ^ (0 == 1)
+ T (0) | 1 | EQ (1) | 1 = 0 ^ (1 == 1)
+ T (0) | 0 | NE (0) | 1 = 0 ^ (0 == 0)
+ T (0) | 1 | NE (0) | 0 = 0 ^ (1 == 0)
+ !T (1) | 0 | EQ (1) | 1 = 1 ^ (0 == 1)
+ !T (1) | 1 | EQ (1) | 0 = 1 ^ (1 == 1)
+ !T (1) | 0 | NE (0) | 0 = 1 ^ (0 == 0)
+ !T (1) | 1 | NE (0) | 1 = 1 ^ (1 == 0) */
+int
+sh_eval_treg_value (rtx op)
+{
+ enum rtx_code code = GET_CODE (op);
+ if ((code != EQ && code != NE) || !CONST_INT_P (XEXP (op, 1)))
+ return -1;
+
+ int cmpop = code == EQ ? 1 : 0;
+ int cmpval = INTVAL (XEXP (op, 1));
+ if (cmpval != 0 && cmpval != 1)
+ return -1;
+
+ int t;
+ if (t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))))
+ t = 0;
+ else if (negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))))
+ t = 1;
+ else
+ return -1;
+
+ return t ^ (cmpval == cmpop);
+}
+
/* Emit INSN, possibly in a PARALLEL with an USE of fpscr for SH4. */
static void
@@ -2485,9 +2522,9 @@ sh_emit_compare_and_branch (rtx *operands, enum machine_mode mode)
sh_emit_set_t_insn (gen_ieee_ccmpeqsf_t (op0, op1), mode);
if (branch_code == code)
- emit_jump_insn (gen_branch_true (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (operands[3]));
else
- emit_jump_insn (gen_branch_false (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_false (operands[3]));
}
void
@@ -2521,7 +2558,7 @@ sh_emit_compare_and_set (rtx *operands, enum machine_mode mode)
{
lab = gen_label_rtx ();
sh_emit_scc_to_t (EQ, op0, op1);
- emit_jump_insn (gen_branch_true (lab, get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (lab));
code = GT;
}
else
@@ -9414,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 above, but don't save all registers.
+ * trapa_handler
+ Like interrupt_handler, 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
- an rte instruction.
+ * trap_exit
+ Use a trapa to exit an interrupt function instead of rte.
- 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.
+ * 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).
- renesas -- use Renesas calling/layout conventions (functions and
- structures).
+ * renesas
+ Use Renesas calling/layout conventions (functions and structures).
- 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.
+ * 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.
+
+ * 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. */
@@ -10762,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)))
@@ -11778,12 +11822,6 @@ static struct builtin_description bdesc[] =
CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2, 0 },
{ shmedia_builtin_p,
CODE_FOR_prefetch, "__builtin_sh_media_PREFO", SH_BLTIN_PSSV, 0 },
-
- { sh1_builtin_p,
- CODE_FOR_get_thread_pointer, "__builtin_thread_pointer", SH_BLTIN_VP, 0 },
- { sh1_builtin_p,
- CODE_FOR_set_thread_pointer, "__builtin_set_thread_pointer",
- SH_BLTIN_PV, 0 },
};
static void
@@ -12628,11 +12666,9 @@ check_use_sfunc_addr (rtx insn, rtx reg)
gcc_unreachable ();
}
-/* This function returns a constant rtx that represents pi / 2**15 in
- SFmode. it's used to scale SFmode angles, in radians, to a
- fixed-point signed 16.16-bit fraction of a full circle, i.e., 2*pi
- maps to 0x10000). */
-
+/* This function returns a constant rtx that represents 2**15 / pi in
+ SFmode. It's used to scale a fixed-point signed 16.16-bit fraction
+ of a full circle back to an SFmode value, i.e. 0x10000 maps to 2*pi. */
static GTY(()) rtx sh_fsca_sf2int_rtx;
rtx
@@ -12649,11 +12685,10 @@ sh_fsca_sf2int (void)
return sh_fsca_sf2int_rtx;
}
-/* This function returns a constant rtx that represents 2**15 / pi in
- SFmode. it's used to scale a fixed-point signed 16.16-bit fraction
- of a full circle back to a SFmode value, i.e., 0x10000 maps to
- 2*pi). */
-
+/* This function returns a constant rtx that represents pi / 2**15 in
+ SFmode. It's used to scale SFmode angles, in radians, to a
+ fixed-point signed 16.16-bit fraction of a full circle, i.e. 2*pi
+ maps to 0x10000. */
static GTY(()) rtx sh_fsca_int2sf_rtx;
rtx
@@ -13355,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;
@@ -13422,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 a0b1e8891f8..2ef4a1a4ee0 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -541,22 +541,22 @@
(eq_attr "needs_delay_slot" "yes")
[(eq_attr "in_delay_slot" "yes") (nil) (nil)])
-;; On the SH and SH2, the rte instruction reads the return pc from the stack,
-;; and thus we can't put a pop instruction in its delay slot.
-;; On the SH3 and SH4, the rte instruction does not use the stack, so a pop
-;; instruction can go in the delay slot.
;; Since a normal return (rts) implicitly uses the PR register,
;; we can't allow PR register loads in an rts delay slot.
+;; On the SH1* and SH2*, the rte instruction reads the return pc from the
+;; stack, and thus we can't put a pop instruction in its delay slot.
+;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
+;; pop instruction can go in the delay slot, unless it references a banked
+;; register (the register bank is switched by rte).
(define_delay
(eq_attr "type" "return")
[(and (eq_attr "in_delay_slot" "yes")
(ior (and (eq_attr "interrupt_function" "no")
(eq_attr "type" "!pload,prset"))
(and (eq_attr "interrupt_function" "yes")
- (ior
- (not (match_test "TARGET_SH3"))
- (eq_attr "hit_stack" "no")
- (eq_attr "banked" "no"))))) (nil) (nil)])
+ (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
+ (eq_attr "banked" "no"))))
+ (nil) (nil)])
;; Since a call implicitly uses the PR register, we can't allow
;; a PR register store in a jsr delay slot.
@@ -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")
@@ -5322,8 +5342,8 @@ label:
emit_insn (gen_movsi (operands[0], operands[1]));
emit_jump_insn (INTVAL (operands[3])
- ? gen_branch_true (skip_neg_label, get_t_reg_rtx ())
- : gen_branch_false (skip_neg_label, get_t_reg_rtx ()));
+ ? gen_branch_true (skip_neg_label)
+ : gen_branch_false (skip_neg_label));
emit_label_after (skip_neg_label,
emit_insn (gen_negsi2 (operands[0], operands[1])));
@@ -5391,8 +5411,8 @@ label:
emit_insn (gen_movsi (high_dst, high_src));
emit_jump_insn (INTVAL (operands[3])
- ? gen_branch_true (skip_neg_label, get_t_reg_rtx ())
- : gen_branch_false (skip_neg_label, get_t_reg_rtx ()));
+ ? gen_branch_true (skip_neg_label)
+ : gen_branch_false (skip_neg_label));
if (!INTVAL (operands[3]))
emit_insn (gen_clrt ());
@@ -5575,11 +5595,25 @@ label:
[(set (match_operand:SI 0 "arith_reg_dest")
(zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
-(define_insn "*zero_extend<mode>si2_compact"
+(define_insn_and_split "*zero_extend<mode>si2_compact"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"extu.<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 zero 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 zero extension with a reg move, which will be
+ 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. */
+ operands[2] = sh_try_omit_signzero_extend (operands[1], curr_insn);
+ if (operands[2] == NULL_RTX)
+ FAIL;
+}
[(set_attr "type" "arith")])
(define_insn "*zero_extendhisi2_media"
@@ -5804,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.
@@ -6186,21 +6232,6 @@ label:
emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
})
-;; Define additional pop for SH1 and SH2 so it does not get
-;; placed in the delay slot.
-(define_insn "*movsi_pop"
- [(set (match_operand:SI 0 "register_operand" "=r,x,l")
- (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
- "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
- && ! TARGET_SH3"
- "@
- mov.l %1,%0
- lds.l %1,%0
- lds.l %1,%0"
- [(set_attr "type" "load_si,mem_mac,pload")
- (set_attr "length" "2,2,2")
- (set_attr "in_delay_slot" "no,no,no")])
-
;; t/r must come after r/r, lest reload will try to reload stuff like
;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
@@ -6598,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")])
@@ -8108,47 +8148,105 @@ label:
;; Define the real conditional branch instructions.
;; ------------------------------------------------------------------------
-(define_insn "branch_true"
- [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "")
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "branch_true"
+ [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
+ (label_ref (match_operand 0))
(pc)))]
- "TARGET_SH1"
-{
- return output_branch (1, insn, operands);
-}
- [(set_attr "type" "cbranch")])
+ "TARGET_SH1")
-(define_insn "*branch_true_eq"
- [(set (pc) (if_then_else (eq (match_operand 1 "t_reg_operand" "")
- (const_int 1))
- (label_ref (match_operand 0 "" ""))
+(define_expand "branch_false"
+ [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
+ (label_ref (match_operand 0))
(pc)))]
- "TARGET_SH1"
-{
- return output_branch (1, insn, operands);
-}
- [(set_attr "type" "cbranch")])
+ "TARGET_SH1")
-(define_insn "branch_false"
- [(set (pc) (if_then_else (eq (match_operand 1 "t_reg_operand" "")
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_insn_and_split "*cbranch_t"
+ [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
+ (label_ref (match_operand 0))
(pc)))]
"TARGET_SH1"
{
- return output_branch (0, insn, operands);
+ return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
}
- [(set_attr "type" "cbranch")])
-
-(define_insn "*branch_false_ne"
- [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "")
- (const_int 1))
- (label_ref (match_operand 0 "" ""))
+ "&& can_create_pseudo_p ()"
+ [(set (pc) (if_then_else (eq (reg:SI T_REG) (match_dup 2))
+ (label_ref (match_dup 0))
(pc)))]
- "TARGET_SH1"
{
- return output_branch (0, insn, operands);
+ /* Try to find missed test and branch combine opportunities which result
+ in redundant T bit tests before conditional branches.
+ FIXME: Probably this would not be needed if CCmode was used
+ together with TARGET_FIXED_CONDITION_CODE_REGS. */
+
+ const int treg_value = sh_eval_treg_value (operands[1]);
+ operands[2] = NULL_RTX;
+
+ /* Scan the insns backwards for an insn that sets the T bit by testing a
+ reg against zero like:
+ (set (reg T_REG) (eq (reg) (const_int 0))) */
+ rtx testing_insn = NULL_RTX;
+ rtx tested_reg = NULL_RTX;
+
+ 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)))
+ {
+ testing_insn = s0.insn;
+ tested_reg = XEXP (s0.set_src, 0);
+ }
+ else
+ FAIL;
+
+ /* Continue scanning the insns backwards and try to find the insn that
+ sets the tested reg which we found above. If the reg is set by storing
+ the T bit or the negated T bit we can eliminate the test insn before
+ the branch. Notice that the branch condition has to be inverted if the
+ test is eliminated. */
+
+ /* If the T bit is used between the testing insn and the brach insn
+ leave it alone. */
+ if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
+ FAIL;
+
+ while (true)
+ {
+ 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 (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))
+ {
+ /* 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 (), s1.insn, testing_insn)
+ || modified_in_p (get_t_reg_rtx (), s1.insn))
+ operands[2] = NULL_RTX;
+
+ break;
+ }
+
+ if (operands[2] == NULL_RTX)
+ FAIL;
+
+ set_insn_deleted (testing_insn);
}
[(set_attr "type" "cbranch")])
@@ -8376,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"
@@ -10085,7 +10186,7 @@ label:
;;
;; On SH the thread pointer is kept in the GBR.
;; These patterns are usually expanded from the respective built-in functions.
-(define_expand "get_thread_pointer"
+(define_expand "get_thread_pointersi"
[(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
"TARGET_SH1")
@@ -10096,7 +10197,7 @@ label:
"stc gbr,%0"
[(set_attr "type" "tls_load")])
-(define_expand "set_thread_pointer"
+(define_expand "set_thread_pointersi"
[(set (reg:SI GBR_REG)
(unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
UNSPECV_GBR))]
@@ -10167,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
@@ -10177,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;
})
@@ -10199,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;
})
@@ -10218,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;
})
@@ -10960,25 +11101,53 @@ label:
(set (reg:SI T_REG) (const_int 1))
(use (match_dup 2))])])
-;; In some cases the zero extension does not get combined away and a
-;; sequence like the following might remain:
-;; mov #-1,r2
-;; tst r1,r1
-;; negc r2,r1
-;; extu.b r1,r1
-(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "arith_reg_dest" "")
- (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
- (set (reg:SI T_REG) (const_int 1))
- (use (match_operand:SI 2 "arith_reg_operand" ""))])
- (set (match_dup 0)
- (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
- "TARGET_SH1 && REGNO (operands[0]) == REGNO (operands[3])"
- [(parallel
- [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
- (set (reg:SI T_REG) (const_int 1))
- (use (match_dup 2))])])
+;; Store the negated T bit in a reg using r0 and xor. This one doesn't
+;; clobber the T bit, which is useful when storing the T bit and the
+;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
+;; Usually we don't want this insn to be matched, except for cases where the
+;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
+(define_insn_and_split "movrt_xor"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=z")
+ (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
+ (use (reg:SI T_REG))]
+ "TARGET_SH1 && !TARGET_SH2A"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (reg:SI T_REG))
+ (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
+
+;; Store the T bit and the negated T bit in two regs in parallel. There is
+;; no real insn to do that, but specifying this pattern will give combine
+;; some opportunities.
+(define_insn_and_split "*movt_movrt"
+ [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
+ (match_operand:SI 1 "negt_reg_operand"))
+ (set (match_operand:SI 2 "arith_reg_dest")
+ (match_operand:SI 3 "t_reg_operand"))])]
+ "TARGET_SH1"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ rtx i = TARGET_SH2A
+ ? gen_movrt (operands[0], get_t_reg_rtx ())
+ : gen_movrt_xor (operands[0], get_t_reg_rtx ());
+
+ emit_insn (i);
+ emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
+ DONE;
+})
+
+(define_insn_and_split "*movt_movrt"
+ [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
+ (match_operand:SI 1 "t_reg_operand"))
+ (set (match_operand:SI 2 "arith_reg_dest")
+ (match_operand:SI 3 "negt_reg_operand"))])]
+ "TARGET_SH1"
+ "#"
+ "&& 1"
+ [(parallel [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_dup 1))])])
;; Use negc to store the T bit in a MSB of a reg in the following way:
;; T = 1: 0x80000000 -> reg
@@ -12055,22 +12224,6 @@ label:
[(set_attr "type" "fsrra")
(set_attr "fp_mode" "single")])
-(define_insn "fsca"
- [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
- (vec_concat:V2SF
- (unspec:SF [(mult:SF
- (float:SF (match_operand:SI 1 "fpul_operand" "y"))
- (match_operand:SF 2 "immediate_operand" "i"))
- ] UNSPEC_FSINA)
- (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
- ] UNSPEC_FCOSA)))
- (use (match_operand:PSI 3 "fpscr_operand" "c"))]
- "TARGET_FPU_ANY && TARGET_FSCA
- && operands[2] == sh_fsca_int2sf ()"
- "fsca fpul,%d0"
- [(set_attr "type" "fsca")
- (set_attr "fp_mode" "single")])
-
;; When the sincos pattern is defined, the builtin functions sin and cos
;; will be expanded to the sincos pattern and one of the output values will
;; remain unused.
@@ -12097,6 +12250,38 @@ label:
DONE;
})
+(define_insn_and_split "fsca"
+ [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
+ (vec_concat:V2SF
+ (unspec:SF [(mult:SF
+ (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
+ (match_operand:SF 2 "fsca_scale_factor" "i"))
+ ] UNSPEC_FSINA)
+ (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
+ ] UNSPEC_FCOSA)))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
+ "TARGET_FPU_ANY && TARGET_FSCA"
+ "fsca fpul,%d0"
+ "&& !fpul_operand (operands[1], SImode)"
+ [(const_int 0)]
+{
+ /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
+ to a simple reg, otherwise reload will have trouble reloading the
+ pseudo into fpul. */
+ rtx x = XEXP (operands[1], 0);
+ while (x != NULL_RTX && !fpul_operand (x, SImode))
+ {
+ gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
+ x = XEXP (x, 0);
+ }
+
+ gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
+ emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
+ DONE;
+}
+ [(set_attr "type" "fsca")
+ (set_attr "fp_mode" "single")])
+
(define_expand "abssf2"
[(set (match_operand:SF 0 "fp_arith_reg_operand" "")
(abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
@@ -15165,7 +15350,7 @@ label:
else
{
emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
- emit_jump_insn (gen_branch_true (operands[2], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (operands[2]));
}
DONE;
diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md
index ee5fced6665..3446e986f27 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 92a6d651eda..b5dc9c8844f 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 9d5d44e85ed..1d1838e6de8 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/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 83eab4b9e7a..451a074da2a 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -1899,7 +1899,7 @@ xtensa_legitimize_tls_address (rtx x)
case TLS_MODEL_INITIAL_EXEC:
case TLS_MODEL_LOCAL_EXEC:
tp = gen_reg_rtx (SImode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointersi (tp));
addend = force_reg (SImode, gen_sym_TPOFF (x));
emit_insn (gen_addsi3 (dest, tp, addend));
break;
@@ -3076,8 +3076,6 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
enum xtensa_builtin
{
XTENSA_BUILTIN_UMULSIDI3,
- XTENSA_BUILTIN_THREAD_POINTER,
- XTENSA_BUILTIN_SET_THREAD_POINTER,
XTENSA_BUILTIN_max
};
@@ -3096,23 +3094,6 @@ xtensa_init_builtins (void)
"__umulsidi3", NULL_TREE);
TREE_NOTHROW (decl) = 1;
TREE_READONLY (decl) = 1;
-
- if (TARGET_THREADPTR)
- {
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_READONLY (decl) = 1;
- TREE_NOTHROW (decl) = 1;
-
- ftype = build_function_type_list (void_type_node, ptr_type_node,
- NULL_TREE);
- decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
- XTENSA_BUILTIN_SET_THREAD_POINTER,
- BUILT_IN_MD, NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- }
}
@@ -3135,10 +3116,6 @@ xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
fold_convert (unsigned_intDI_type_node, arg1));
break;
- case XTENSA_BUILTIN_THREAD_POINTER:
- case XTENSA_BUILTIN_SET_THREAD_POINTER:
- break;
-
default:
internal_error ("bad builtin code");
break;
@@ -3166,19 +3143,6 @@ xtensa_expand_builtin (tree exp, rtx target,
implement it. If not, just call the function. */
return expand_call (exp, target, ignore);
- case XTENSA_BUILTIN_THREAD_POINTER:
- if (!target || !register_operand (target, Pmode))
- target = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (target));
- return target;
-
- case XTENSA_BUILTIN_SET_THREAD_POINTER:
- arg = expand_normal (CALL_EXPR_ARG (exp, 0));
- if (!register_operand (arg, Pmode))
- arg = copy_to_mode_reg (Pmode, arg);
- emit_insn (gen_set_tp (arg));
- return const0_rtx;
-
default:
internal_error ("bad builtin code");
}
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index d6eb54891b8..b87f08988ea 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1714,7 +1714,7 @@
""
"")
-(define_insn "load_tp"
+(define_insn "get_thread_pointersi"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"TARGET_THREADPTR"
@@ -1723,7 +1723,7 @@
(set_attr "mode" "SI")
(set_attr "length" "3")])
-(define_insn "set_tp"
+(define_insn "set_thread_pointersi"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
UNSPECV_SET_TP)]
"TARGET_THREADPTR"
diff --git a/gcc/configure b/gcc/configure
index 45bba8e785e..a223c600d9a 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -21237,11 +21237,15 @@ for f in $gcc_cv_as_bfd_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure.in \
$gcc_cv_as_gas_srcdir/Makefile.in ; do
- gcc_cv_gas_version=`sed -n -e 's/^[ ]*\(VERSION=[0-9]*\.[0-9]*.*\)/\1/p' < $f`
+ gcc_cv_gas_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gas_version != x; then
break
fi
done
+case $gcc_cv_gas_version in
+ VERSION=[0-9]*) ;;
+ *) as_fn_error "cannot find version of in-tree assembler" "$LINENO" 5;;
+esac
gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.[0-9]*\.\([0-9]*\)"`
@@ -21395,11 +21399,15 @@ $as_echo "newly built ld" >&6; }
fi
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
do
- gcc_cv_gld_version=`sed -n -e 's/^[ ]*\(VERSION=[0-9]*\.[0-9]*.*\)/\1/p' < $f`
+ gcc_cv_gld_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gld_version != x; then
break
fi
done
+ case $gcc_cv_gld_version in
+ VERSION=[0-9]*) ;;
+ *) as_fn_error "cannot find version of in-tree linker" "$LINENO" 5 ;;
+ esac
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
else
@@ -22063,6 +22071,12 @@ else
if test x"$ld_is_gold" = xyes; then
:
elif echo "$ld_ver" | grep GNU > /dev/null; then
+ case "${target}" in
+ mmix-knuth-mmixware)
+ # The linker emits by default mmo, not ELF, so "no" is appropriate.
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
if test 0"$ld_date" -lt 20020404; then
if test -n "$ld_date"; then
# If there was date string, but was earlier than 2002-04-04, fail
@@ -22820,6 +22834,9 @@ $as_echo "$gcc_cv_as_comdat_group_percent" >&6; }
if test $gcc_cv_as_comdat_group_percent = yes; then
gcc_cv_as_comdat_group_group=no
else
+ if test -z "${gcc_cv_as_comdat_group_group+set}"; then
+ gcc_cv_as_comdat_group_group=no
+ fi
case "${target}" in
# Sun as uses a completely different syntax.
*-*-solaris2*)
@@ -25346,8 +25363,8 @@ if test "${gcc_cv_as_aix_ref+set}" = set; then :
else
gcc_cv_as_aix_ref=no
if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2.21.0 \* 1000 \) + gcc_cv_as_aix_ref=yes \) \* 1000 + `
- then :
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 21 \) \* 1000 + 0`
+ then gcc_cv_as_aix_ref=yes
fi
elif test x$gcc_cv_as != x; then
$as_echo ' .csect stuff[rw]
@@ -26253,7 +26270,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
@@ -26297,7 +26316,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 6ad6d19c9ed..17e1d86e349 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2049,11 +2049,17 @@ if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
do
changequote(,)dnl
- gcc_cv_gld_version=`sed -n -e 's/^[ ]*\(VERSION=[0-9]*\.[0-9]*.*\)/\1/p' < $f`
+ gcc_cv_gld_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gld_version != x; then
break
fi
done
+ case $gcc_cv_gld_version in
+ VERSION=[0-9]*) ;;
+changequote([,])dnl
+ *) AC_MSG_ERROR([[cannot find version of in-tree linker]]) ;;
+changequote(,)dnl
+ esac
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
changequote([,])dnl
@@ -2319,6 +2325,12 @@ else
if test x"$ld_is_gold" = xyes; then
:
elif echo "$ld_ver" | grep GNU > /dev/null; then
+ case "${target}" in
+ mmix-knuth-mmixware)
+ # The linker emits by default mmo, not ELF, so "no" is appropriate.
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
if test 0"$ld_date" -lt 20020404; then
if test -n "$ld_date"; then
# If there was date string, but was earlier than 2002-04-04, fail
@@ -2649,6 +2661,9 @@ else
if test $gcc_cv_as_comdat_group_percent = yes; then
gcc_cv_as_comdat_group_group=no
else
+ if test -z "${gcc_cv_as_comdat_group_group+set}"; then
+ gcc_cv_as_comdat_group_group=no
+ fi
case "${target}" in
# Sun as uses a completely different syntax.
*-*-solaris2*)
@@ -3878,7 +3893,7 @@ LCF0:
case $target in
*-*-aix*)
gcc_GAS_CHECK_FEATURE([.ref support],
- gcc_cv_as_aix_ref, [2.21.0],,
+ gcc_cv_as_aix_ref, [2,21,0],,
[ .csect stuff[[rw]]
stuff:
.long 1
@@ -4379,7 +4394,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
@@ -4416,7 +4433,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 a52b643c638..73ab5a9b0ae 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,87 @@
+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
+ * semantics.c (finish_call_expr): Pass array of 3 sizeof_arg
+ trees and locs (corresponding to first 3 arguments) to
+ sizeof_pointer_memaccess_warning.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24449
+ * decl.c (grokfndecl): When checking for ::main declarations
+ use PROCESSING_REAL_TEMPLATE_DECL_P().
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * call.c (build_new_op_1): Pass RO_ARROW_STAR to cp_build_indirect_ref.
+ * typeck.c (cp_build_indirect_ref): Handle RO_ARROW_STAR.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_THUNKS): NULL_TREE for non-virtual functions.
+ (SET_DECL_THUNKS): New.
+ * decl.c (duplicate_decls): Adjust.
+ * method.c (make_thunk): Adjust.
+
+ * decl.c (grokdeclarator): Set DECL_GNU_TLS_P for static data
+ members, too.
+
2012-10-09 Dodji Seketeli <dodji@redhat.com>
PR c++/53540 - using fails to be equivalent to typedef
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3351a585f2b..e21049b8e64 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);
@@ -5309,7 +5353,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
return cp_build_array_ref (input_location, arg1, arg2, complain);
case MEMBER_REF:
- return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL,
+ return build_m_component_ref (cp_build_indirect_ref (arg1, RO_ARROW_STAR,
complain),
arg2, complain);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0e77b81c85b..a478de80563 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 35819ed10c4..7b4277b05b7 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;
@@ -2378,7 +2380,20 @@ struct GTY((variable_size)) lang_decl {
/* The thunks associated with NODE, a FUNCTION_DECL. */
#define DECL_THUNKS(NODE) \
- (LANG_DECL_FN_CHECK (NODE)->context)
+ (DECL_VIRTUAL_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
+
+/* Set DECL_THUNKS. */
+#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) \
@@ -4138,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],
@@ -5319,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);
@@ -5331,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);
@@ -5366,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 0b936ea1a8b..d25aa804971 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2052,7 +2052,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* DECL_THUNKS is only valid for virtual functions,
otherwise it is a DECL_FRIEND_CONTEXT. */
if (DECL_VIRTUAL_P (newdecl))
- DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
+ SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl));
}
/* Only variables have this field. */
else if (TREE_CODE (newdecl) == VAR_DECL
@@ -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;
@@ -7416,7 +7421,7 @@ grokfndecl (tree ctype,
if (ctype == NULL_TREE && DECL_MAIN_P (decl))
{
- if (processing_template_decl)
+ if (PROCESSING_REAL_TEMPLATE_DECL_P())
error ("cannot declare %<::main%> to be a template");
if (inlinep)
error ("cannot declare %<::main%> to be inline");
@@ -10446,7 +10451,11 @@ grokdeclarator (const cp_declarator *declarator,
DECL_EXTERNAL (decl) = 1;
if (thread_p)
- DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ {
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ if (declspecs->gnu_thread_keyword_p)
+ DECL_GNU_TLS_P (decl) = true;
+ }
if (constexpr_p && !initialized)
{
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 2934c9b1078..76f939f1049 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 40d0ce325f3..044603887e8 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 a42ed60a99f..4da5cc9ebca 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -126,7 +126,8 @@ make_thunk (tree function, bool this_adjusting,
FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (thunk);
- DECL_THUNKS (thunk) = NULL_TREE;
+ DECL_VIRTUAL_P (thunk) = true;
+ SET_DECL_THUNKS (thunk, NULL_TREE);
DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
TREE_READONLY (thunk) = TREE_READONLY (function);
@@ -157,7 +158,7 @@ make_thunk (tree function, bool this_adjusting,
/* Add it to the list of thunks associated with FUNCTION. */
DECL_CHAIN (thunk) = DECL_THUNKS (function);
- DECL_THUNKS (function) = thunk;
+ SET_DECL_THUNKS (function, thunk);
return thunk;
}
@@ -428,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 ();
}
@@ -459,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 ();
}
@@ -477,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)
@@ -485,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))
@@ -515,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;
@@ -530,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))
@@ -548,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))
@@ -832,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);
@@ -1109,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;
@@ -1161,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;
@@ -1169,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. */
@@ -1180,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;
@@ -1230,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;
@@ -1251,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);
@@ -1404,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;
@@ -1431,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
@@ -1441,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;
@@ -1498,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
@@ -1509,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;
@@ -1543,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;
@@ -1574,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);
@@ -1599,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;
}
@@ -1612,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)))
@@ -1765,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 cd328b31c72..f0105604921 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 a7939c87647..853d789f987 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 d81626cb35e..7e8d8b0880d 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/semantics.c b/gcc/cp/semantics.c
index 4beed0073fb..6798c1bf5d4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2173,16 +2173,30 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
{
if (warn_sizeof_pointer_memaccess
&& !VEC_empty(tree, *args)
- && TREE_CODE (VEC_last(tree, *args)) == SIZEOF_EXPR
&& !processing_template_decl)
{
- tree sizeof_arg = VEC_last(tree, *args);
- if (SIZEOF_EXPR_TYPE_P (sizeof_arg))
- sizeof_arg = TREE_TYPE (TREE_OPERAND (sizeof_arg, 0));
- else
- sizeof_arg = TREE_OPERAND (sizeof_arg, 0);
+ location_t sizeof_arg_loc[3];
+ tree sizeof_arg[3];
+ unsigned int i;
+ for (i = 0; i < 3; i++)
+ {
+ tree t;
+
+ sizeof_arg_loc[i] = UNKNOWN_LOCATION;
+ sizeof_arg[i] = NULL_TREE;
+ if (i >= VEC_length (tree, *args))
+ continue;
+ t = VEC_index (tree, *args, i);
+ if (TREE_CODE (t) != SIZEOF_EXPR)
+ continue;
+ if (SIZEOF_EXPR_TYPE_P (t))
+ sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
+ else
+ sizeof_arg[i] = TREE_OPERAND (t, 0);
+ sizeof_arg_loc[i] = EXPR_LOCATION (t);
+ }
sizeof_pointer_memaccess_warning
- (EXPR_LOCATION (VEC_last(tree, *args)), fn, *args,
+ (sizeof_arg_loc, fn, *args,
sizeof_arg, same_type_ignoring_top_level_qualifiers_p);
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a41337c2116..8d555c2e2b1 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/cp/typeck.c b/gcc/cp/typeck.c
index 13e75ab9ebf..eaa0935dc98 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2908,6 +2908,10 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
case RO_IMPLICIT_CONVERSION:
error ("invalid use of implicit conversion on pointer to member");
break;
+ case RO_ARROW_STAR:
+ error ("left hand operand of %<->*%> must be a pointer to class, "
+ "but is a pointer to member of type %qT", type);
+ break;
default:
gcc_unreachable ();
}
diff --git a/gcc/cse.c b/gcc/cse.c
index 16255988fc5..b5631f363da 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 e7c4221df3e..1f9f97efc5d 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 96575f985e0..95fdbf7a5d5 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 72fce0598a7..bcd6c08a691 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 98cbf226176..aae4d471fb6 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 c413a75930f..705713cd1bd 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 53e77388f02..3f9228dc53a 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -57,42 +57,6 @@ along with GCC; see the file COPYING3. If not see
static bitmap_head seen_in_block;
static bitmap_head seen_in_insn;
-
-/*----------------------------------------------------------------------------
- Public functions access functions for the dataflow problems.
-----------------------------------------------------------------------------*/
-/* Get the live at out set for BB no matter what problem happens to be
- defined. This function is used by the register allocators who
- choose different dataflow problems depending on the optimization
- level. */
-
-bitmap
-df_get_live_out (basic_block bb)
-{
- gcc_assert (df_lr);
-
- if (df_live)
- return DF_LIVE_OUT (bb);
- else
- return DF_LR_OUT (bb);
-}
-
-/* Get the live at in set for BB no matter what problem happens to be
- defined. This function is used by the register allocators who
- choose different dataflow problems depending on the optimization
- level. */
-
-bitmap
-df_get_live_in (basic_block bb)
-{
- gcc_assert (df_lr);
-
- if (df_live)
- return DF_LIVE_IN (bb);
- else
- return DF_LR_IN (bb);
-}
-
/*----------------------------------------------------------------------------
Utility functions.
----------------------------------------------------------------------------*/
@@ -2858,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;
@@ -2909,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:
{
@@ -2949,6 +2931,7 @@ df_kill_notes (rtx insn, bitmap live)
}
break;
}
+
default:
pprev = &XEXP (link, 1);
link = *pprev;
@@ -2957,7 +2940,6 @@ df_kill_notes (rtx insn, bitmap live)
}
}
-
/* Set a NOTE_TYPE note for REG in INSN. */
static inline void
@@ -3231,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))
@@ -3372,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/df.h b/gcc/df.h
index e7031d0bb2f..c0902b16d7a 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -951,8 +951,6 @@ extern void debug_df_chain (struct df_link *);
extern struct df_link *df_chain_create (df_ref, df_ref);
extern void df_chain_unlink (df_ref);
extern void df_chain_copy (df_ref, struct df_link *);
-extern bitmap df_get_live_in (basic_block);
-extern bitmap df_get_live_out (basic_block);
extern void df_grow_bb_info (struct dataflow *);
extern void df_chain_dump (struct df_link *, FILE *);
extern void df_print_bb_index (basic_block bb, FILE *file);
@@ -1023,7 +1021,10 @@ extern void df_compute_regs_ever_live (bool);
extern bool df_read_modify_subreg_p (rtx);
extern void df_scan_verify (void);
-/* Get basic block info. */
+
+/*----------------------------------------------------------------------------
+ Public functions access functions for the dataflow problems.
+----------------------------------------------------------------------------*/
static inline struct df_scan_bb_info *
df_scan_get_bb_info (unsigned int index)
@@ -1079,6 +1080,39 @@ df_word_lr_get_bb_info (unsigned int index)
return NULL;
}
+/* Get the live at out set for BB no matter what problem happens to be
+ defined. This function is used by the register allocators who
+ choose different dataflow problems depending on the optimization
+ level. */
+
+static inline bitmap
+df_get_live_out (basic_block bb)
+{
+ gcc_checking_assert (df_lr);
+
+ if (df_live)
+ return DF_LIVE_OUT (bb);
+ else
+ return DF_LR_OUT (bb);
+}
+
+/* Get the live at in set for BB no matter what problem happens to be
+ defined. This function is used by the register allocators who
+ choose different dataflow problems depending on the optimization
+ level. */
+
+static inline bitmap
+df_get_live_in (basic_block bb)
+{
+ gcc_checking_assert (df_lr);
+
+ if (df_live)
+ return DF_LIVE_IN (bb);
+ else
+ return DF_LR_IN (bb);
+}
+
+/* Get basic block info. */
/* Get the artificial defs for a basic block. */
static inline df_ref *
diff --git a/gcc/doc/arm-neon-intrinsics.texi b/gcc/doc/arm-neon-intrinsics.texi
index a75e5821e2b..14e6264aeaa 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 9fd2f27b0fd..6bf929a5c40 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})
@@ -6864,7 +6882,7 @@ a1, @dots{}, an@} >> @{b0, b1, @dots{}, bn@} == @{a0 >> b0, a1 >> b1,
@dots{}, an >> bn@}}@. Vector operands must have the same number of
elements.
-For the convenience in C it is allowed to use a binary vector operation
+For convenience, it is allowed to use a binary vector operation
where one operand is a scalar. In that case the compiler will transform
the scalar operand into a vector where each element is the scalar from
the operation. The transformation will happen only if the scalar could be
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
index c48b663a033..082a5282c8d 100644
--- a/gcc/doc/generic.texi
+++ b/gcc/doc/generic.texi
@@ -1388,7 +1388,8 @@ shift. Right shift should be treated as arithmetic, i.e., the
high-order bits should be zero-filled when the expression has unsigned
type and filled with the sign bit when the expression has signed type.
Note that the result is undefined if the second operand is larger
-than or equal to the first operand's type size.
+than or equal to the first operand's type size. Unlike most nodes, these
+can have a vector as first operand and a scalar as second operand.
@item BIT_IOR_EXPR
@@ -1482,11 +1483,12 @@ allows the backend to choose between the faster of @code{TRUNC_DIV_EXPR},
@itemx NE_EXPR
These nodes represent the less than, less than or equal to, greater
than, greater than or equal to, equal, and not equal comparison
-operators. The first and second operand with either be both of integral
-type or both of floating type. The result type of these expressions
-will always be of integral or boolean type. These operations return
-the result type's zero value for false, and the result type's one value
-for true.
+operators. The first and second operands will either be both of integral
+type, both of floating type or both of vector type. The result type of
+these expressions will always be of integral, boolean or signed integral
+vector type. These operations return the result type's zero value for
+false, the result type's one value for true, and a vector whose elements
+are zero (false) or minus one (true) for vectors.
For floating point comparisons, if we honor IEEE NaNs and either operand
is NaN, then @code{NE_EXPR} always returns true and the remaining operators
@@ -1769,6 +1771,17 @@ of elements of a floating point type. The result is a vector that contains
twice as many elements of an integral type whose size is half as wide. The
elements of the two vectors are merged (concatenated) to form the output
vector.
+
+@item VEC_COND_EXPR
+These nodes represent @code{?:} expressions. The three operands must be
+vectors of the same size and number of elements. The second and third
+operands must have the same type as the entire expression. The first
+operand is of signed integral vector type. If an element of the first
+operand evaluates to a zero value, the corresponding element of the
+result is taken from the third operand. If it evaluates to a minus one
+value, it is taken from the second operand. It should never evaluate to
+any other value. In contrast with a @code{COND_EXPR}, all operands are
+always evaluated.
@end table
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
index b2214b8053b..ea1a928c4ab 100644
--- a/gcc/doc/gty.texi
+++ b/gcc/doc/gty.texi
@@ -65,6 +65,27 @@ The parser understands simple typedefs such as
@code{typedef int @var{name};}.
These don't need to be marked.
+Since @code{gengtype}'s understanding of C++ is limited, there are
+several constructs and declarations that are not supported inside
+classes/structures marked for automatic GC code generation. The
+following C++ constructs produce a @code{gengtype} error on
+structures/classes marked for automatic GC code generation:
+
+@itemize @bullet
+@item
+Type definitions inside classes/structures are not supported.
+@item
+Enumerations inside classes/structures are not supported.
+@end itemize
+
+If you have a class or structure using any of the above constructs,
+you need to mark that class as @code{GTY ((user))} and provide your
+own marking routines (see section @ref{User GC} for details).
+
+It is always valid to include function definitions inside classes.
+Those are always ignored by @code{gengtype}, as it only cares about
+data members.
+
@menu
* GTY Options:: What goes inside a @code{GTY(())}.
* GGC Roots:: Making global variables GGC roots.
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index cbd49f50d90..e7d5e10059d 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 c5765e5ec3d..fe489fdbbe7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -372,7 +372,7 @@ Objective-C and Objective-C++ Dialects}.
-finline-small-functions -fipa-cp -fipa-cp-clone @gol
-fipa-pta -fipa-profile -fipa-pure-const -fipa-reference @gol
-fira-algorithm=@var{algorithm} @gol
--fira-region=@var{region} @gol
+-fira-region=@var{region} -fira-hoist-pressure @gol
-fira-loop-pressure -fno-ira-share-save-slots @gol
-fno-ira-share-spill-slots -fira-verbose=@var{n} @gol
-fivopts -fkeep-inline-functions -fkeep-static-consts @gol
@@ -7002,6 +7002,14 @@ This typically results in the smallest code size, and is enabled by default for
@end table
+@item -fira-hoist-pressure
+@opindex fira-hoist-pressure
+Use IRA to evaluate register pressure in the code hoisting pass for
+decisions to hoist expressions. This option usually results in smaller
+code, but it can slow the compiler down.
+
+This option is enabled at level @option{-Os} for all targets.
+
@item -fira-loop-pressure
@opindex fira-loop-pressure
Use IRA to evaluate register pressure in loops for decisions to move
@@ -11010,6 +11018,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
@@ -11023,7 +11032,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 9f2012f148a..32866d5c156 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
@@ -5501,7 +5517,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
@@ -6133,6 +6151,18 @@ If this pattern is not specified, all memory models except
@code{__ATOMIC_RELAXED} will result in issuing a @code{sync_synchronize}
barrier pattern.
+@cindex @code{get_thread_pointer@var{mode}} instruction pattern
+@cindex @code{set_thread_pointer@var{mode}} instruction pattern
+@item @samp{get_thread_pointer@var{mode}}
+@itemx @samp{set_thread_pointer@var{mode}}
+These patterns emit code that reads/sets the TLS thread pointer. Currently,
+these are only needed if the target needs to support the
+@code{__builtin_thread_pointer} and @code{__builtin_set_thread_pointer}
+builtins.
+
+The get/set patterns have a single output/input operand respectively,
+with @var{mode} intended to be @code{Pmode}.
+
@cindex @code{stack_protect_set} instruction pattern
@item @samp{stack_protect_set}
diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi
index 9c004c8cd3f..f6a31f8d4c7 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 66d3b04bd03..35cb2cf62eb 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 eff4a3909c8..631a1f20ac7 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 95fc130c3db..fcdb1b11951 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 88cac856dad..a4673531995 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 1adea93c316..8fa19fd5ce1 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 154648e7bff..562ffe03aca 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 141185befc7..d56d5411e7b 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/fold-const.c b/gcc/fold-const.c
index 99655a1df9c..b1d811d3548 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8294,6 +8294,40 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
return build_vector (type, elts);
}
+ case REDUC_MIN_EXPR:
+ case REDUC_MAX_EXPR:
+ case REDUC_PLUS_EXPR:
+ {
+ unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+ tree *elts;
+ enum tree_code subcode;
+
+ if (TREE_CODE (op0) != VECTOR_CST)
+ return NULL_TREE;
+
+ elts = XALLOCAVEC (tree, nelts);
+ if (!vec_cst_ctor_to_array (op0, elts))
+ return NULL_TREE;
+
+ switch (code)
+ {
+ case REDUC_MIN_EXPR: subcode = MIN_EXPR; break;
+ case REDUC_MAX_EXPR: subcode = MAX_EXPR; break;
+ case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break;
+ default: gcc_unreachable ();
+ }
+
+ for (i = 1; i < nelts; i++)
+ {
+ elts[0] = const_binop (subcode, elts[0], elts[i]);
+ if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0]))
+ return NULL_TREE;
+ elts[i] = build_zero_cst (TREE_TYPE (type));
+ }
+
+ return build_vector (type, elts);
+ }
+
default:
return NULL_TREE;
} /* switch (code) */
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7a3092a420c..37afedeaeba 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,39 @@
+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
+ * interface.c (check_dummy_characteristics): Recursively check dummy
+ procedures.
+
+2012-10-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54784
+ * trans-stmt.c (gfc_trans_allocate): Correctly determine the reference
+ to the _data component for polymorphic allocation with SOURCE.
+
2012-10-06 Janus Weil <janus@gcc.gnu.org>
PR fortran/54832
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 4822149cc0b..2bdabfe806c 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -1063,6 +1063,19 @@ check_dummy_characteristics (gfc_symbol *s1, gfc_symbol *s2,
/* FIXME: Do more comprehensive testing of attributes, like e.g.
ASYNCHRONOUS, CONTIGUOUS, VALUE, VOLATILE, etc. */
+ /* Check interface of dummy procedures. */
+ if (s1->attr.flavor == FL_PROCEDURE)
+ {
+ char err[200];
+ if (!gfc_compare_interfaces (s1, s2, s2->name, 0, 1, err, sizeof(err),
+ NULL, NULL))
+ {
+ snprintf (errmsg, err_len, "Interface mismatch in dummy procedure "
+ "'%s': %s", s1->name, err);
+ return FAILURE;
+ }
+ }
+
/* Check string length. */
if (s1->ts.type == BT_CHARACTER
&& s1->ts.u.cl && s1->ts.u.cl->length
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 722e036510e..ac3021ea72c 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 1178e3d3cb5..cf9f34672a4 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 204f069cc53..b95c8dae758 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,
@@ -5130,7 +5130,7 @@ gfc_trans_allocate (gfc_code * code)
gfc_actual_arglist *actual;
gfc_expr *ppc;
gfc_code *ppc_code;
- gfc_ref *dataref;
+ gfc_ref *ref, *dataref;
/* Do a polymorphic deep copy. */
actual = gfc_get_actual_arglist ();
@@ -5142,13 +5142,15 @@ gfc_trans_allocate (gfc_code * code)
actual->next->expr->ts.type = BT_CLASS;
gfc_add_data_component (actual->next->expr);
- dataref = actual->next->expr->ref;
+ dataref = NULL;
/* Make sure we go up through the reference chain to
the _data reference, where the arrayspec is found. */
- while (dataref->next && dataref->next->type != REF_ARRAY)
- dataref = dataref->next;
+ for (ref = actual->next->expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_COMPONENT
+ && strcmp (ref->u.c.component->name, "_data") == 0)
+ dataref = ref;
- if (dataref->u.c.component->as)
+ if (dataref && dataref->u.c.component->as)
{
int dim;
gfc_expr *temp;
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 9818ceb1f4a..7e6d58c1bb6 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/gcov.c b/gcc/gcov.c
index cf26ce19a2c..09831c2c6d6 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -842,7 +842,7 @@ create_file_names (const char *file_name)
}
/* Remove the extension. */
- cptr = strrchr (name, '.');
+ cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
if (cptr)
*cptr = 0;
diff --git a/gcc/gcse.c b/gcc/gcse.c
index a066b36c642..99e7685cdba 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1,6 +1,6 @@
/* Partial redundancy elimination / Hoisting for RTL.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,9 +20,11 @@ along with GCC; see the file COPYING3. If not see
/* TODO
- reordering of memory allocation and freeing to be more space efficient
- - do rough calc of how many regs are needed in each block, and a rough
- calc of how many regs are available in each class and use that to
- throttle back the code in cases where RTX_COST is minimal.
+ - simulate register pressure change of each basic block accurately during
+ hoist process. But I doubt the benefit since most expressions hoisted
+ are constant or address, which usually won't reduce register pressure.
+ - calc rough register pressure information and use the info to drive all
+ kinds of code motion (including code hoisting) in a unified way.
*/
/* References searched while implementing this.
@@ -141,11 +143,12 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "toplev.h"
+#include "hard-reg-set.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "regs.h"
-#include "hard-reg-set.h"
+#include "ira.h"
#include "flags.h"
#include "insn-config.h"
#include "recog.h"
@@ -412,6 +415,22 @@ static bool doing_code_hoisting_p = false;
/* For available exprs */
static sbitmap *ae_kill;
+/* Data stored for each basic block. */
+struct bb_data
+{
+ /* Maximal register pressure inside basic block for given register class
+ (defined only for the pressure classes). */
+ int max_reg_pressure[N_REG_CLASSES];
+};
+
+#define BB_DATA(bb) ((struct bb_data *) (bb)->aux)
+
+static basic_block curr_bb;
+
+/* Current register pressure for each pressure class. */
+static int curr_reg_pressure[N_REG_CLASSES];
+
+
static void compute_can_copy (void);
static void *gmalloc (size_t) ATTRIBUTE_MALLOC;
static void *gcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
@@ -460,9 +479,11 @@ static void alloc_code_hoist_mem (int, int);
static void free_code_hoist_mem (void);
static void compute_code_hoist_vbeinout (void);
static void compute_code_hoist_data (void);
-static int hoist_expr_reaches_here_p (basic_block, int, basic_block, char *,
- int, int *);
+static int should_hoist_expr_to_dom (basic_block, struct expr *, basic_block,
+ sbitmap, int, int *, enum reg_class,
+ int *, bitmap);
static int hoist_code (void);
+static enum reg_class get_pressure_class_and_nregs (rtx insn, int *nregs);
static int one_code_hoisting_pass (void);
static rtx process_insert_insn (struct expr *);
static int pre_edge_insert (struct edge_list *, struct expr **);
@@ -1519,9 +1540,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);
@@ -1857,7 +1879,7 @@ prune_expressions (bool pre_p)
a basic block we should account for any side-effects of a subsequent
jump instructions that could clobber the expression. It would
be best to implement this check along the lines of
- hoist_expr_reaches_here_p where the target block is already known
+ should_hoist_expr_to_dom where the target block is already known
and, hence, there's no need to conservatively prune expressions on
"intermediate" set-and-jump instructions. */
FOR_EACH_EDGE (e, ei, bb->preds)
@@ -2825,10 +2847,21 @@ compute_code_hoist_data (void)
fprintf (dump_file, "\n");
}
-/* Determine if the expression identified by EXPR_INDEX would
- reach BB unimpared if it was placed at the end of EXPR_BB.
- Stop the search if the expression would need to be moved more
- than DISTANCE instructions.
+/* Determine if the expression EXPR should be hoisted to EXPR_BB up in
+ flow graph, if it can reach BB unimpared. Stop the search if the
+ expression would need to be moved more than DISTANCE instructions.
+
+ DISTANCE is the number of instructions through which EXPR can be
+ hoisted up in flow graph.
+
+ BB_SIZE points to an array which contains the number of instructions
+ for each basic block.
+
+ PRESSURE_CLASS and NREGS are register class and number of hard registers
+ for storing EXPR.
+
+ HOISTED_BBS points to a bitmap indicating basic blocks through which
+ EXPR is hoisted.
It's unclear exactly what Muchnick meant by "unimpared". It seems
to me that the expression must either be computed or transparent in
@@ -2841,18 +2874,32 @@ compute_code_hoist_data (void)
paths. */
static int
-hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb,
- char *visited, int distance, int *bb_size)
+should_hoist_expr_to_dom (basic_block expr_bb, struct expr *expr,
+ basic_block bb, sbitmap visited, int distance,
+ int *bb_size, enum reg_class pressure_class,
+ int *nregs, bitmap hoisted_bbs)
{
+ unsigned int i;
edge pred;
edge_iterator ei;
+ sbitmap_iterator sbi;
int visited_allocated_locally = 0;
/* Terminate the search if distance, for which EXPR is allowed to move,
is exhausted. */
if (distance > 0)
{
- distance -= bb_size[bb->index];
+ /* Let EXPR be hoisted through basic block at no cost if the block
+ has low register pressure. An exception is constant expression,
+ because hoisting constant expr aggressively results in worse code.
+ The exception is made by the observation of CSiBE on ARM target,
+ while it has no obvious effect on other targets like x86, x86_64,
+ mips and powerpc. */
+ if (!flag_ira_hoist_pressure
+ || (BB_DATA (bb)->max_reg_pressure[pressure_class]
+ >= ira_class_hard_regs_num[pressure_class]
+ || CONST_INT_P (expr->expr)))
+ distance -= bb_size[bb->index];
if (distance <= 0)
return 0;
@@ -2863,7 +2910,8 @@ hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb,
if (visited == NULL)
{
visited_allocated_locally = 1;
- visited = XCNEWVEC (char, last_basic_block);
+ visited = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (visited);
}
FOR_EACH_EDGE (pred, ei, bb->preds)
@@ -2874,23 +2922,37 @@ hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb,
break;
else if (pred_bb == expr_bb)
continue;
- else if (visited[pred_bb->index])
+ else if (TEST_BIT (visited, pred_bb->index))
continue;
-
- else if (! TEST_BIT (transp[pred_bb->index], expr_index))
+ else if (! TEST_BIT (transp[pred_bb->index], expr->bitmap_index))
break;
-
/* Not killed. */
else
{
- visited[pred_bb->index] = 1;
- if (! hoist_expr_reaches_here_p (expr_bb, expr_index, pred_bb,
- visited, distance, bb_size))
+ SET_BIT (visited, pred_bb->index);
+ if (! should_hoist_expr_to_dom (expr_bb, expr, pred_bb,
+ visited, distance, bb_size,
+ pressure_class, nregs, hoisted_bbs))
break;
}
}
if (visited_allocated_locally)
- free (visited);
+ {
+ /* If EXPR can be hoisted to expr_bb, record basic blocks through
+ which EXPR is hoisted in hoisted_bbs. Also update register
+ pressure for basic blocks newly added in hoisted_bbs. */
+ if (flag_ira_hoist_pressure && !pred)
+ {
+ EXECUTE_IF_SET_IN_SBITMAP (visited, 0, i, sbi)
+ if (!bitmap_bit_p (hoisted_bbs, i))
+ {
+ bitmap_set_bit (hoisted_bbs, i);
+ BB_DATA (BASIC_BLOCK (i))->max_reg_pressure[pressure_class]
+ += *nregs;
+ }
+ }
+ sbitmap_free (visited);
+ }
return (pred == NULL);
}
@@ -2907,7 +2969,44 @@ find_occr_in_bb (struct occr *occr, basic_block bb)
return occr;
}
-/* Actually perform code hoisting. */
+/* Actually perform code hoisting.
+
+ The code hoisting pass can hoist multiple computations of the same
+ expression along dominated path to a dominating basic block, like
+ from b2/b3 to b1 as depicted below:
+
+ b1 ------
+ /\ |
+ / \ |
+ bx by distance
+ / \ |
+ / \ |
+ b2 b3 ------
+
+ Unfortunately code hoisting generally extends the live range of an
+ output pseudo register, which increases register pressure and hurts
+ register allocation. To address this issue, an attribute MAX_DISTANCE
+ is computed and attached to each expression. The attribute is computed
+ from rtx cost of the corresponding expression and it's used to control
+ how long the expression can be hoisted up in flow graph. As the
+ expression is hoisted up in flow graph, GCC decreases its DISTANCE
+ and stops the hoist if DISTANCE reaches 0.
+
+ Option "-fira-hoist-pressure" implements register pressure directed
+ hoist based on upper method. The rationale is:
+ 1. Calculate register pressure for each basic block by reusing IRA
+ facility.
+ 2. When expression is hoisted through one basic block, GCC checks
+ register pressure of the basic block and decrease DISTANCE only
+ when the register pressure is high. In other words, expression
+ will be hoisted through basic block with low register pressure
+ at no cost.
+ 3. Update register pressure information for basic blocks through
+ which expression is hoisted.
+ TODO: It is possible to have register pressure decreased because
+ of shrinked live ranges of input pseudo registers when hoisting
+ an expression. For now, this effect is not simulated and we just
+ increase register pressure for hoisted expressions. */
static int
hoist_code (void)
@@ -2916,12 +3015,18 @@ hoist_code (void)
VEC (basic_block, heap) *dom_tree_walk;
unsigned int dom_tree_walk_index;
VEC (basic_block, heap) *domby;
- unsigned int i,j;
+ unsigned int i, j, k;
struct expr **index_map;
struct expr *expr;
int *to_bb_head;
int *bb_size;
int changed = 0;
+ struct bb_data *data;
+ /* Basic blocks that have occurrences reachable from BB. */
+ bitmap from_bbs;
+ /* Basic blocks through which expr is hoisted. */
+ bitmap hoisted_bbs = NULL;
+ bitmap_iterator bi;
/* Compute a mapping from expression number (`bitmap_index') to
hash table entry. */
@@ -2959,6 +3064,10 @@ hoist_code (void)
&& (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest
== ENTRY_BLOCK_PTR->next_bb));
+ from_bbs = BITMAP_ALLOC (NULL);
+ if (flag_ira_hoist_pressure)
+ hoisted_bbs = BITMAP_ALLOC (NULL);
+
dom_tree_walk = get_all_dominated_blocks (CDI_DOMINATORS,
ENTRY_BLOCK_PTR->next_bb);
@@ -2977,12 +3086,12 @@ hoist_code (void)
{
if (TEST_BIT (hoist_vbeout[bb->index], i))
{
+ int nregs = 0;
+ enum reg_class pressure_class = NO_REGS;
/* Current expression. */
struct expr *expr = index_map[i];
/* Number of occurrences of EXPR that can be hoisted to BB. */
int hoistable = 0;
- /* Basic blocks that have occurrences reachable from BB. */
- bitmap_head _from_bbs, *from_bbs = &_from_bbs;
/* Occurrences reachable from BB. */
VEC (occr_t, heap) *occrs_to_hoist = NULL;
/* We want to insert the expression into BB only once, so
@@ -2990,8 +3099,6 @@ hoist_code (void)
int insn_inserted_p;
occr_t occr;
- bitmap_initialize (from_bbs, 0);
-
/* If an expression is computed in BB and is available at end of
BB, hoist all occurrences dominated by BB to BB. */
if (TEST_BIT (comp[bb->index], i))
@@ -3045,13 +3152,18 @@ hoist_code (void)
max_distance += (bb_size[dominated->index]
- to_bb_head[INSN_UID (occr->insn)]);
- /* Note if the expression would reach the dominated block
- unimpared if it was placed at the end of BB.
+ pressure_class = get_pressure_class_and_nregs (occr->insn,
+ &nregs);
+
+ /* Note if the expression should be hoisted from the dominated
+ block to BB if it can reach DOMINATED unimpared.
Keep track of how many times this expression is hoistable
from a dominated block into BB. */
- if (hoist_expr_reaches_here_p (bb, i, dominated, NULL,
- max_distance, bb_size))
+ if (should_hoist_expr_to_dom (bb, expr, dominated, NULL,
+ max_distance, bb_size,
+ pressure_class, &nregs,
+ hoisted_bbs))
{
hoistable++;
VEC_safe_push (occr_t, heap,
@@ -3092,6 +3204,28 @@ hoist_code (void)
/* Punt, no point hoisting a single occurence. */
VEC_free (occr_t, heap, occrs_to_hoist);
+ if (flag_ira_hoist_pressure
+ && !VEC_empty (occr_t, occrs_to_hoist))
+ {
+ /* Update register pressure for basic block to which expr
+ is hoisted. */
+ data = BB_DATA (bb);
+ data->max_reg_pressure[pressure_class] += nregs;
+ }
+ else if (flag_ira_hoist_pressure)
+ {
+ /* Restore register pressure of basic block recorded in
+ hoisted_bbs when expr will not be hoisted. */
+ EXECUTE_IF_SET_IN_BITMAP (hoisted_bbs, 0, k, bi)
+ {
+ data = BB_DATA (BASIC_BLOCK (k));
+ data->max_reg_pressure[pressure_class] -= nregs;
+ }
+ }
+
+ if (flag_ira_hoist_pressure)
+ bitmap_clear (hoisted_bbs);
+
insn_inserted_p = 0;
/* Walk through occurrences of I'th expressions we want
@@ -3140,6 +3274,10 @@ hoist_code (void)
}
VEC_free (basic_block, heap, dom_tree_walk);
+ BITMAP_FREE (from_bbs);
+ if (flag_ira_hoist_pressure)
+ BITMAP_FREE (hoisted_bbs);
+
free (bb_size);
free (to_bb_head);
free (index_map);
@@ -3147,6 +3285,165 @@ hoist_code (void)
return changed;
}
+/* Return pressure class and number of needed hard registers (through
+ *NREGS) of register REGNO. */
+static enum reg_class
+get_regno_pressure_class (int regno, int *nregs)
+{
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ enum reg_class pressure_class;
+
+ pressure_class = reg_allocno_class (regno);
+ pressure_class = ira_pressure_class_translate[pressure_class];
+ *nregs
+ = ira_reg_class_max_nregs[pressure_class][PSEUDO_REGNO_MODE (regno)];
+ return pressure_class;
+ }
+ else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)
+ && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
+ {
+ *nregs = 1;
+ return ira_pressure_class_translate[REGNO_REG_CLASS (regno)];
+ }
+ else
+ {
+ *nregs = 0;
+ return NO_REGS;
+ }
+}
+
+/* Return pressure class and number of hard registers (through *NREGS)
+ for destination of INSN. */
+static enum reg_class
+get_pressure_class_and_nregs (rtx insn, int *nregs)
+{
+ rtx reg;
+ enum reg_class pressure_class;
+ rtx set = single_set (insn);
+
+ /* Considered invariant insns have only one set. */
+ gcc_assert (set != NULL_RTX);
+ reg = SET_DEST (set);
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ if (MEM_P (reg))
+ {
+ *nregs = 0;
+ pressure_class = NO_REGS;
+ }
+ else
+ {
+ gcc_assert (REG_P (reg));
+ pressure_class = reg_allocno_class (REGNO (reg));
+ pressure_class = ira_pressure_class_translate[pressure_class];
+ *nregs
+ = ira_reg_class_max_nregs[pressure_class][GET_MODE (SET_SRC (set))];
+ }
+ return pressure_class;
+}
+
+/* Increase (if INCR_P) or decrease current register pressure for
+ register REGNO. */
+static void
+change_pressure (int regno, bool incr_p)
+{
+ int nregs;
+ enum reg_class pressure_class;
+
+ pressure_class = get_regno_pressure_class (regno, &nregs);
+ if (! incr_p)
+ curr_reg_pressure[pressure_class] -= nregs;
+ else
+ {
+ curr_reg_pressure[pressure_class] += nregs;
+ if (BB_DATA (curr_bb)->max_reg_pressure[pressure_class]
+ < curr_reg_pressure[pressure_class])
+ BB_DATA (curr_bb)->max_reg_pressure[pressure_class]
+ = curr_reg_pressure[pressure_class];
+ }
+}
+
+/* Calculate register pressure for each basic block by walking insns
+ from last to first. */
+static void
+calculate_bb_reg_pressure (void)
+{
+ int i;
+ unsigned int j;
+ rtx insn;
+ basic_block bb;
+ bitmap curr_regs_live;
+ bitmap_iterator bi;
+
+
+ ira_setup_eliminable_regset ();
+ curr_regs_live = BITMAP_ALLOC (&reg_obstack);
+ FOR_EACH_BB (bb)
+ {
+ curr_bb = bb;
+ bitmap_copy (curr_regs_live, DF_LR_OUT (bb));
+ for (i = 0; i < ira_pressure_classes_num; i++)
+ curr_reg_pressure[ira_pressure_classes[i]] = 0;
+ EXECUTE_IF_SET_IN_BITMAP (curr_regs_live, 0, j, bi)
+ change_pressure (j, true);
+
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ {
+ rtx dreg;
+ int regno;
+ df_ref *def_rec, *use_rec;
+
+ if (! NONDEBUG_INSN_P (insn))
+ continue;
+
+ for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+ {
+ dreg = DF_REF_REAL_REG (*def_rec);
+ gcc_assert (REG_P (dreg));
+ regno = REGNO (dreg);
+ if (!(DF_REF_FLAGS (*def_rec)
+ & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+ {
+ if (bitmap_clear_bit (curr_regs_live, regno))
+ change_pressure (regno, false);
+ }
+ }
+
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ {
+ dreg = DF_REF_REAL_REG (*use_rec);
+ gcc_assert (REG_P (dreg));
+ regno = REGNO (dreg);
+ if (bitmap_set_bit (curr_regs_live, regno))
+ change_pressure (regno, true);
+ }
+ }
+ }
+ BITMAP_FREE (curr_regs_live);
+
+ if (dump_file == NULL)
+ return;
+
+ fprintf (dump_file, "\nRegister Pressure: \n");
+ FOR_EACH_BB (bb)
+ {
+ fprintf (dump_file, " Basic block %d: \n", bb->index);
+ for (i = 0; (int) i < ira_pressure_classes_num; i++)
+ {
+ enum reg_class pressure_class;
+
+ pressure_class = ira_pressure_classes[i];
+ if (BB_DATA (bb)->max_reg_pressure[pressure_class] == 0)
+ continue;
+
+ fprintf (dump_file, " %s=%d\n", reg_class_names[pressure_class],
+ BB_DATA (bb)->max_reg_pressure[pressure_class]);
+ }
+ }
+ fprintf (dump_file, "\n");
+}
+
/* Top level routine to perform one code hoisting (aka unification) pass
Return nonzero if a change was made. */
@@ -3166,6 +3463,16 @@ one_code_hoisting_pass (void)
doing_code_hoisting_p = true;
+ /* Calculate register pressure for each basic block. */
+ if (flag_ira_hoist_pressure)
+ {
+ regstat_init_n_sets_and_refs ();
+ ira_set_pseudo_classes (false, dump_file);
+ alloc_aux_for_blocks (sizeof (struct bb_data));
+ calculate_bb_reg_pressure ();
+ regstat_free_n_sets_and_refs ();
+ }
+
/* We need alias. */
init_alias_analysis ();
@@ -3186,6 +3493,11 @@ one_code_hoisting_pass (void)
free_code_hoist_mem ();
}
+ if (flag_ira_hoist_pressure)
+ {
+ free_aux_for_blocks ();
+ free_reg_info ();
+ }
free_hash_table (&expr_hash_table);
free_gcse_mem ();
obstack_free (&gcse_obstack, NULL);
diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
index 5788a6a26d6..fd8090606d3 100644
--- a/gcc/gengtype-lex.l
+++ b/gcc/gengtype-lex.l
@@ -50,12 +50,15 @@ update_lineno (const char *l, size_t len)
%}
-ID [[:alpha:]_][[:alnum:]_]*
+CID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
HWS [ \t\r\v\f]*
IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET
ITYPE {IWORD}({WS}{IWORD})*
+ /* Include '::' in identifiers to capture C++ scope qualifiers. */
+ID {CID}({HWS}::{HWS}{CID})*
EOID [^[:alnum:]_]
+CXX_KEYWORD inline|public:|private:|protected:|template|operator|friend
%x in_struct in_struct_comment in_comment
%option warn noyywrap nounput nodefault perf-report
@@ -83,6 +86,10 @@ EOID [^[:alnum:]_]
BEGIN(in_struct);
return UNION;
}
+^{HWS}class/{EOID} {
+ BEGIN(in_struct);
+ return STRUCT;
+}
^{HWS}extern/{EOID} {
BEGIN(in_struct);
return EXTERN;
@@ -93,18 +100,27 @@ EOID [^[:alnum:]_]
}
}
+ /* Parsing inside a struct, union or class declaration. */
<in_struct>{
-
"/*" { BEGIN(in_struct_comment); }
+"//".*\n { lexer_line.line++; }
{WS} { update_lineno (yytext, yyleng); }
\\\n { lexer_line.line++; }
"const"/{EOID} /* don't care */
+{CXX_KEYWORD}/{EOID} |
+"~" |
+"&" {
+ *yylval = XDUPVAR (const char, yytext, yyleng, yyleng + 1);
+ return IGNORABLE_CXX_KEYWORD;
+}
"GTY"/{EOID} { return GTY_TOKEN; }
"VEC"/{EOID} { return VEC_TOKEN; }
"union"/{EOID} { return UNION; }
"struct"/{EOID} { return STRUCT; }
+"class"/{EOID} { return STRUCT; }
+"typedef"/{EOID} { return TYPEDEF; }
"enum"/{EOID} { return ENUM; }
"ptr_alias"/{EOID} { return PTR_ALIAS; }
"nested_ptr"/{EOID} { return NESTED_PTR; }
@@ -127,7 +143,6 @@ EOID [^[:alnum:]_]
return SCALAR;
}
-
{ID}/{EOID} {
*yylval = XDUPVAR (const char, yytext, yyleng, yyleng+1);
return ID;
@@ -148,7 +163,7 @@ EOID [^[:alnum:]_]
}
"..." { return ELLIPSIS; }
-[(){},*:<>;=%|-] { return yytext[0]; }
+[(){},*:<>;=%|+-] { return yytext[0]; }
/* ignore pp-directives */
^{HWS}"#"{HWS}[a-z_]+[^\n]*\n {lexer_line.line++;}
@@ -159,6 +174,7 @@ EOID [^[:alnum:]_]
}
"/*" { BEGIN(in_comment); }
+"//".*\n { lexer_line.line++; }
\n { lexer_line.line++; }
{ID} |
"'"("\\".|[^\\])"'" |
@@ -172,6 +188,7 @@ EOID [^[:alnum:]_]
[^*\n] /* do nothing */
"*"/[^/] /* do nothing */
}
+
<in_comment>"*/" { BEGIN(INITIAL); }
<in_struct_comment>"*/" { BEGIN(in_struct); }
diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c
index 03ee7819b0f..5737a156f70 100644
--- a/gcc/gengtype-parse.c
+++ b/gcc/gengtype-parse.c
@@ -87,6 +87,7 @@ static const char *const token_names[] = {
"a string constant",
"a character constant",
"an array declarator",
+ "a C++ keyword to ignore"
};
/* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */
@@ -98,6 +99,7 @@ static const char *const token_value_format[] = {
"'\"%s\"'",
"\"'%s'\"",
"'[%s]'",
+ "'%s'",
};
/* Produce a printable representation for a token defined by CODE and
@@ -313,78 +315,77 @@ consume_balanced (int opener, int closer)
}
/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
- expressions, until we encounter a semicolon outside any such
- delimiters; absorb that too. If IMMEDIATE is true, it is an error
- if the semicolon is not the first token encountered. */
+ expressions, until we encounter an end-of-statement marker (a ';' or
+ a '}') outside any such delimiters; absorb that too. */
+
static void
-consume_until_semi (bool immediate)
+consume_until_eos (void)
{
- if (immediate && token () != ';')
- require (';');
for (;;)
switch (token ())
{
case ';':
advance ();
return;
- default:
- advance ();
- break;
+
+ case '{':
+ consume_balanced ('{', '}');
+ return;
case '(':
consume_balanced ('(', ')');
break;
+
case '[':
consume_balanced ('[', ']');
break;
- case '{':
- consume_balanced ('{', '}');
- break;
case '}':
case ']':
case ')':
parse_error ("unmatched '%c' while scanning for ';'", token ());
- return;
+ return;
case EOF_TOKEN:
parse_error ("unexpected end of file while scanning for ';'");
return;
+
+ default:
+ advance ();
+ break;
}
}
/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
expressions, until we encounter a comma or semicolon outside any
- such delimiters; absorb that too. If IMMEDIATE is true, it is an
- error if the comma or semicolon is not the first token encountered.
- Returns true if the loop ended with a comma. */
+ such delimiters; absorb that too. Returns true if the loop ended
+ with a comma. */
+
static bool
-consume_until_comma_or_semi (bool immediate)
+consume_until_comma_or_eos ()
{
- if (immediate && token () != ',' && token () != ';')
- require2 (',', ';');
for (;;)
switch (token ())
{
case ',':
advance ();
return true;
+
case ';':
advance ();
return false;
- default:
- advance ();
- break;
+
+ case '{':
+ consume_balanced ('{', '}');
+ return false;
case '(':
consume_balanced ('(', ')');
break;
+
case '[':
consume_balanced ('[', ']');
break;
- case '{':
- consume_balanced ('{', '}');
- break;
case '}':
case ']':
@@ -396,6 +397,10 @@ consume_until_comma_or_semi (bool immediate)
case EOF_TOKEN:
parse_error ("unexpected end of file while scanning for ',' or ';'");
return false;
+
+ default:
+ advance ();
+ break;
}
}
@@ -548,6 +553,8 @@ gtymarker_opt (void)
return 0;
return gtymarker ();
}
+
+
/* Declarators. The logic here is largely lifted from c-parser.c.
Note that we do not have to process abstract declarators, which can
@@ -584,16 +591,21 @@ array_and_function_declarators_opt (type_p ty)
return ty;
}
-static type_p inner_declarator (type_p, const char **, options_p *);
+static type_p inner_declarator (type_p, const char **, options_p *, bool);
/* direct_declarator:
'(' inner_declarator ')'
+ '(' \epsilon ')' <-- C++ ctors/dtors
gtymarker_opt ID array_and_function_declarators_opt
Subroutine of declarator, mutually recursive with inner_declarator;
- do not use elsewhere. */
+ do not use elsewhere.
+
+ IN_STRUCT is true if we are called while parsing structures or classes. */
+
static type_p
-direct_declarator (type_p ty, const char **namep, options_p *optsp)
+direct_declarator (type_p ty, const char **namep, options_p *optsp,
+ bool in_struct)
{
/* The first token in a direct-declarator must be an ID, a
GTY marker, or an open parenthesis. */
@@ -602,18 +614,45 @@ direct_declarator (type_p ty, const char **namep, options_p *optsp)
case GTY_TOKEN:
*optsp = gtymarker ();
/* fall through */
+
case ID:
*namep = require (ID);
+ /* If the next token is '(', we are parsing a function declaration.
+ Functions are ignored by gengtype, so we return NULL. */
+ if (token () == '(')
+ return NULL;
break;
case '(':
+ /* If the declarator starts with a '(', we have three options. We
+ are either parsing 'TYPE (*ID)' (i.e., a function pointer)
+ or 'TYPE(...)'.
+
+ The latter will be a constructor iff we are inside a
+ structure or class. Otherwise, it could be a typedef, but
+ since we explicitly reject typedefs inside structures, we can
+ assume that we found a ctor and return NULL. */
advance ();
- ty = inner_declarator (ty, namep, optsp);
+ if (in_struct && token () != '*')
+ {
+ /* Found a constructor. Find and consume the closing ')'. */
+ while (token () != ')')
+ advance ();
+ advance ();
+ /* Tell the caller to ignore this. */
+ return NULL;
+ }
+ ty = inner_declarator (ty, namep, optsp, in_struct);
require (')');
break;
+ case IGNORABLE_CXX_KEYWORD:
+ /* Any C++ keyword like 'operator' means that we are not looking
+ at a regular data declarator. */
+ return NULL;
+
default:
- parse_error ("expected '(', 'GTY', or an identifier, have %s",
+ parse_error ("expected '(', ')', 'GTY', or an identifier, have %s",
print_cur_token ());
/* Do _not_ advance if what we have is a close squiggle brace, as
we will get much better error recovery that way. */
@@ -643,23 +682,26 @@ direct_declarator (type_p ty, const char **namep, options_p *optsp)
direct_declarator
Mutually recursive subroutine of direct_declarator; do not use
- elsewhere. */
+ elsewhere.
+
+ IN_STRUCT is true if we are called while parsing structures or classes. */
static type_p
-inner_declarator (type_p ty, const char **namep, options_p *optsp)
+inner_declarator (type_p ty, const char **namep, options_p *optsp,
+ bool in_struct)
{
if (token () == '*')
{
type_p inner;
advance ();
- inner = inner_declarator (ty, namep, optsp);
+ inner = inner_declarator (ty, namep, optsp, in_struct);
if (inner == 0)
return 0;
else
return create_pointer (ty);
}
else
- return direct_declarator (ty, namep, optsp);
+ return direct_declarator (ty, namep, optsp, in_struct);
}
/* declarator: '*'+ direct_declarator
@@ -667,10 +709,15 @@ inner_declarator (type_p ty, const char **namep, options_p *optsp)
This is the sole public interface to this part of the grammar.
Arguments are the type known so far, a pointer to where the name
may be stored, and a pointer to where GTY options may be stored.
- Returns the final type. */
+
+ IN_STRUCT is true when we are called to parse declarators inside
+ a structure or class.
+
+ Returns the final type. */
static type_p
-declarator (type_p ty, const char **namep, options_p *optsp)
+declarator (type_p ty, const char **namep, options_p *optsp,
+ bool in_struct = false)
{
*namep = 0;
*optsp = 0;
@@ -679,7 +726,7 @@ declarator (type_p ty, const char **namep, options_p *optsp)
advance ();
ty = create_pointer (ty);
}
- return direct_declarator (ty, namep, optsp);
+ return direct_declarator (ty, namep, optsp, in_struct);
}
/* Types and declarations. */
@@ -708,18 +755,19 @@ struct_field_seq (void)
if (!ty || token () == ':')
{
- consume_until_semi (false);
+ consume_until_eos ();
continue;
}
do
{
- dty = declarator (ty, &name, &dopts);
+ dty = declarator (ty, &name, &dopts, true);
+
/* There could be any number of weird things after the declarator,
notably bitfield declarations and __attribute__s. If this
function returns true, the last thing was a comma, so we have
more than one declarator paired with the current type. */
- another = consume_until_comma_or_semi (false);
+ another = consume_until_comma_or_eos ();
if (!dty)
continue;
@@ -760,7 +808,12 @@ opts_have (options_p opts, const char *str)
Returns a partial type; under some conditions (notably
"struct foo GTY((...)) thing;") it may write an options
structure to *OPTSP.
-*/
+
+ NESTED is true when parsing a declaration already known to have a
+ GTY marker. In these cases, typedef and enum declarations are not
+ allowed because gengtype only understands types at the global
+ scope. */
+
static type_p
type (options_p *optsp, bool nested)
{
@@ -777,6 +830,12 @@ type (options_p *optsp, bool nested)
s = typedef_name ();
return resolve_typedef (s, &lexer_line);
+ case IGNORABLE_CXX_KEYWORD:
+ /* By returning NULL here, we indicate to the caller that they
+ should ignore everything following this keyword up to the
+ next ';' or '}'. */
+ return NULL;
+
case STRUCT:
case UNION:
{
@@ -796,8 +855,8 @@ type (options_p *optsp, bool nested)
/* Top-level structures that are not explicitly tagged GTY(())
are treated as mere forward declarations. This is because
there are a lot of structures that we don't need to know
- about, and some of those have weird macro stuff in them
- that we can't handle. */
+ about, and some of those have C++ and macro constructs that
+ we cannot handle. */
if (nested || token () == GTY_TOKEN)
{
is_gty = GTY_BEFORE_ID;
@@ -819,6 +878,13 @@ type (options_p *optsp, bool nested)
opts = gtymarker_opt ();
}
+ if (token () == ':')
+ {
+ /* Skip over C++ inheritance specification. */
+ while (token () != '{')
+ advance ();
+ }
+
if (is_gty)
{
bool is_user_gty = opts_have (opts, "user");
@@ -853,6 +919,21 @@ type (options_p *optsp, bool nested)
return find_structure (s, kind);
}
+ case TYPEDEF:
+ /* In C++, a typedef inside a struct/class/union defines a new
+ type for that inner scope. We cannot support this in
+ gengtype because we have no concept of scoping.
+
+ We handle typedefs in the global scope separately (see
+ parse_file), so if we find a 'typedef', we must be inside
+ a struct. */
+ gcc_assert (nested);
+ parse_error ("typedefs not supported in structures marked with "
+ "automatic GTY markers. Use GTY((user)) to mark "
+ "this structure.");
+ advance ();
+ return NULL;
+
case ENUM:
advance ();
if (token () == ID)
@@ -864,6 +945,23 @@ type (options_p *optsp, bool nested)
if (token () == '{')
consume_balanced ('{', '}');
+
+ /* If after parsing the enum we are at the end of the statement,
+ and we are currently inside a structure, then this was an
+ enum declaration inside this scope.
+
+ We cannot support this for the same reason we cannot support
+ 'typedef' inside structures (see the TYPEDEF handler above).
+ If this happens, emit an error and return NULL. */
+ if (nested && token () == ';')
+ {
+ parse_error ("enum definitions not supported in structures marked "
+ "with automatic GTY markers. Use GTY((user)) to mark "
+ "this structure.");
+ advance ();
+ return NULL;
+ }
+
return create_scalar_type (s);
default:
@@ -901,7 +999,7 @@ typedef_decl (void)
/* Yet another place where we could have junk (notably attributes)
after the declarator. */
- another = consume_until_comma_or_semi (false);
+ another = consume_until_comma_or_eos ();
if (dty)
do_typedef (name, dty, &lexer_line);
}
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
index c94d50b1ef6..e3317ec36a4 100644
--- a/gcc/gengtype-state.c
+++ b/gcc/gengtype-state.c
@@ -961,6 +961,8 @@ write_state_type (type_p current)
current->state_number = state_written_type_count;
switch (current->kind)
{
+ case TYPE_NONE:
+ gcc_unreachable ();
case TYPE_STRUCT:
write_state_struct_type (current);
break;
@@ -988,9 +990,6 @@ write_state_type (type_p current)
case TYPE_STRING:
write_state_string_type (current);
break;
-
- default:
- fatal ("Unexpected type...");
}
}
@@ -1318,7 +1317,6 @@ read_state_scalar_char_type (type_p *type)
read_state_common_type_content (*type);
}
-
/* Read the string_type. */
static void
read_state_string_type (type_p *type)
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 213567653fe..b9fbd96fcbf 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -497,10 +497,10 @@ struct type scalar_char = {
/* Lists of various things. */
-pair_p typedefs;
-type_p structures;
-type_p param_structs;
-pair_p variables;
+pair_p typedefs = NULL;
+type_p structures = NULL;
+type_p param_structs = NULL;
+pair_p variables = NULL;
static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
static type_p adjust_field_tree_exp (type_p t, options_p opt);
@@ -611,6 +611,7 @@ resolve_typedef (const char *s, struct fileloc *pos)
return create_user_defined_type (s, pos);
}
+
/* Create and return a new structure with tag NAME at POS with fields
FIELDS and options O. The KIND of structure must be one of
TYPE_STRUCT, TYPE_UNION or TYPE_USER_STRUCT. */
@@ -676,8 +677,7 @@ new_structure (const char *name, enum typekind kind, struct fileloc *pos,
structures = s;
}
- if (s->u.s.line.file != NULL
- || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
+ if (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap))
{
error_at_line (pos, "duplicate definition of '%s %s'",
isunion ? "union" : "struct", s->u.s.tag);
@@ -763,6 +763,7 @@ create_scalar_type (const char *name)
return &scalar_nonchar;
}
+
/* Return a pointer to T. */
type_p
@@ -2636,7 +2637,7 @@ walk_type (type_p t, struct walk_type_data *d)
/* If a pointer type is marked as "atomic", we process the
field itself, but we don't walk the data that they point to.
-
+
There are two main cases where we walk types: to mark
pointers that are reachable, and to relocate pointers when
writing a PCH file. In both cases, an atomic pointer is
@@ -3514,7 +3515,7 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
{
oprintf (d.of, " %s (x);\n", mark_hook_name);
}
-
+
d.prev_val[2] = "*x";
d.indent = 6;
if (orig_s->kind != TYPE_USER_STRUCT)
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index 4a178ec3967..e687e488567 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -308,7 +308,6 @@ struct type {
type_p param[NUM_PARAM]; /* The actual parameter types. */
struct fileloc line; /* The source location. */
} param_struct;
-
} u;
};
@@ -444,38 +443,38 @@ extern void parse_file (const char *name);
extern bool hit_error;
/* Token codes. */
-enum
- {
- EOF_TOKEN = 0,
-
- /* Per standard convention, codes in the range (0, UCHAR_MAX]
- represent single characters with those character codes. */
-
- CHAR_TOKEN_OFFSET = UCHAR_MAX + 1,
- GTY_TOKEN = CHAR_TOKEN_OFFSET,
- TYPEDEF,
- EXTERN,
- STATIC,
- UNION,
- STRUCT,
- ENUM,
- VEC_TOKEN,
- ELLIPSIS,
- PTR_ALIAS,
- NESTED_PTR,
- USER_GTY,
- PARAM_IS,
- NUM,
- SCALAR,
- ID,
- STRING,
- CHAR,
- ARRAY,
-
- /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have
- a meaningful value to be printed. */
- FIRST_TOKEN_WITH_VALUE = PARAM_IS
- };
+enum gty_token
+{
+ EOF_TOKEN = 0,
+
+ /* Per standard convention, codes in the range (0, UCHAR_MAX]
+ represent single characters with those character codes. */
+ CHAR_TOKEN_OFFSET = UCHAR_MAX + 1,
+ GTY_TOKEN = CHAR_TOKEN_OFFSET,
+ TYPEDEF,
+ EXTERN,
+ STATIC,
+ UNION,
+ STRUCT,
+ ENUM,
+ VEC_TOKEN,
+ ELLIPSIS,
+ PTR_ALIAS,
+ NESTED_PTR,
+ USER_GTY,
+ PARAM_IS,
+ NUM,
+ SCALAR,
+ ID,
+ STRING,
+ CHAR,
+ ARRAY,
+ IGNORABLE_CXX_KEYWORD,
+
+ /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have
+ a meaningful value to be printed. */
+ FIRST_TOKEN_WITH_VALUE = PARAM_IS
+};
/* Level for verbose messages, e.g. output file generation... */
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 2c6104cb25a..d736d2c027f 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 979715ab95e..14e7007e56c 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. */
@@ -7683,6 +7696,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
}
case FMA_EXPR:
+ case VEC_COND_EXPR:
case VEC_PERM_EXPR:
/* Classified as tcc_expression. */
goto expr_3;
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index f45caf48771..838d3a5161d 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -6633,7 +6633,7 @@ sched_init (void)
/* We need info about pseudos for rtl dumps about pseudo
classes and costs. */
regstat_init_n_sets_and_refs ();
- ira_set_pseudo_classes (sched_verbose ? sched_dump : NULL);
+ ira_set_pseudo_classes (true, sched_verbose ? sched_dump : NULL);
sched_regno_pressure_class
= (enum reg_class *) xmalloc (max_regno * sizeof (enum reg_class));
for (i = 0; i < max_regno; i++)
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 2f486a231b7..5654c667547 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/ira-build.c b/gcc/ira-build.c
index 1181813d92b..986bb5e5f62 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -1458,6 +1458,96 @@ finish_cost_vectors (void)
+/* Compute a post-ordering of the reverse control flow of the loop body
+ designated by the children nodes of LOOP_NODE, whose body nodes in
+ pre-order are input as LOOP_PREORDER. Return a VEC with a post-order
+ of the reverse loop body.
+
+ For the post-order of the reverse CFG, we visit the basic blocks in
+ LOOP_PREORDER array in the reverse order of where they appear.
+ This is important: We do not just want to compute a post-order of
+ the reverse CFG, we want to make a best-guess for a visiting order that
+ minimizes the number of chain elements per allocno live range. If the
+ blocks would be visited in a different order, we would still compute a
+ correct post-ordering but it would be less likely that two nodes
+ connected by an edge in the CFG are neighbours in the topsort. */
+
+static VEC (ira_loop_tree_node_t, heap) *
+ira_loop_tree_body_rev_postorder (ira_loop_tree_node_t loop_node ATTRIBUTE_UNUSED,
+ VEC (ira_loop_tree_node_t, heap) *loop_preorder)
+{
+ VEC (ira_loop_tree_node_t, heap) *topsort_nodes = NULL;
+ unsigned int n_loop_preorder;
+
+ n_loop_preorder = VEC_length (ira_loop_tree_node_t, loop_preorder);
+ if (n_loop_preorder != 0)
+ {
+ ira_loop_tree_node_t subloop_node;
+ unsigned int i;
+ VEC (ira_loop_tree_node_t, heap) *dfs_stack;
+
+ /* This is a bit of strange abuse of the BB_VISITED flag: We use
+ the flag to mark blocks we still have to visit to add them to
+ our post-order. Define an alias to avoid confusion. */
+#define BB_TO_VISIT BB_VISITED
+
+ FOR_EACH_VEC_ELT (ira_loop_tree_node_t, loop_preorder, i, subloop_node)
+ {
+ gcc_checking_assert (! (subloop_node->bb->flags & BB_TO_VISIT));
+ subloop_node->bb->flags |= BB_TO_VISIT;
+ }
+
+ topsort_nodes = VEC_alloc (ira_loop_tree_node_t, heap, n_loop_preorder);
+ dfs_stack = VEC_alloc (ira_loop_tree_node_t, heap, n_loop_preorder);
+
+ FOR_EACH_VEC_ELT_REVERSE (ira_loop_tree_node_t, loop_preorder,
+ i, subloop_node)
+ {
+ if (! (subloop_node->bb->flags & BB_TO_VISIT))
+ continue;
+
+ subloop_node->bb->flags &= ~BB_TO_VISIT;
+ VEC_quick_push (ira_loop_tree_node_t, dfs_stack, subloop_node);
+ while (! VEC_empty (ira_loop_tree_node_t, dfs_stack))
+ {
+ edge e;
+ edge_iterator ei;
+
+ ira_loop_tree_node_t n = VEC_last (ira_loop_tree_node_t,
+ dfs_stack);
+ FOR_EACH_EDGE (e, ei, n->bb->preds)
+ {
+ ira_loop_tree_node_t pred_node;
+ basic_block pred_bb = e->src;
+
+ if (e->src == ENTRY_BLOCK_PTR)
+ continue;
+
+ pred_node = IRA_BB_NODE_BY_INDEX (pred_bb->index);
+ if (pred_node != n
+ && (pred_node->bb->flags & BB_TO_VISIT))
+ {
+ pred_node->bb->flags &= ~BB_TO_VISIT;
+ VEC_quick_push (ira_loop_tree_node_t, dfs_stack, pred_node);
+ }
+ }
+ if (n == VEC_last (ira_loop_tree_node_t, dfs_stack))
+ {
+ VEC_pop (ira_loop_tree_node_t, dfs_stack);
+ VEC_quick_push (ira_loop_tree_node_t, topsort_nodes, n);
+ }
+ }
+ }
+
+#undef BB_TO_VISIT
+ VEC_free (ira_loop_tree_node_t, heap, dfs_stack);
+ }
+
+ gcc_assert (VEC_length (ira_loop_tree_node_t, topsort_nodes)
+ == n_loop_preorder);
+ return topsort_nodes;
+}
+
/* The current loop tree node and its regno allocno map. */
ira_loop_tree_node_t ira_curr_loop_tree_node;
ira_allocno_t *ira_curr_regno_allocno_map;
@@ -1467,7 +1557,16 @@ ira_allocno_t *ira_curr_regno_allocno_map;
correspondingly in preorder and postorder. The function sets up
IRA_CURR_LOOP_TREE_NODE and IRA_CURR_REGNO_ALLOCNO_MAP. If BB_P,
basic block nodes of LOOP_NODE is also processed (before its
- subloop nodes). */
+ subloop nodes).
+
+ If BB_P is set and POSTORDER_FUNC is given, the basic blocks in
+ the loop are passed in the *reverse* post-order of the *reverse*
+ CFG. This is only used by ira_create_allocno_live_ranges, which
+ wants to visit basic blocks in this order to minimize the number
+ of elements per live range chain.
+ Note that the loop tree nodes are still visited in the normal,
+ forward post-order of the loop tree. */
+
void
ira_traverse_loop_tree (bool bb_p, ira_loop_tree_node_t loop_node,
void (*preorder_func) (ira_loop_tree_node_t),
@@ -1483,18 +1582,37 @@ ira_traverse_loop_tree (bool bb_p, ira_loop_tree_node_t loop_node,
(*preorder_func) (loop_node);
if (bb_p)
- for (subloop_node = loop_node->children;
- subloop_node != NULL;
- subloop_node = subloop_node->next)
- if (subloop_node->bb != NULL)
- {
- if (preorder_func != NULL)
- (*preorder_func) (subloop_node);
+ {
+ VEC (ira_loop_tree_node_t, heap) *loop_preorder = NULL;
+ unsigned int i;
+
+ /* Add all nodes to the set of nodes to visit. The IRA loop tree
+ is set up such that nodes in the loop body appear in a pre-order
+ of their place in the CFG. */
+ for (subloop_node = loop_node->children;
+ subloop_node != NULL;
+ subloop_node = subloop_node->next)
+ if (subloop_node->bb != NULL)
+ VEC_safe_push (ira_loop_tree_node_t, heap,
+ loop_preorder, subloop_node);
+
+ if (preorder_func != NULL)
+ FOR_EACH_VEC_ELT (ira_loop_tree_node_t, loop_preorder, i, subloop_node)
+ (*preorder_func) (subloop_node);
- if (postorder_func != NULL)
+ if (postorder_func != NULL)
+ {
+ VEC (ira_loop_tree_node_t, heap) *loop_rev_postorder =
+ ira_loop_tree_body_rev_postorder (loop_node, loop_preorder);
+ FOR_EACH_VEC_ELT_REVERSE (ira_loop_tree_node_t, loop_rev_postorder,
+ i, subloop_node)
(*postorder_func) (subloop_node);
+ VEC_free (ira_loop_tree_node_t, heap, loop_rev_postorder);
}
+ VEC_free (ira_loop_tree_node_t, heap, loop_preorder);
+ }
+
for (subloop_node = loop_node->subloops;
subloop_node != NULL;
subloop_node = subloop_node->subloop_next)
@@ -1597,7 +1715,7 @@ create_bb_allocnos (ira_loop_tree_node_t bb_node)
create_insn_allocnos (PATTERN (insn), false);
/* It might be a allocno living through from one subloop to
another. */
- EXECUTE_IF_SET_IN_REG_SET (DF_LR_IN (bb), FIRST_PSEUDO_REGISTER, i, bi)
+ EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (bb), FIRST_PSEUDO_REGISTER, i, bi)
if (ira_curr_regno_allocno_map[i] == NULL)
ira_create_allocno (i, false, ira_curr_loop_tree_node);
}
@@ -1613,9 +1731,9 @@ create_loop_allocnos (edge e)
bitmap_iterator bi;
ira_loop_tree_node_t parent;
- live_in_regs = DF_LR_IN (e->dest);
+ live_in_regs = df_get_live_in (e->dest);
border_allocnos = ira_curr_loop_tree_node->border_allocnos;
- EXECUTE_IF_SET_IN_REG_SET (DF_LR_OUT (e->src),
+ EXECUTE_IF_SET_IN_REG_SET (df_get_live_out (e->src),
FIRST_PSEUDO_REGISTER, i, bi)
if (bitmap_bit_p (live_in_regs, i))
{
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index fc2e4e8b29b..bcf03216af8 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -2014,8 +2014,8 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
if (e->src != loop_node->loop->latch
&& (regno < 0
- || (bitmap_bit_p (DF_LR_OUT (e->src), regno)
- && bitmap_bit_p (DF_LR_IN (e->dest), regno))))
+ || (bitmap_bit_p (df_get_live_out (e->src), regno)
+ && bitmap_bit_p (df_get_live_in (e->dest), regno))))
freq += EDGE_FREQUENCY (e);
}
else
@@ -2023,8 +2023,8 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
edges = get_loop_exit_edges (loop_node->loop);
FOR_EACH_VEC_ELT (edge, edges, i, e)
if (regno < 0
- || (bitmap_bit_p (DF_LR_OUT (e->src), regno)
- && bitmap_bit_p (DF_LR_IN (e->dest), regno)))
+ || (bitmap_bit_p (df_get_live_out (e->src), regno)
+ && bitmap_bit_p (df_get_live_in (e->dest), regno)))
freq += EDGE_FREQUENCY (e);
VEC_free (edge, heap, edges);
}
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index 583629bf5a0..d124ef28cab 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -860,7 +860,7 @@ ira_build_conflicts (void)
ira_object_iterator oi;
build_conflicts ();
- ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, add_copies);
+ ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
/* We need finished conflict table for the subsequent call. */
if (flag_ira_region == IRA_REGION_ALL
|| flag_ira_region == IRA_REGION_MIXED)
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 0c59b03ded2..034eff831ed 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -2048,9 +2048,10 @@ ira_costs (void)
ira_free (total_allocno_costs);
}
-/* Entry function which defines classes for pseudos. */
+/* Entry function which defines classes for pseudos.
+ Set pseudo_classes_defined_p only if DEFINE_PSEUDO_CLASSES is true. */
void
-ira_set_pseudo_classes (FILE *dump_file)
+ira_set_pseudo_classes (bool define_pseudo_classes, FILE *dump_file)
{
allocno_p = false;
internal_flag_ira_verbose = flag_ira_verbose;
@@ -2059,7 +2060,9 @@ ira_set_pseudo_classes (FILE *dump_file)
initiate_regno_cost_classes ();
find_costs_and_classes (dump_file);
finish_regno_cost_classes ();
- pseudo_classes_defined_p = true;
+ if (define_pseudo_classes)
+ pseudo_classes_defined_p = true;
+
finish_costs ();
}
diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index dbab5374173..b0d9a825124 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -495,6 +495,7 @@ generate_edge_moves (edge e)
bitmap_iterator bi;
ira_allocno_t src_allocno, dest_allocno, *src_map, *dest_map;
move_t move;
+ bitmap regs_live_in_dest, regs_live_out_src;
src_loop_node = IRA_BB_NODE (e->src)->parent;
dest_loop_node = IRA_BB_NODE (e->dest)->parent;
@@ -503,9 +504,11 @@ generate_edge_moves (edge e)
return;
src_map = src_loop_node->regno_allocno_map;
dest_map = dest_loop_node->regno_allocno_map;
- EXECUTE_IF_SET_IN_REG_SET (DF_LR_IN (e->dest),
+ regs_live_in_dest = df_get_live_in (e->dest);
+ regs_live_out_src = df_get_live_out (e->src);
+ EXECUTE_IF_SET_IN_REG_SET (regs_live_in_dest,
FIRST_PSEUDO_REGISTER, regno, bi)
- if (bitmap_bit_p (DF_LR_OUT (e->src), regno))
+ if (bitmap_bit_p (regs_live_out_src, regno))
{
src_allocno = src_map[regno];
dest_allocno = dest_map[regno];
@@ -1206,15 +1209,16 @@ add_ranges_and_copies (void)
destination block) to use for searching allocnos by their
regnos because of subsequent IR flattening. */
node = IRA_BB_NODE (bb)->parent;
- bitmap_copy (live_through, DF_LR_IN (bb));
+ bitmap_copy (live_through, df_get_live_in (bb));
add_range_and_copies_from_move_list
(at_bb_start[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
- bitmap_copy (live_through, DF_LR_OUT (bb));
+ bitmap_copy (live_through, df_get_live_out (bb));
add_range_and_copies_from_move_list
(at_bb_end[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
FOR_EACH_EDGE (e, ei, bb->succs)
{
- bitmap_and (live_through, DF_LR_IN (e->dest), DF_LR_OUT (bb));
+ bitmap_and (live_through,
+ df_get_live_in (e->dest), df_get_live_out (bb));
add_range_and_copies_from_move_list
((move_t) e->aux, node, live_through,
REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e)));
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 853832e3c9f..940cd681f2a 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -1148,7 +1148,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
high_pressure_start_point[ira_pressure_classes[i]] = -1;
}
curr_bb_node = loop_tree_node;
- reg_live_out = DF_LR_OUT (bb);
+ reg_live_out = df_get_live_out (bb);
sparseset_clear (objects_live);
REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out);
AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset);
@@ -1458,7 +1458,7 @@ remove_some_program_points_and_update_live_ranges (void)
int *map;
ira_object_t obj;
ira_object_iterator oi;
- live_range_t r;
+ live_range_t r, prev_r, next_r;
sbitmap born_or_dead, born, dead;
sbitmap_iterator sbi;
bool born_p, dead_p, prev_born_p, prev_dead_p;
@@ -1502,10 +1502,19 @@ remove_some_program_points_and_update_live_ranges (void)
ira_max_point = n;
FOR_EACH_OBJECT (obj, oi)
- for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
+ for (r = OBJECT_LIVE_RANGES (obj), prev_r = NULL; r != NULL; r = next_r)
{
+ next_r = r->next;
r->start = map[r->start];
r->finish = map[r->finish];
+ if (prev_r == NULL || prev_r->start > r->finish + 1)
+ {
+ prev_r = r;
+ continue;
+ }
+ prev_r->start = r->start;
+ prev_r->next = next_r;
+ ira_finish_live_range (r);
}
ira_free (map);
diff --git a/gcc/ira.c b/gcc/ira.c
index 4a7dcb52043..78b3f92db00 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2337,16 +2337,23 @@ void
mark_elimination (int from, int to)
{
basic_block bb;
+ bitmap r;
FOR_EACH_BB (bb)
{
- /* We don't use LIVE info in IRA. */
- bitmap r = DF_LR_IN (bb);
-
- if (REGNO_REG_SET_P (r, from))
+ r = DF_LR_IN (bb);
+ if (bitmap_bit_p (r, from))
+ {
+ bitmap_clear_bit (r, from);
+ bitmap_set_bit (r, to);
+ }
+ if (! df_live)
+ continue;
+ r = DF_LIVE_IN (bb);
+ if (bitmap_bit_p (r, from))
{
- CLEAR_REGNO_REG_SET (r, from);
- SET_REGNO_REG_SET (r, to);
+ bitmap_clear_bit (r, from);
+ bitmap_set_bit (r, to);
}
}
}
@@ -3194,10 +3201,12 @@ update_equiv_regs (void)
{
FOR_EACH_BB (bb)
{
- bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
- bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
+ if (! df_live)
+ continue;
+ bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
}
/* Last pass - adjust debug insns referencing cleared regs. */
@@ -3319,14 +3328,14 @@ build_insn_chain (void)
CLEAR_REG_SET (live_relevant_regs);
bitmap_clear (live_subregs_used);
- EXECUTE_IF_SET_IN_BITMAP (DF_LR_OUT (bb), 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), 0, i, bi)
{
if (i >= FIRST_PSEUDO_REGISTER)
break;
bitmap_set_bit (live_relevant_regs, i);
}
- EXECUTE_IF_SET_IN_BITMAP (DF_LR_OUT (bb),
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb),
FIRST_PSEUDO_REGISTER, i, bi)
{
if (pseudo_for_reload_consideration_p (i))
@@ -4157,12 +4166,6 @@ ira (FILE *f)
setup_prohibited_mode_move_regs ();
df_note_add_problem ();
-
- if (optimize == 1)
- {
- df_live_add_problem ();
- df_live_set_all_dirty ();
- }
#ifdef ENABLE_CHECKING
df->changeable_flags |= DF_VERIFY_SCHEDULED;
#endif
@@ -4183,7 +4186,7 @@ ira (FILE *f)
crtl->is_leaf = leaf_function_p ();
if (resize_reg_info () && flag_ira_loop_pressure)
- ira_set_pseudo_classes (ira_dump_file);
+ ira_set_pseudo_classes (true, ira_dump_file);
rebuild_p = update_equiv_regs ();
@@ -4233,8 +4236,8 @@ ira (FILE *f)
if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
{
flow_loops_find (&ira_loops);
- record_loop_exits ();
current_loops = &ira_loops;
+ record_loop_exits ();
}
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
@@ -4277,9 +4280,14 @@ ira (FILE *f)
info. */
df_analyze ();
+ /* ??? Rebuild the loop tree, but why? Does the loop tree
+ change if new insns were generated? Can that be handled
+ by updating the loop tree incrementally? */
+ release_recorded_exits ();
+ flow_loops_free (&ira_loops);
flow_loops_find (&ira_loops);
- record_loop_exits ();
current_loops = &ira_loops;
+ record_loop_exits ();
setup_allocno_assignment_flags ();
ira_initiate_assign ();
@@ -4363,6 +4371,7 @@ do_reload (void)
if (current_loops != NULL)
{
+ release_recorded_exits ();
flow_loops_free (&ira_loops);
free_dominance_info (CDI_DOMINATORS);
}
@@ -4391,8 +4400,6 @@ do_reload (void)
df_rescan_all_insns is not going to help here because it does not
touch the artificial uses and defs. */
df_finish_pass (true);
- if (optimize > 1)
- df_live_add_problem ();
df_scan_alloc (NULL);
df_scan_blocks ();
diff --git a/gcc/ira.h b/gcc/ira.h
index 6870c4bf303..0cafdf4a94c 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -1,6 +1,6 @@
/* Communication between the Integrated Register Allocator (IRA) and
the rest of the compiler.
- Copyright (C) 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012
Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
@@ -131,7 +131,7 @@ extern void ira_init (void);
extern void ira_finish_once (void);
extern void ira_setup_eliminable_regset (void);
extern rtx ira_eliminate_regs (rtx, enum machine_mode);
-extern void ira_set_pseudo_classes (FILE *);
+extern void ira_set_pseudo_classes (bool, FILE *);
extern void ira_implicitly_set_insn_hard_regs (HARD_REG_SET *);
extern void ira_sort_regnos_for_alter_reg (int *, int, unsigned int *);
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 8dcfea5bba8..3ab19cae932 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 a420569fd43..996e6e3a645 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -1,5 +1,5 @@
/* RTL-level loop invariant motion.
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -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;
@@ -1923,7 +1939,7 @@ move_loop_invariants (void)
{
df_analyze ();
regstat_init_n_sets_and_refs ();
- ira_set_pseudo_classes (dump_file);
+ ira_set_pseudo_classes (true, dump_file);
calculate_loop_reg_pressure ();
regstat_free_n_sets_and_refs ();
}
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 658f20360f7..43d3c4e3ede 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))
@@ -2004,11 +2004,30 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
}
}
else
- /* If we did not use this insn to make a replacement, any overlap
- between stores in this insn and our expression will cause the
- expression to become invalid. */
- if (for_each_rtx (expr, altered_reg_used, this_altered))
- goto out;
+ {
+ rtx *pnote, *pnote_next;
+
+ /* If we did not use this insn to make a replacement, any overlap
+ between stores in this insn and our expression will cause the
+ expression to become invalid. */
+ if (for_each_rtx (expr, altered_reg_used, this_altered))
+ goto out;
+
+ /* Likewise for the conditions. */
+ for (pnote = &cond_list; *pnote; pnote = pnote_next)
+ {
+ rtx note = *pnote;
+ rtx old_cond = XEXP (note, 0);
+
+ pnote_next = &XEXP (note, 1);
+ if (for_each_rtx (&old_cond, altered_reg_used, this_altered))
+ {
+ *pnote = *pnote_next;
+ pnote_next = pnote;
+ free_EXPR_LIST_node (note);
+ }
+ }
+ }
if (CONSTANT_P (*expr))
goto out;
@@ -2224,13 +2243,18 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
rtx niter = desc->niter_expr;
rtx mmin, mmax, cmp;
unsigned HOST_WIDEST_INT nmax, inc;
+ unsigned HOST_WIDEST_INT andmax = 0;
+
+ /* We used to look for constant operand 0 of AND,
+ but canonicalization should always make this impossible. */
+ gcc_checking_assert (GET_CODE (niter) != AND
+ || !CONST_INT_P (XEXP (niter, 0)));
if (GET_CODE (niter) == AND
- && CONST_INT_P (XEXP (niter, 0)))
+ && CONST_INT_P (XEXP (niter, 1)))
{
- nmax = INTVAL (XEXP (niter, 0));
- if (!(nmax & (nmax + 1)))
- return nmax;
+ andmax = UINTVAL (XEXP (niter, 1));
+ niter = XEXP (niter, 0);
}
get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax);
@@ -2258,7 +2282,13 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
if (dump_file)
fprintf (dump_file, ";; improved upper bound by one.\n");
}
- return nmax / inc;
+ nmax /= inc;
+ if (andmax)
+ nmax = MIN (nmax, andmax);
+ if (dump_file)
+ fprintf (dump_file, ";; Determined upper bound "HOST_WIDEST_INT_PRINT_DEC".\n",
+ nmax);
+ return nmax;
}
/* Computes number of iterations of the CONDITION in INSN in LOOP and stores
@@ -2563,7 +2593,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
? iv0.base
: mode_mmin);
max = (up - down) / inc + 1;
- record_niter_bound (loop, double_int::from_shwi (max),
+ record_niter_bound (loop, double_int::from_uhwi (max),
false, true);
if (iv0.step == const0_rtx)
@@ -2776,14 +2806,14 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
desc->const_iter = true;
desc->niter = val & GET_MODE_MASK (desc->mode);
- record_niter_bound (loop, double_int::from_shwi (desc->niter),
+ record_niter_bound (loop, double_int::from_uhwi (desc->niter),
false, true);
}
else
{
max = determine_max_iter (loop, desc, old_niter);
gcc_assert (max);
- record_niter_bound (loop, double_int::from_shwi (max),
+ record_niter_bound (loop, double_int::from_uhwi (max),
false, true);
/* simplify_using_initial_values does a copy propagation on the registers
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index b6dace030c1..0dd8b0a9d5c 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -100,10 +100,6 @@ struct var_to_expand
the accumulator. If REUSE_EXPANSION is 0 reuse
the original accumulator. Else use
var_expansions[REUSE_EXPANSION - 1]. */
- unsigned accum_pos; /* The position in which the accumulator is placed in
- the insn src. For example in x = x + something
- accum_pos is 0 while in x = something + x accum_pos
- is 1. */
};
/* Information about optimization applied in
@@ -602,26 +598,21 @@ decide_unroll_constant_iterations (struct loop *loop, int flags)
}
}
- if (dump_file)
- fprintf (dump_file, ";; max_unroll %d (%d copies, initial %d).\n",
- best_unroll + 1, best_copies, nunroll);
-
loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
loop->lpt_decision.times = best_unroll;
if (dump_file)
- fprintf (dump_file,
- ";; Decided to unroll the constant times rolling loop, %d times.\n",
- loop->lpt_decision.times);
+ fprintf (dump_file, ";; Decided to unroll the loop %d times (%d copies).\n",
+ loop->lpt_decision.times, best_copies);
}
-/* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES + 1
- times. The transformation does this:
+/* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES times.
+ The transformation does this:
for (i = 0; i < 102; i++)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
i = 0;
body; i++;
@@ -671,7 +662,7 @@ unroll_loop_constant_iterations (struct loop *loop)
of exit condition have continuous body after unrolling. */
if (dump_file)
- fprintf (dump_file, ";; Condition on beginning of loop.\n");
+ fprintf (dump_file, ";; Condition at beginning of loop.\n");
/* Peel exit_mod iterations. */
RESET_BIT (wont_exit, 0);
@@ -713,7 +704,7 @@ unroll_loop_constant_iterations (struct loop *loop)
the loop tests the condition at the end of loop body. */
if (dump_file)
- fprintf (dump_file, ";; Condition on end of loop.\n");
+ fprintf (dump_file, ";; Condition at end of loop.\n");
/* We know that niter >= max_unroll + 2; so we do not need to care of
case when we would exit before reaching the loop. So just peel
@@ -896,9 +887,7 @@ decide_unroll_runtime_iterations (struct loop *loop, int flags)
loop->lpt_decision.times = i - 1;
if (dump_file)
- fprintf (dump_file,
- ";; Decided to unroll the runtime computable "
- "times rolling loop, %d times.\n",
+ fprintf (dump_file, ";; Decided to unroll the loop %d times.\n",
loop->lpt_decision.times);
}
@@ -949,14 +938,14 @@ split_edge_and_insert (edge e, rtx insns)
return bb;
}
-/* Unroll LOOP for that we are able to count number of iterations in runtime
- LOOP->LPT_DECISION.TIMES + 1 times. The transformation does this (with some
+/* Unroll LOOP for which we are able to count number of iterations in runtime
+ LOOP->LPT_DECISION.TIMES times. The transformation does this (with some
extra care for case n < 0):
for (i = 0; i < n; i++)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
i = 0;
mod = n % 4;
@@ -1314,20 +1303,23 @@ decide_peel_simple (struct loop *loop, int flags)
loop->lpt_decision.times = npeel;
if (dump_file)
- fprintf (dump_file, ";; Decided to simply peel the loop, %d times.\n",
+ fprintf (dump_file, ";; Decided to simply peel the loop %d times.\n",
loop->lpt_decision.times);
}
-/* Peel a LOOP LOOP->LPT_DECISION.TIMES times. The transformation:
+/* Peel a LOOP LOOP->LPT_DECISION.TIMES times. The transformation does this:
+
while (cond)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
if (!cond) goto end;
body;
if (!cond) goto end;
body;
+ if (!cond) goto end;
+ body;
while (cond)
body;
end: ;
@@ -1464,16 +1456,16 @@ decide_unroll_stupid (struct loop *loop, int flags)
loop->lpt_decision.times = i - 1;
if (dump_file)
- fprintf (dump_file,
- ";; Decided to unroll the loop stupidly, %d times.\n",
+ fprintf (dump_file, ";; Decided to unroll the loop stupidly %d times.\n",
loop->lpt_decision.times);
}
-/* Unroll a LOOP LOOP->LPT_DECISION.TIMES times. The transformation:
+/* Unroll a LOOP LOOP->LPT_DECISION.TIMES times. The transformation does this:
+
while (cond)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
while (cond)
{
@@ -1767,7 +1759,6 @@ analyze_insn_to_expand_var (struct loop *loop, rtx insn)
ves->op = GET_CODE (src);
ves->expansion_count = 0;
ves->reuse_expansion = 0;
- ves->accum_pos = accum_pos;
return ves;
}
@@ -2127,9 +2118,7 @@ expand_var_during_unrolling (struct var_to_expand *ve, rtx insn)
else
new_reg = get_expansion (ve);
- validate_change (insn, &SET_DEST (set), new_reg, 1);
- validate_change (insn, &XEXP (SET_SRC (set), ve->accum_pos), new_reg, 1);
-
+ validate_replace_rtx_group (SET_DEST (set), new_reg, insn);
if (apply_change_group ())
if (really_new_expansion)
{
@@ -2169,7 +2158,7 @@ static void
insert_var_expansion_initialization (struct var_to_expand *ve,
basic_block place)
{
- rtx seq, var, zero_init, insn;
+ rtx seq, var, zero_init;
unsigned i;
enum machine_mode mode = GET_MODE (ve->reg);
bool honor_signed_zero_p = HONOR_SIGNED_ZEROS (mode);
@@ -2209,11 +2198,7 @@ insert_var_expansion_initialization (struct var_to_expand *ve,
seq = get_insns ();
end_sequence ();
- insn = BB_HEAD (place);
- while (!NOTE_INSN_BASIC_BLOCK_P (insn))
- insn = NEXT_INSN (insn);
-
- emit_insn_after (seq, insn);
+ emit_insn_after (seq, BB_END (place));
}
/* Combine the variable expansions at the loop exit. PLACE is the
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index 4107048de01..25d77dab22f 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 a5d13eec5ff..15905f859a4 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 55a20dd134b..806045b52bf 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 c7b7ef94871..c9d13aea4da 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/lto/ChangeLog b/gcc/lto/ChangeLog
index 265922f5d13..49b8af0235d 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,10 @@
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ PR lto/54898
+ * lto.c (gimple_types_compatible_p_1): Also compare
+ TYPE_MAIN_VARIANT.
+ (iterative_hash_gimple_type): Also hash TYPE_MAIN_VARIANT.
+
2012-10-09 Tobias Burnus <burnus@net-b.de>
* lto-lang.c (lto_register_builtin_type): Avoid useless
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 2b9156aebba..7f64daee219 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -581,6 +581,15 @@ gimple_types_compatible_p_1 (tree t1, tree t2, type_pair_t p,
if (!compare_type_names_p (t1, t2))
goto different_types;
+ /* The main variant of both types should compare equal. */
+ if (TYPE_MAIN_VARIANT (t1) != t1
+ || TYPE_MAIN_VARIANT (t2) != t2)
+ {
+ if (!gtc_visit (TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2),
+ state, sccstack, sccstate, sccstate_obstack))
+ goto different_types;
+ }
+
/* We may not merge typedef types to the same type in different
contexts. */
if (TYPE_NAME (t1)
@@ -1101,6 +1110,12 @@ iterative_hash_gimple_type (tree type, hashval_t val,
&& TYPE_P (DECL_CONTEXT (TYPE_NAME (type))))
v = visit (DECL_CONTEXT (TYPE_NAME (type)), state, v,
sccstack, sccstate, sccstate_obstack);
+
+ /* Factor in the variant structure. */
+ if (TYPE_MAIN_VARIANT (type) != type)
+ v = visit (TYPE_MAIN_VARIANT (type), state, v,
+ sccstack, sccstate, sccstate_obstack);
+
v = iterative_hash_hashval_t (TREE_CODE (type), v);
v = iterative_hash_hashval_t (TYPE_QUALS (type), v);
v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
index 8b025b2cf32..13de5e48ed1 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 8a6c6a330b4..e22031615fa 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);
}
@@ -6388,20 +6402,14 @@ get_rtx_code (enum tree_code tcode, bool unsignedp)
unsigned operators. Do not generate compare instruction. */
static rtx
-vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
+vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
+ bool unsignedp, enum insn_code icode)
{
struct expand_operand ops[2];
- enum rtx_code rcode;
- tree t_op0, t_op1;
rtx rtx_op0, rtx_op1;
+ enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
- /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
- ensures that condition is a relational operation. */
- gcc_assert (COMPARISON_CLASS_P (cond));
-
- rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
- t_op0 = TREE_OPERAND (cond, 0);
- t_op1 = TREE_OPERAND (cond, 1);
+ gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
/* Expand operands. */
rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
@@ -6684,11 +6692,26 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
enum machine_mode mode = TYPE_MODE (vec_cond_type);
enum machine_mode cmp_op_mode;
bool unsignedp;
+ tree op0a, op0b;
+ enum tree_code tcode;
- gcc_assert (COMPARISON_CLASS_P (op0));
+ if (COMPARISON_CLASS_P (op0))
+ {
+ op0a = TREE_OPERAND (op0, 0);
+ op0b = TREE_OPERAND (op0, 1);
+ tcode = TREE_CODE (op0);
+ }
+ else
+ {
+ /* Fake op0 < 0. */
+ gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0)));
+ op0a = op0;
+ op0b = build_zero_cst (TREE_TYPE (op0));
+ tcode = LT_EXPR;
+ }
+ unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
+ cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
- unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)));
- cmp_op_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0)));
gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
&& GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
@@ -6697,7 +6720,7 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
if (icode == CODE_FOR_nothing)
return 0;
- comparison = vector_compare_rtx (op0, unsignedp, icode);
+ comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
rtx_op1 = expand_normal (op1);
rtx_op2 = expand_normal (op2);
@@ -6943,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/optabs.def b/gcc/optabs.def
index 9f6b29cd3e5..b483b0274e7 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -306,3 +306,6 @@ OPTAB_D (atomic_sub_fetch_optab, "atomic_sub_fetch$I$a")
OPTAB_D (atomic_sub_optab, "atomic_sub$I$a")
OPTAB_D (atomic_xor_fetch_optab, "atomic_xor_fetch$I$a")
OPTAB_D (atomic_xor_optab, "atomic_xor$I$a")
+
+OPTAB_D (get_thread_pointer_optab, "get_thread_pointer$I$a")
+OPTAB_D (set_thread_pointer_optab, "set_thread_pointer$I$a")
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 0abe6bcf2a8..87575c22af1 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 8e583f03064..e98a66f5b58 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 ccfe3c70a91..98bbd302c8e 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 b464d1fdc3f..ab4f851b756 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 744878d8e63..3cda1a7c24e 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/regmove.c b/gcc/regmove.c
index 6ff8ef6191c..408366d9d2b 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -1,6 +1,7 @@
/* Move registers around to reduce number of move instructions needed.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -1237,7 +1238,7 @@ regmove_optimize (void)
regstat_compute_ri ();
if (flag_ira_loop_pressure)
- ira_set_pseudo_classes (dump_file);
+ ira_set_pseudo_classes (true, dump_file);
regno_src_regno = XNEWVEC (int, nregs);
for (i = nregs; --i >= 0; )
diff --git a/gcc/reload.c b/gcc/reload.c
index 2e41ed6498e..91521b16336 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 cd5d4352b86..09f1e773899 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 fb7d45cfb96..a19bdfdc0d1 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 936a1317bb7..b9ffb2d6118 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 fb3323e1910..14a28abcc58 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 c2e2f5b8d0e..a7e4d3e3041 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,361 @@
+2012-10-19 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/54981
+ * gcc.dg/pr54981.c: New testcase.
+
+2012-10-19 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ PR target/54892
+ * gcc.target/arm/pr54892.c: New.
+
+2012-10-19 Bin Cheng <bin.cheng@arm.com>
+
+ * testsuite/gcc.dg/hoist-register-pressure.c: New test.
+
+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
+ * gcc.dg/pr54919.c: New testcase.
+
+2012-10-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53581
+ * g++.dg/template/crash113.C: New.
+
+2012-10-14 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/unroll_5.c: New testcase.
+
+2012-10-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52643
+ * g++.dg/opt/pr52643.C: New.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54602
+ * gcc.target/sh/pr54602-1.c: New.
+ * gcc.target/sh/pr54602-2.c: New.
+ * gcc.target/sh/pr54602-3.c: New.
+ * gcc.target/sh/pr54602-4.c: New.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54680
+ * gcc.target/sh/pr54680.c: New.
+
+2012-10-12 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/webizer.c: New testcase.
+
+2012-10-12 Janis Johnson <janisjo@codesourcery.com>
+
+ * gcc.dg/vect/pr48765.c: Skip for conflicting options, don't
+ specify -m64.
+
+ * gcc.target/arm/div64-unwinding.c: Skip, don't xfail, for
+ GNU/Linux.
+
+ * lib/target-supports.exp (check_effective_target_arm_hard_vfp_ok):
+ Return 0 if already specifying -mfloat-abi other than hard.
+
+2012-10-12 Joe Seymour <jseymour@codesourcery.com>
+
+ * gcc.dg/pr53060.c: Prune irrelevant warning.
+
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * c-c++-common/Wsizeof-pointer-memaccess1.c: New test.
+ * c-c++-common/Wsizeof-pointer-memaccess2.c: New test.
+ * gcc.dg/Wsizeof-pointer-memaccess1.c: New test.
+ * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Test also stpncpy.
+ Adjust expected wording of warnings for *cmp* builtins.
+ * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
+ * g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24449
+ * g++.dg/parse/friend-main.C: New.
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * g++.dg/pr53055.C: New testcase.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52744
+ * g++.dg/cpp0x/pr52744.C: New.
+
+2012-10-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40453
+ * gfortran.dg/dummy_procedure_9.f90: New.
+
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/54894
+ * gcc.dg/torture/pr54894.c: New testcase.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * gcc.target/sh/pr51244-13.c: New.
+ * gcc.target/sh/pr51244-14.c: New.
+ * gcc.target/sh/pr51244-15.c: New.
+ * gcc.target/sh/pr51244-16.c: New.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51878
+ * g++.dg/cpp0x/decltype45.C: New.
+
+2012-10-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54784
+ * gfortran.dg/class_allocate_13.f90: New.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/ext/visibility/pragma-override1.C: Fix target markup.
+ * g++.dg/ext/visibility/pragma-override2.C: Fix target markup.
+
+ * g++.dg/gomp/tls-5.C: Require tls_native.
+ * g++.dg/tls/thread_local7.C: Require tls_native.
+ * g++.dg/tls/static2.C: New.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36107
+ * g++.dg/ext/weak5.C: New.
+
+2012-10-11 Marc Glisse <marc.glisse@inria.fr>
+
+ PR testsuite/54868
+ * gcc.dg/tree-ssa/forwprop-22.c: Move ...
+ * gcc.dg/vect/nodump-forwprop-22.c: ... here. Adapt options.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43765
+ * g++.dg/parse/pr43765.C: New.
+
+2012-10-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * obj-c++.dg/tls/init-2.mm: Tweak errors.
+
+2012-10-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43663
+ * g++.dg/init/bitfield3.C: New.
+
+2012-10-10 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/mips32-dsp-accinit-2.c: Fix test description.
+
+2012-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/54877
+ * gcc.dg/torture/pr54877.c: New test.
+
2012-10-10 Venkataramanan Kumar <venkataramanan.kumar@amd.com>
PR testsuite/53397
diff --git a/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c
new file mode 100644
index 00000000000..2a5f4193b21
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c
@@ -0,0 +1,161 @@
+/* Test -Wsizeof-pointer-memaccess warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int snprintf (char *, size_t, const char *, ...);
+extern int vsnprintf (char *, size_t, const char *, __builtin_va_list);
+extern void *memchr (const void *, int, size_t);
+#ifdef __cplusplus
+}
+#endif
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+void foo (void **);
+
+void
+f1 (void *x)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ void *arr[100];
+ int i = 0;
+ arr[i++] = memchr (&a, 0, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ arr[i++] = memchr (pa1, 0, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa2, 0, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa3, 0, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa4, 0, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa1, 0, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pa2, 0, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pa3, 0, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ arr[i++] = memchr (&a, 0, sizeof a);
+ arr[i++] = memchr (&a, 0, sizeof (a));
+ arr[i++] = memchr (&a, 0, sizeof (struct A));
+ arr[i++] = memchr (&a, 0, sizeof (const struct A));
+ arr[i++] = memchr (&a, 0, sizeof (volatile struct A));
+ arr[i++] = memchr (&a, 0, sizeof (volatile const struct A));
+ arr[i++] = memchr (&a, 0, sizeof (TA));
+ arr[i++] = memchr (&a, 0, sizeof (__typeof (*&a)));
+ arr[i++] = memchr (pa1, 0, sizeof (*pa1));
+ arr[i++] = memchr (pa2, 0, sizeof (*pa3));
+ arr[i++] = memchr (pa3, 0, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ arr[i++] = memchr ((void *) &a, 0, sizeof (&a));
+ arr[i++] = memchr ((char *) &a, 0, sizeof (&a));
+ arr[i++] = memchr (&a, 0, sizeof (&a) + 0);
+ arr[i++] = memchr (&a, 0, 0 + sizeof (&a));
+
+ foo (arr);
+}
+
+void
+f2 (void *x)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ void *arr[100];
+ int i = 0;
+ arr[i++] = memchr (&b, 0, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ arr[i++] = memchr (pb1, 0, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb2, 0, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb3, 0, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb4, 0, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb1, 0, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pb2, 0, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pb3, 0, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ arr[i++] = memchr (&b, 0, sizeof b);
+ arr[i++] = memchr (&b, 0, sizeof (b));
+ arr[i++] = memchr (&b, 0, sizeof (struct B));
+ arr[i++] = memchr (&b, 0, sizeof (const struct B));
+ arr[i++] = memchr (&b, 0, sizeof (volatile struct B));
+ arr[i++] = memchr (&b, 0, sizeof (volatile const struct B));
+ arr[i++] = memchr (&b, 0, sizeof (TB));
+ arr[i++] = memchr (&b, 0, sizeof (__typeof (*&b)));
+ arr[i++] = memchr (pb1, 0, sizeof (*pb1));
+ arr[i++] = memchr (pb2, 0, sizeof (*pb3));
+ arr[i++] = memchr (pb3, 0, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ arr[i++] = memchr ((void *) &b, 0, sizeof (&b));
+ arr[i++] = memchr ((char *) &b, 0, sizeof (&b));
+ arr[i++] = memchr (&b, 0, sizeof (&b) + 0);
+ arr[i++] = memchr (&b, 0, 0 + sizeof (&b));
+
+ foo (arr);
+}
+
+void
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ void *arr[100];
+ int i = 0;
+ arr[i++] = memchr (y, 0, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ arr[i++] = memchr (y1, 0, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ arr[i++] = memchr (y2, 0, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ arr[i++] = memchr (&c, 0, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ arr[i++] = memchr (w, 0, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ /* These are correct, no warning. */
+ arr[i++] = memchr (y, 0, sizeof (*y));
+ arr[i++] = memchr (y1, 0, sizeof (*y2));
+ arr[i++] = memchr (buf1, 0, sizeof buf1);
+ arr[i++] = memchr (buf3, 0, sizeof (buf3));
+ arr[i++] = memchr (&buf3[0], 0, sizeof (buf3));
+ arr[i++] = memchr (&buf4[0], 0, sizeof (buf4));
+ arr[i++] = memchr (w, 0, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ arr[i++] = memchr ((void *) y, 0, sizeof (y));
+ arr[i++] = memchr ((char *) y1, 0, sizeof (y2));
+ arr[i++] = memchr (y, 0, sizeof (y) + 0);
+ arr[i++] = memchr (y1, 0, 0 + sizeof (y2));
+ arr[i++] = memchr ((void *) &c, 0, sizeof (&c));
+ arr[i++] = memchr ((signed char *) &c, 0, sizeof (&c));
+ arr[i++] = memchr (&c, 0, sizeof (&c) + 0);
+ arr[i++] = memchr (&c, 0, 0 + sizeof (&c));
+
+ foo (arr);
+}
+
+void
+f4 (char x[64], char *y, __builtin_va_list ap)
+{
+ char buf[128], *p = buf;
+ snprintf (x, sizeof (x), "%s", y); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ vsnprintf (x, sizeof (x), "%s", ap); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ snprintf (p, sizeof (p), "%s", y); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ vsnprintf (p, sizeof (p), "%s", ap); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+
+ /* These are correct, no warning. */
+ snprintf (buf, sizeof (buf), "%s", y);
+ vsnprintf (buf, sizeof (buf), "%s", ap);
+ snprintf (p, sizeof (buf), "%s", y);
+ vsnprintf (p, sizeof (buf), "%s", ap);
+}
diff --git a/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c
new file mode 100644
index 00000000000..73cdf0eaba7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c
@@ -0,0 +1,482 @@
+/* Test -Wsizeof-pointer-memaccess warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+#define bos(ptr) __builtin_object_size (ptr, 1)
+#define bos0(ptr) __builtin_object_size (ptr, 0)
+
+#define memset(dst, val, sz) __builtin___memset_chk (dst, val, sz, bos (dst))
+#define memcpy(dst, src, sz) __builtin___memcpy_chk (dst, src, sz, bos (dst))
+#define memmove(dst, src, sz) __builtin___memmove_chk (dst, src, sz, bos (dst))
+#define strncpy(dst, src, sz) __builtin___strncpy_chk (dst, src, sz, bos (dst))
+#define strncat(dst, src, sz) __builtin___strncat_chk (dst, src, sz, bos (dst))
+#define stpncpy(dst, src, sz) __builtin___stpncpy_chk (dst, src, sz, bos (dst))
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+void
+f1 (void *x)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ memset (&a, 0, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memset (pa1, 0, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa2, 0, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa3, 0, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa4, 0, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa1, 0, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pa2, 0, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pa3, 0, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memcpy (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memcpy (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memmove (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pa4, x, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memmove (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ memset (&a, 0, sizeof a);
+ memset (&a, 0, sizeof (a));
+ memset (&a, 0, sizeof (struct A));
+ memset (&a, 0, sizeof (const struct A));
+ memset (&a, 0, sizeof (volatile struct A));
+ memset (&a, 0, sizeof (volatile const struct A));
+ memset (&a, 0, sizeof (TA));
+ memset (&a, 0, sizeof (__typeof (*&a)));
+ memset (pa1, 0, sizeof (*pa1));
+ memset (pa2, 0, sizeof (*pa3));
+ memset (pa3, 0, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memset ((void *) &a, 0, sizeof (&a));
+ memset ((char *) &a, 0, sizeof (&a));
+ memset (&a, 0, sizeof (&a) + 0);
+ memset (&a, 0, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memcpy (&a, x, sizeof a);
+ memcpy (&a, x, sizeof (a));
+ memcpy (&a, x, sizeof (struct A));
+ memcpy (&a, x, sizeof (const struct A));
+ memcpy (&a, x, sizeof (volatile struct A));
+ memcpy (&a, x, sizeof (volatile const struct A));
+ memcpy (&a, x, sizeof (TA));
+ memcpy (&a, x, sizeof (__typeof (*&a)));
+ memcpy (pa1, x, sizeof (*pa1));
+ memcpy (pa2, x, sizeof (*pa3));
+ memcpy (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy ((void *) &a, x, sizeof (&a));
+ memcpy ((char *) &a, x, sizeof (&a));
+ memcpy (&a, x, sizeof (&a) + 0);
+ memcpy (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memcpy (x, &a, sizeof a);
+ memcpy (x, &a, sizeof (a));
+ memcpy (x, &a, sizeof (struct A));
+ memcpy (x, &a, sizeof (const struct A));
+ memcpy (x, &a, sizeof (volatile struct A));
+ memcpy (x, &a, sizeof (volatile const struct A));
+ memcpy (x, &a, sizeof (TA));
+ memcpy (x, &a, sizeof (__typeof (*&a)));
+ memcpy (x, pa1, sizeof (*pa1));
+ memcpy (x, pa2, sizeof (*pa3));
+ memcpy (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy (x, (void *) &a, sizeof (&a));
+ memcpy (x, (char *) &a, sizeof (&a));
+ memcpy (x, &a, sizeof (&a) + 0);
+ memcpy (x, &a, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memmove (&a, x, sizeof a);
+ memmove (&a, x, sizeof (a));
+ memmove (&a, x, sizeof (struct A));
+ memmove (&a, x, sizeof (const struct A));
+ memmove (&a, x, sizeof (volatile struct A));
+ memmove (&a, x, sizeof (volatile const struct A));
+ memmove (&a, x, sizeof (TA));
+ memmove (&a, x, sizeof (__typeof (*&a)));
+ memmove (pa1, x, sizeof (*pa1));
+ memmove (pa2, x, sizeof (*pa3));
+ memmove (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove ((void *) &a, x, sizeof (&a));
+ memmove ((char *) &a, x, sizeof (&a));
+ memmove (&a, x, sizeof (&a) + 0);
+ memmove (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memmove (x, &a, sizeof a);
+ memmove (x, &a, sizeof (a));
+ memmove (x, &a, sizeof (struct A));
+ memmove (x, &a, sizeof (const struct A));
+ memmove (x, &a, sizeof (volatile struct A));
+ memmove (x, &a, sizeof (volatile const struct A));
+ memmove (x, &a, sizeof (TA));
+ memmove (x, &a, sizeof (__typeof (*&a)));
+ memmove (x, pa1, sizeof (*pa1));
+ memmove (x, pa2, sizeof (*pa3));
+ memmove (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove (x, (void *) &a, sizeof (&a));
+ memmove (x, (char *) &a, sizeof (&a));
+ memmove (x, &a, sizeof (&a) + 0);
+ memmove (x, &a, 0 + sizeof (&a));
+}
+
+void
+f2 (void *x)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ memset (&b, 0, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memset (pb1, 0, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb2, 0, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb3, 0, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb4, 0, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb1, 0, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pb2, 0, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pb3, 0, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memcpy (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memcpy (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memmove (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pb4, x, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memmove (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ memset (&b, 0, sizeof b);
+ memset (&b, 0, sizeof (b));
+ memset (&b, 0, sizeof (struct B));
+ memset (&b, 0, sizeof (const struct B));
+ memset (&b, 0, sizeof (volatile struct B));
+ memset (&b, 0, sizeof (volatile const struct B));
+ memset (&b, 0, sizeof (TB));
+ memset (&b, 0, sizeof (__typeof (*&b)));
+ memset (pb1, 0, sizeof (*pb1));
+ memset (pb2, 0, sizeof (*pb3));
+ memset (pb3, 0, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memset ((void *) &b, 0, sizeof (&b));
+ memset ((char *) &b, 0, sizeof (&b));
+ memset (&b, 0, sizeof (&b) + 0);
+ memset (&b, 0, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memcpy (&b, x, sizeof b);
+ memcpy (&b, x, sizeof (b));
+ memcpy (&b, x, sizeof (struct B));
+ memcpy (&b, x, sizeof (const struct B));
+ memcpy (&b, x, sizeof (volatile struct B));
+ memcpy (&b, x, sizeof (volatile const struct B));
+ memcpy (&b, x, sizeof (TB));
+ memcpy (&b, x, sizeof (__typeof (*&b)));
+ memcpy (pb1, x, sizeof (*pb1));
+ memcpy (pb2, x, sizeof (*pb3));
+ memcpy (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy ((void *) &b, x, sizeof (&b));
+ memcpy ((char *) &b, x, sizeof (&b));
+ memcpy (&b, x, sizeof (&b) + 0);
+ memcpy (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memcpy (x, &b, sizeof b);
+ memcpy (x, &b, sizeof (b));
+ memcpy (x, &b, sizeof (struct B));
+ memcpy (x, &b, sizeof (const struct B));
+ memcpy (x, &b, sizeof (volatile struct B));
+ memcpy (x, &b, sizeof (volatile const struct B));
+ memcpy (x, &b, sizeof (TB));
+ memcpy (x, &b, sizeof (__typeof (*&b)));
+ memcpy (x, pb1, sizeof (*pb1));
+ memcpy (x, pb2, sizeof (*pb3));
+ memcpy (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy (x, (void *) &b, sizeof (&b));
+ memcpy (x, (char *) &b, sizeof (&b));
+ memcpy (x, &b, sizeof (&b) + 0);
+ memcpy (x, &b, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memmove (&b, x, sizeof b);
+ memmove (&b, x, sizeof (b));
+ memmove (&b, x, sizeof (struct B));
+ memmove (&b, x, sizeof (const struct B));
+ memmove (&b, x, sizeof (volatile struct B));
+ memmove (&b, x, sizeof (volatile const struct B));
+ memmove (&b, x, sizeof (TB));
+ memmove (&b, x, sizeof (__typeof (*&b)));
+ memmove (pb1, x, sizeof (*pb1));
+ memmove (pb2, x, sizeof (*pb3));
+ memmove (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove ((void *) &b, x, sizeof (&b));
+ memmove ((char *) &b, x, sizeof (&b));
+ memmove (&b, x, sizeof (&b) + 0);
+ memmove (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memmove (x, &b, sizeof b);
+ memmove (x, &b, sizeof (b));
+ memmove (x, &b, sizeof (struct B));
+ memmove (x, &b, sizeof (const struct B));
+ memmove (x, &b, sizeof (volatile struct B));
+ memmove (x, &b, sizeof (volatile const struct B));
+ memmove (x, &b, sizeof (TB));
+ memmove (x, &b, sizeof (__typeof (*&b)));
+ memmove (x, pb1, sizeof (*pb1));
+ memmove (x, pb2, sizeof (*pb3));
+ memmove (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove (x, (void *) &b, sizeof (&b));
+ memmove (x, (char *) &b, sizeof (&b));
+ memmove (x, &b, sizeof (&b) + 0);
+ memmove (x, &b, 0 + sizeof (&b));
+}
+
+void
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ char *y3;
+ memset (y, 0, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memset (y1, 0, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memset (y2, 0, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memset (&c, 0, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memset (w, 0, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ memcpy (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memcpy (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memcpy (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memcpy (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memcpy (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ memcpy (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memcpy (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memcpy (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memcpy (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memcpy (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ memmove (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memmove (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memmove (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memmove (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memmove (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ memmove (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memmove (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memmove (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memmove (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memmove (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ /* These are correct, no warning. */
+ memset (y, 0, sizeof (*y));
+ memset (y1, 0, sizeof (*y2));
+ memset (buf1, 0, sizeof buf1);
+ memset (buf3, 0, sizeof (buf3));
+ memset (&buf3[0], 0, sizeof (buf3));
+ memset (&buf4[0], 0, sizeof (buf4));
+ memset (w, 0, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memset ((void *) y, 0, sizeof (y));
+ memset ((char *) y1, 0, sizeof (y2));
+ memset (y, 0, sizeof (y) + 0);
+ memset (y1, 0, 0 + sizeof (y2));
+ memset ((void *) &c, 0, sizeof (&c));
+ memset ((signed char *) &c, 0, sizeof (&c));
+ memset (&c, 0, sizeof (&c) + 0);
+ memset (&c, 0, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memcpy (y, x, sizeof (*y));
+ memcpy (y1, x, sizeof (*y2));
+ memcpy (buf1, x, sizeof buf1);
+ memcpy (buf3, x, sizeof (buf3));
+ memcpy (&buf3[0], x, sizeof (buf3));
+ memcpy (&buf4[0], x, sizeof (buf4));
+ memcpy (&y3, y, sizeof (y3));
+ memcpy ((char *) &y3, y, sizeof (y3));
+ memcpy (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy ((void *) y, x, sizeof (y));
+ memcpy ((char *) y1, x, sizeof (y2));
+ memcpy (y, x, sizeof (y) + 0);
+ memcpy (y1, x, 0 + sizeof (y2));
+ memcpy ((void *) &c, x, sizeof (&c));
+ memcpy ((signed char *) &c, x, sizeof (&c));
+ memcpy (&c, x, sizeof (&c) + 0);
+ memcpy (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memcpy (x, y, sizeof (*y));
+ memcpy (x, y1, sizeof (*y2));
+ memcpy (x, buf1, sizeof buf1);
+ memcpy (x, buf3, sizeof (buf3));
+ memcpy (x, &buf3[0], sizeof (buf3));
+ memcpy (x, &buf4[0], sizeof (buf4));
+ memcpy (y, &y3, sizeof (y3));
+ memcpy (y, (char *) &y3, sizeof (y3));
+ memcpy (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy (x, (void *) y, sizeof (y));
+ memcpy (x, (char *) y1, sizeof (y2));
+ memcpy (x, y, sizeof (y) + 0);
+ memcpy (x, y1, 0 + sizeof (y2));
+ memcpy (x, (void *) &c, sizeof (&c));
+ memcpy (x, (signed char *) &c, sizeof (&c));
+ memcpy (x, &c, sizeof (&c) + 0);
+ memcpy (x, &c, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memmove (y, x, sizeof (*y));
+ memmove (y1, x, sizeof (*y2));
+ memmove (buf1, x, sizeof buf1);
+ memmove (buf3, x, sizeof (buf3));
+ memmove (&buf3[0], x, sizeof (buf3));
+ memmove (&buf4[0], x, sizeof (buf4));
+ memmove (&y3, y, sizeof (y3));
+ memmove ((char *) &y3, y, sizeof (y3));
+ memmove (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove ((void *) y, x, sizeof (y));
+ memmove ((char *) y1, x, sizeof (y2));
+ memmove (y, x, sizeof (y) + 0);
+ memmove (y1, x, 0 + sizeof (y2));
+ memmove ((void *) &c, x, sizeof (&c));
+ memmove ((signed char *) &c, x, sizeof (&c));
+ memmove (&c, x, sizeof (&c) + 0);
+ memmove (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memmove (x, y, sizeof (*y));
+ memmove (x, y1, sizeof (*y2));
+ memmove (x, buf1, sizeof buf1);
+ memmove (x, buf3, sizeof (buf3));
+ memmove (x, &buf3[0], sizeof (buf3));
+ memmove (x, &buf4[0], sizeof (buf4));
+ memmove (y, &y3, sizeof (y3));
+ memmove (y, (char *) &y3, sizeof (y3));
+ memmove (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove (x, (void *) y, sizeof (y));
+ memmove (x, (char *) y1, sizeof (y2));
+ memmove (x, y, sizeof (y) + 0);
+ memmove (x, y1, 0 + sizeof (y2));
+ memmove (x, (void *) &c, sizeof (&c));
+ memmove (x, (signed char *) &c, sizeof (&c));
+ memmove (x, &c, sizeof (&c) + 0);
+ memmove (x, &c, 0 + sizeof (&c));
+}
+
+void
+f4 (char *x, char **y, int z, char w[64])
+{
+ const char *s1 = "foobarbaz";
+ const char *s2 = "abcde12345678";
+ strncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ strncat (x, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ stpncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+
+ strncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ strncat (w, s2, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ stpncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+
+ /* These are correct, no warning. */
+ const char s3[] = "foobarbaz";
+ const char s4[] = "abcde12345678";
+ strncpy (x, s3, sizeof (s3));
+ strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
+}
+
+/* { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" } */
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 00000000000..8967f384afd
--- /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/decltype45.C b/gcc/testsuite/g++.dg/cpp0x/decltype45.C
new file mode 100644
index 00000000000..f768d8554e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype45.C
@@ -0,0 +1,40 @@
+// PR c++/51878
+// { dg-do compile { target c++11 } }
+
+template<class F, class... T>
+auto indirect_call(F f, T... t) -> decltype(f(t...))
+{
+ return f(t...);
+}
+
+template<class F, class T>
+struct VariadicBind
+{
+ F f;
+ T t;
+
+ template<class... A>
+ auto operator()(A... a) -> decltype(indirect_call(f, t, a...))
+ {
+ return indirect_call(f, t, a...);
+ }
+};
+
+template<class F>
+void apply(F f)
+{
+ f();
+}
+
+template<class F, class V1, class... V>
+void apply(F f, V1 v1, V... v)
+{
+ apply(VariadicBind<F, int>{f, v1}, v...);
+}
+
+void func(int, int) { }
+
+int main()
+{
+ apply(func, 0, 0);
+}
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 00000000000..99603106512
--- /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 00000000000..de5745358ef
--- /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 00000000000..8e8ff010ffe
--- /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 00000000000..257487efb11
--- /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 00000000000..2e18e5d62f3
--- /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 00000000000..621ba604c22
--- /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 00000000000..7116e2f0700
--- /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 00000000000..b6754dc4a46
--- /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 00000000000..a8aa6d98ad9
--- /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 00000000000..5ac88d6b7db
--- /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 00000000000..22608246706
--- /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 00000000000..d55d3d2a5bf
--- /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 00000000000..dc5e86b6348
--- /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/cpp0x/pr52744.C b/gcc/testsuite/g++.dg/cpp0x/pr52744.C
new file mode 100644
index 00000000000..1a01fb2957f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr52744.C
@@ -0,0 +1,83 @@
+// PR c++/52744
+// { dg-do compile { target c++11 } }
+
+struct T
+{
+ int a;
+ void b(){}
+ int c(int)
+ {
+ return 1;
+ }
+};
+
+template<typename CT, CT> struct member_helper;
+
+template<typename FT, FT(T::*mem)>
+struct member_helper<FT(T::*), mem>
+{
+ static const char* worker()
+ {
+ return "for members";
+ }
+};
+
+template<typename Return, typename... Args, Return(T::*fun)(Args...)>
+struct member_helper<Return(T::*)(Args...), fun>
+{
+ static const char* worker()
+ {
+ return "for member functions returning non void";
+ }
+};
+
+template<typename... Args, void(T::*fun)(Args...)>
+struct member_helper<void(T::*)(Args...), fun>
+{
+ static const char* worker()
+ {
+ return "for member functions returning void";
+ }
+};
+
+void member_test()
+{
+ member_helper<decltype(&T::a), &T::a>::worker();
+ member_helper<decltype(&T::b), &T::b>::worker();
+ member_helper<decltype(&T::c), &T::c>::worker();
+}
+
+typedef void lua_State;
+
+template<typename T, T> class function_helper
+{
+ static_assert(sizeof(T) != sizeof(T),
+ "Error: function_helper works with functions (duh)");
+};
+
+template<typename Return, typename... Args, Return(*func)(Args...)>
+struct function_helper<Return(*)(Args...), func>
+{
+ static int wrapper(lua_State* l)
+ {
+ return 1;
+ }
+};
+
+template<typename... Args, void(*func)(Args...)>
+struct function_helper<void(*)(Args...), func>
+{
+ static int wrapper(lua_State* l)
+ {
+ return 0;
+ }
+};
+
+int ciao(int){ return 0; }
+void ciao2(int){}
+
+void function_test()
+{
+ function_helper<decltype(&ciao), &ciao>::wrapper(0);
+ function_helper<decltype(&ciao2), &ciao2>::wrapper(0);
+}
diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
index b8133909a7f..c13161d3ceb 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
@@ -1,7 +1,7 @@
/* Test that #pragma GCC visibility does not override class member specific settings. */
/* { dg-do compile } */
/* { dg-require-visibility "internal" } */
-/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } { ! *-*-darwin* } } } }*/
+/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! { *-*-solaris2* *-*-darwin* } } } } } */
/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */
#pragma GCC visibility push(hidden)
diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
index 3ceaf4a2523..25e9ceac076 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
@@ -1,7 +1,7 @@
/* Test that #pragma GCC visibility does not override class member specific settings. */
/* { dg-do compile } */
/* { dg-require-visibility "internal" } */
-/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } { ! *-*-darwin* } } } } */
+/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! { *-*-solaris2* *-*-darwin* } } } } } */
/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */
#pragma GCC visibility push(hidden)
diff --git a/gcc/testsuite/g++.dg/ext/weak5.C b/gcc/testsuite/g++.dg/ext/weak5.C
new file mode 100644
index 00000000000..f2924a0b6d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/weak5.C
@@ -0,0 +1,12 @@
+// PR c++/36107
+// { dg-do assemble }
+// { dg-require-weak "" }
+
+class Test {
+ public:
+ Test() __attribute__((weak));
+};
+
+void test() {
+ Test test;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/tls-5.C b/gcc/testsuite/g++.dg/gomp/tls-5.C
index 74e4faaa884..f1dcdae688d 100644
--- a/gcc/testsuite/g++.dg/gomp/tls-5.C
+++ b/gcc/testsuite/g++.dg/gomp/tls-5.C
@@ -1,6 +1,7 @@
// The reference temp should be TLS, not normal data.
// { dg-require-effective-target c++11 }
-// { dg-final { scan-assembler-not "\\.data" } }
+// { dg-require-alias }
+// { dg-final { scan-assembler-not "\\.data" { target tls_native } } }
extern int&& ir;
#pragma omp threadprivate (ir)
diff --git a/gcc/testsuite/g++.dg/init/array30.C b/gcc/testsuite/g++.dg/init/array30.C
new file mode 100644
index 00000000000..696d9bf992d
--- /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 00000000000..9bb66a5950f
--- /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/init/bitfield3.C b/gcc/testsuite/g++.dg/init/bitfield3.C
new file mode 100644
index 00000000000..23db2d4a34c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/bitfield3.C
@@ -0,0 +1,11 @@
+// PR c++/43663
+
+struct S
+{
+ S(): i(0) {}
+ int i : 3;
+};
+
+S s;
+
+const int& cr(s.i);
diff --git a/gcc/testsuite/g++.dg/opt/pr52643.C b/gcc/testsuite/g++.dg/opt/pr52643.C
new file mode 100644
index 00000000000..271dd76c12d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr52643.C
@@ -0,0 +1,64 @@
+// PR c++/52643
+// { dg-options "-O" }
+
+template<class T> class already_AddRefd {};
+
+template<class T>
+class ObjRef
+{
+public:
+ ObjRef() {}
+
+ ObjRef(const already_AddRefd<T> aar) {}
+
+ ~ObjRef()
+ {
+ T* mPtr;
+ mPtr->release_ref();
+ }
+
+ operator T* () const
+ {
+ return __null;
+ }
+
+ template<class U>
+ void operator= (const already_AddRefd<U>& newAssign) {}
+};
+
+class MyRetClass {
+public:
+ void release_ref();
+};
+
+class MyClass
+{
+ void appendChild();
+ void getTripleOutOfByPredicate();
+ already_AddRefd<MyRetClass> getNextTriple();
+};
+
+void
+MyClass::getTripleOutOfByPredicate()
+{
+ ObjRef<MyRetClass> t (getNextTriple());
+
+ if (t == __null)
+ throw MyRetClass();
+}
+
+void
+MyClass::appendChild()
+{
+ while (1)
+ {
+ try
+ {
+ ObjRef<MyRetClass> t (getNextTriple());
+ continue;
+ }
+ catch (MyRetClass)
+ {
+ }
+ }
+}
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 00000000000..87c183aab66
--- /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 00000000000..5002602b698
--- /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/friend-main.C b/gcc/testsuite/g++.dg/parse/friend-main.C
new file mode 100644
index 00000000000..e6d32e71ba4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/friend-main.C
@@ -0,0 +1,30 @@
+// PR c++/24449
+
+class Fooa
+{
+ friend int main();
+};
+
+template <class T> class Foob
+{
+ friend int main();
+ int i;
+};
+
+int main()
+{
+ Foob<void> a;
+ a.i = 7;
+}
+
+class Fooc
+{
+ template<class T> friend int main(); // { dg-error "cannot declare .::main. to be a template" }
+};
+
+template<class T> class Food
+{
+ template<class U> friend int main(); // { dg-error "cannot declare .::main. to be a template" }
+};
+
+template<class U> int main() {} // { dg-error "cannot declare .::main. to be a template" }
diff --git a/gcc/testsuite/g++.dg/parse/pr43765.C b/gcc/testsuite/g++.dg/parse/pr43765.C
new file mode 100644
index 00000000000..0b341ddb8ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr43765.C
@@ -0,0 +1,14 @@
+// PR c++/43765
+// { dg-options "" }
+
+struct SomeType
+{
+ const char *values[];
+};
+const char *temp[] = {"607", "612", 0};
+
+SomeType vals[] =
+ {
+ { values : temp, },
+ 0
+ }; // { dg-error "invalid" }
diff --git a/gcc/testsuite/g++.dg/parse/tmpl-outside1.C b/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
index e63e3cd4412..7d969e46858 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 00000000000..54d39fa88db
--- /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/pr53055.C b/gcc/testsuite/g++.dg/pr53055.C
new file mode 100644
index 00000000000..787af9d156f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr53055.C
@@ -0,0 +1,5 @@
+// PR c++/53055
+// { dg-do compile }
+
+struct A A :: * p ;
+int i = p ->* p ; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/crash113.C b/gcc/testsuite/g++.dg/template/crash113.C
new file mode 100644
index 00000000000..3d3a562bdcd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash113.C
@@ -0,0 +1,50 @@
+// PR c++/53581
+
+template<class A, int M, int N>
+class Child;
+
+template<class A, int M, int N>
+class Base
+{
+public:
+ Child<A, M, N> operator-(const Base<A, M, N> &m) const
+ {
+ Child<A, M, N> diff;
+ return diff;
+ }
+
+ A test() const
+ {
+ return 0;
+ }
+
+private:
+ A values[M * N];
+};
+
+template<class A, int N>
+class Ops
+{
+public:
+ virtual ~Ops() {}
+
+ bool bar() const
+ {
+ Child<A, N, N> mat;
+ return (*static_cast<const Child<A, N, N>*>(this) - mat).test();
+ }
+};
+
+
+template<class A, int N>
+class Child<A, N, N> : public Base<A, N, N>, public Ops<A, N> {};
+
+class ImageWarp
+{
+ bool bar() const
+ {
+ return foo.bar();
+ }
+
+ Child<float, 3, 3> foo;
+};
diff --git a/gcc/testsuite/g++.dg/template/pr29633.C b/gcc/testsuite/g++.dg/template/pr29633.C
new file mode 100644
index 00000000000..3e0254a46e4
--- /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 31dfa6a83d0..691517fd372 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/static2.C b/gcc/testsuite/g++.dg/tls/static2.C
new file mode 100644
index 00000000000..ab688dd8dc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/static2.C
@@ -0,0 +1,18 @@
+// { dg-final { scan-assembler-not "_ZTHN1A1iE" } }
+// { dg-final { scan-assembler-not "_ZTWN1A1iE" } }
+// { dg-require-effective-target tls }
+
+struct A
+{
+ static __thread int i;
+};
+
+int
+test ()
+{
+ if (A::i != 8)
+ return 1;
+
+ A::i = 17;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local-cse.C b/gcc/testsuite/g++.dg/tls/thread_local-cse.C
index 47c6aede339..29553d2ba7e 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 130114811f8..7c8481cc2cb 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_local7.C b/gcc/testsuite/g++.dg/tls/thread_local7.C
index 77a1c05e44c..f453b965768 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local7.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local7.C
@@ -2,7 +2,7 @@
// { dg-require-effective-target tls }
// The reference temp should be TLS, not normal data.
-// { dg-final { scan-assembler-not "\\.data" } }
+// { dg-final { scan-assembler-not "\\.data" { target tls_native } } }
void f()
{
diff --git a/gcc/testsuite/g++.dg/tls/thread_local7g.C b/gcc/testsuite/g++.dg/tls/thread_local7g.C
index 6960598173a..3479aeb31fa 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/Wsizeof-pointer-memaccess1.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
index c57096cc063..6cb39809d6c 100644
--- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
@@ -14,6 +14,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t);
extern int memcmp (const void *, const void *, size_t);
extern char *strncpy (char *__restrict, const char *__restrict, size_t);
extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
extern char *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
@@ -56,6 +57,13 @@ strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___stpncpy_chk (dest, src, len, bos (dest));
+}
#endif
}
@@ -127,23 +135,23 @@ f1 (void *x, int z)
memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&a, 0, sizeof a);
@@ -331,23 +339,23 @@ f2 (void *x, int z)
memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&b, 0, sizeof b);
@@ -519,17 +527,17 @@ f3 (void *x, char *y, int z, X w)
memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
- z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
// These are correct, no warning.
memset (y, 0, sizeof (*y));
@@ -673,23 +681,29 @@ f3 (void *x, char *y, int z, X w)
}
int
-f4 (char *x, char **y, int z)
+f4 (char *x, char **y, int z, char w[64])
{
const char *s1 = "foobarbaz";
const char *s2 = "abcde12345678";
strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ stpncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+
+ strncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ strncat (w, s2, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ stpncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
// These are correct, no warning.
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
index d5a29d8f582..9e2805d2b74 100644
--- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
@@ -14,6 +14,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t);
extern int memcmp (const void *, const void *, size_t);
extern char *strncpy (char *__restrict, const char *__restrict, size_t);
extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
extern char *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
@@ -56,6 +57,13 @@ strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___stpncpy_chk (dest, src, len, bos (dest));
+}
#endif
}
@@ -128,23 +136,23 @@ f1 (void *x, int z)
memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&a, 0, sizeof a);
@@ -333,23 +341,23 @@ f2 (void *x, int z)
memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&b, 0, sizeof b);
@@ -522,17 +530,17 @@ f3 (void *x, char *y, int z, X w)
memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
- z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
// These are correct, no warning.
memset (y, 0, sizeof (*y));
@@ -677,23 +685,29 @@ f3 (void *x, char *y, int z, X w)
template <int N>
int
-f4 (char *x, char **y, int z)
+f4 (char *x, char **y, int z, char w[64])
{
const char *s1 = "foobarbaz";
const char *s2 = "abcde12345678";
strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ stpncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+
+ strncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ strncat (w, s2, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ stpncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
// These are correct, no warning.
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
@@ -704,12 +718,12 @@ f4 (char *x, char **y, int z)
}
int
-f (void *x, char *y, int z, X w, char **u)
+f (void *x, char *y, int z, X w, char **u, char v[64])
{
z += f1<0> (x, z);
z += f2<0> (x, z);
z += f3<0> (x, y, z, w);
- z += f4<0> (y, u, z);
+ z += f4<0> (y, u, z, v);
return z;
}
diff --git a/gcc/testsuite/g++.dg/torture/predcom-1.C b/gcc/testsuite/g++.dg/torture/predcom-1.C
index c668cac606d..9e9a4b38cfa 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 7be0cd868cc..97bc2bafebb 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 5a74b2f6fdd..e4045b50b59 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 429e8127c2b..3c8bb0c08e6 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 99b4cd384fb..51a66fd4116 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 f66f1038c7c..9c985141fd8 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 00000000000..72349c9d7d7
--- /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/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
new file mode 100644
index 00000000000..b683be7ceff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
@@ -0,0 +1,456 @@
+/* Test -Wsizeof-pointer-memaccess warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void bzero (void *, size_t);
+extern void bcopy (void *, const void *, size_t);
+extern int bcmp (const void *, const void *, size_t);
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+int
+f1 (void *x, int z)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ bzero (&a, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bzero (pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa2, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa4, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bcopy (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ bcopy (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += bcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += bcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ bzero (&a, sizeof a);
+ bzero (&a, sizeof (a));
+ bzero (&a, sizeof (struct A));
+ bzero (&a, sizeof (const struct A));
+ bzero (&a, sizeof (volatile struct A));
+ bzero (&a, sizeof (volatile const struct A));
+ bzero (&a, sizeof (TA));
+ bzero (&a, sizeof (__typeof (*&a)));
+ bzero (pa1, sizeof (*pa1));
+ bzero (pa2, sizeof (*pa3));
+ bzero (pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bzero ((void *) &a, sizeof (&a));
+ bzero ((char *) &a, sizeof (&a));
+ bzero (&a, sizeof (&a) + 0);
+ bzero (&a, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ bcopy (x, &a, sizeof a);
+ bcopy (x, &a, sizeof (a));
+ bcopy (x, &a, sizeof (struct A));
+ bcopy (x, &a, sizeof (const struct A));
+ bcopy (x, &a, sizeof (volatile struct A));
+ bcopy (x, &a, sizeof (volatile const struct A));
+ bcopy (x, &a, sizeof (TA));
+ bcopy (x, &a, sizeof (__typeof (*&a)));
+ bcopy (x, pa1, sizeof (*pa1));
+ bcopy (x, pa2, sizeof (*pa3));
+ bcopy (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy (x, (void *) &a, sizeof (&a));
+ bcopy (x, (char *) &a, sizeof (&a));
+ bcopy (x, &a, sizeof (&a) + 0);
+ bcopy (x, &a, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ bcopy (&a, x, sizeof a);
+ bcopy (&a, x, sizeof (a));
+ bcopy (&a, x, sizeof (struct A));
+ bcopy (&a, x, sizeof (const struct A));
+ bcopy (&a, x, sizeof (volatile struct A));
+ bcopy (&a, x, sizeof (volatile const struct A));
+ bcopy (&a, x, sizeof (TA));
+ bcopy (&a, x, sizeof (__typeof (*&a)));
+ bcopy (pa1, x, sizeof (*pa1));
+ bcopy (pa2, x, sizeof (*pa3));
+ bcopy (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy ((void *) &a, x, sizeof (&a));
+ bcopy ((char *) &a, x, sizeof (&a));
+ bcopy (&a, x, sizeof (&a) + 0);
+ bcopy (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ z += bcmp (&a, x, sizeof a);
+ z += bcmp (&a, x, sizeof (a));
+ z += bcmp (&a, x, sizeof (struct A));
+ z += bcmp (&a, x, sizeof (const struct A));
+ z += bcmp (&a, x, sizeof (volatile struct A));
+ z += bcmp (&a, x, sizeof (volatile const struct A));
+ z += bcmp (&a, x, sizeof (TA));
+ z += bcmp (&a, x, sizeof (__typeof (*&a)));
+ z += bcmp (pa1, x, sizeof (*pa1));
+ z += bcmp (pa2, x, sizeof (*pa3));
+ z += bcmp (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp ((void *) &a, x, sizeof (&a));
+ z += bcmp ((char *) &a, x, sizeof (&a));
+ z += bcmp (&a, x, sizeof (&a) + 0);
+ z += bcmp (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ z += bcmp (x, &a, sizeof a);
+ z += bcmp (x, &a, sizeof (a));
+ z += bcmp (x, &a, sizeof (struct A));
+ z += bcmp (x, &a, sizeof (const struct A));
+ z += bcmp (x, &a, sizeof (volatile struct A));
+ z += bcmp (x, &a, sizeof (volatile const struct A));
+ z += bcmp (x, &a, sizeof (TA));
+ z += bcmp (x, &a, sizeof (__typeof (*&a)));
+ z += bcmp (x, pa1, sizeof (*pa1));
+ z += bcmp (x, pa2, sizeof (*pa3));
+ z += bcmp (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp (x, (void *) &a, sizeof (&a));
+ z += bcmp (x, (char *) &a, sizeof (&a));
+ z += bcmp (x, &a, sizeof (&a) + 0);
+ z += bcmp (x, &a, 0 + sizeof (&a));
+
+ return z;
+}
+
+int
+f2 (void *x, int z)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ bzero (&b, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bzero (pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb2, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb4, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bcopy (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ bcopy (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += bcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += bcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ bzero (&b, sizeof b);
+ bzero (&b, sizeof (b));
+ bzero (&b, sizeof (struct B));
+ bzero (&b, sizeof (const struct B));
+ bzero (&b, sizeof (volatile struct B));
+ bzero (&b, sizeof (volatile const struct B));
+ bzero (&b, sizeof (TB));
+ bzero (&b, sizeof (__typeof (*&b)));
+ bzero (pb1, sizeof (*pb1));
+ bzero (pb2, sizeof (*pb3));
+ bzero (pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bzero ((void *) &b, sizeof (&b));
+ bzero ((char *) &b, sizeof (&b));
+ bzero (&b, sizeof (&b) + 0);
+ bzero (&b, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ bcopy (x, &b, sizeof b);
+ bcopy (x, &b, sizeof (b));
+ bcopy (x, &b, sizeof (struct B));
+ bcopy (x, &b, sizeof (const struct B));
+ bcopy (x, &b, sizeof (volatile struct B));
+ bcopy (x, &b, sizeof (volatile const struct B));
+ bcopy (x, &b, sizeof (TB));
+ bcopy (x, &b, sizeof (__typeof (*&b)));
+ bcopy (x, pb1, sizeof (*pb1));
+ bcopy (x, pb2, sizeof (*pb3));
+ bcopy (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy (x, (void *) &b, sizeof (&b));
+ bcopy (x, (char *) &b, sizeof (&b));
+ bcopy (x, &b, sizeof (&b) + 0);
+ bcopy (x, &b, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ bcopy (&b, x, sizeof b);
+ bcopy (&b, x, sizeof (b));
+ bcopy (&b, x, sizeof (struct B));
+ bcopy (&b, x, sizeof (const struct B));
+ bcopy (&b, x, sizeof (volatile struct B));
+ bcopy (&b, x, sizeof (volatile const struct B));
+ bcopy (&b, x, sizeof (TB));
+ bcopy (&b, x, sizeof (__typeof (*&b)));
+ bcopy (pb1, x, sizeof (*pb1));
+ bcopy (pb2, x, sizeof (*pb3));
+ bcopy (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy ((void *) &b, x, sizeof (&b));
+ bcopy ((char *) &b, x, sizeof (&b));
+ bcopy (&b, x, sizeof (&b) + 0);
+ bcopy (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ z += bcmp (&b, x, sizeof b);
+ z += bcmp (&b, x, sizeof (b));
+ z += bcmp (&b, x, sizeof (struct B));
+ z += bcmp (&b, x, sizeof (const struct B));
+ z += bcmp (&b, x, sizeof (volatile struct B));
+ z += bcmp (&b, x, sizeof (volatile const struct B));
+ z += bcmp (&b, x, sizeof (TB));
+ z += bcmp (&b, x, sizeof (__typeof (*&b)));
+ z += bcmp (pb1, x, sizeof (*pb1));
+ z += bcmp (pb2, x, sizeof (*pb3));
+ z += bcmp (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp ((void *) &b, x, sizeof (&b));
+ z += bcmp ((char *) &b, x, sizeof (&b));
+ z += bcmp (&b, x, sizeof (&b) + 0);
+ z += bcmp (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ z += bcmp (x, &b, sizeof b);
+ z += bcmp (x, &b, sizeof (b));
+ z += bcmp (x, &b, sizeof (struct B));
+ z += bcmp (x, &b, sizeof (const struct B));
+ z += bcmp (x, &b, sizeof (volatile struct B));
+ z += bcmp (x, &b, sizeof (volatile const struct B));
+ z += bcmp (x, &b, sizeof (TB));
+ z += bcmp (x, &b, sizeof (__typeof (*&b)));
+ z += bcmp (x, pb1, sizeof (*pb1));
+ z += bcmp (x, pb2, sizeof (*pb3));
+ z += bcmp (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp (x, (void *) &b, sizeof (&b));
+ z += bcmp (x, (char *) &b, sizeof (&b));
+ z += bcmp (x, &b, sizeof (&b) + 0);
+ z += bcmp (x, &b, 0 + sizeof (&b));
+
+ return z;
+}
+
+int
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ char *y3;
+ bzero (y, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bzero (y1, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bzero (y2, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bzero (&c, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bzero (w, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ bcopy (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bcopy (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bcopy (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bcopy (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bcopy (x, w, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ bcopy (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ bcopy (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ bcopy (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ bcopy (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ bcopy (w, x, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ z += bcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += bcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += bcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += bcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += bcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+
+ z += bcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += bcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += bcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += bcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += bcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+
+ /* These are correct, no warning. */
+ bzero (y, sizeof (*y));
+ bzero (y1, sizeof (*y2));
+ bzero (buf1, sizeof buf1);
+ bzero (buf3, sizeof (buf3));
+ bzero (&buf3[0], sizeof (buf3));
+ bzero (&buf4[0], sizeof (buf4));
+ bzero (w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ bzero ((void *) y, sizeof (y));
+ bzero ((char *) y1, sizeof (y2));
+ bzero (y, sizeof (y) + 0);
+ bzero (y1, 0 + sizeof (y2));
+ bzero ((void *) &c, sizeof (&c));
+ bzero ((signed char *) &c, sizeof (&c));
+ bzero (&c, sizeof (&c) + 0);
+ bzero (&c, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ bcopy (x, y, sizeof (*y));
+ bcopy (x, y1, sizeof (*y2));
+ bcopy (x, buf1, sizeof buf1);
+ bcopy (x, buf3, sizeof (buf3));
+ bcopy (x, &buf3[0], sizeof (buf3));
+ bcopy (x, &buf4[0], sizeof (buf4));
+ bcopy (y, &y3, sizeof (y3));
+ bcopy (y, (char *) &y3, sizeof (y3));
+ bcopy (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy (x, (void *) y, sizeof (y));
+ bcopy (x, (char *) y1, sizeof (y2));
+ bcopy (x, y, sizeof (y) + 0);
+ bcopy (x, y1, 0 + sizeof (y2));
+ bcopy (x, (void *) &c, sizeof (&c));
+ bcopy (x, (signed char *) &c, sizeof (&c));
+ bcopy (x, &c, sizeof (&c) + 0);
+ bcopy (x, &c, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ bcopy (y, x, sizeof (*y));
+ bcopy (y1, x, sizeof (*y2));
+ bcopy (buf1, x, sizeof buf1);
+ bcopy (buf3, x, sizeof (buf3));
+ bcopy (&buf3[0], x, sizeof (buf3));
+ bcopy (&buf4[0], x, sizeof (buf4));
+ bcopy (&y3, y, sizeof (y3));
+ bcopy ((char *) &y3, y, sizeof (y3));
+ bcopy (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy ((void *) y, x, sizeof (y));
+ bcopy ((char *) y1, x, sizeof (y2));
+ bcopy (y, x, sizeof (y) + 0);
+ bcopy (y1, x, 0 + sizeof (y2));
+ bcopy ((void *) &c, x, sizeof (&c));
+ bcopy ((signed char *) &c, x, sizeof (&c));
+ bcopy (&c, x, sizeof (&c) + 0);
+ bcopy (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ z += bcmp (y, x, sizeof (*y));
+ z += bcmp (y1, x, sizeof (*y2));
+ z += bcmp (buf1, x, sizeof buf1);
+ z += bcmp (buf3, x, sizeof (buf3));
+ z += bcmp (&buf3[0], x, sizeof (buf3));
+ z += bcmp (&buf4[0], x, sizeof (buf4));
+ z += bcmp (&y3, y, sizeof (y3));
+ z += bcmp ((char *) &y3, y, sizeof (y3));
+ z += bcmp (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp ((void *) y, x, sizeof (y));
+ z += bcmp ((char *) y1, x, sizeof (y2));
+ z += bcmp (y, x, sizeof (y) + 0);
+ z += bcmp (y1, x, 0 + sizeof (y2));
+ z += bcmp ((void *) &c, x, sizeof (&c));
+ z += bcmp ((signed char *) &c, x, sizeof (&c));
+ z += bcmp (&c, x, sizeof (&c) + 0);
+ z += bcmp (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ z += bcmp (x, y, sizeof (*y));
+ z += bcmp (x, y1, sizeof (*y2));
+ z += bcmp (x, buf1, sizeof buf1);
+ z += bcmp (x, buf3, sizeof (buf3));
+ z += bcmp (x, &buf3[0], sizeof (buf3));
+ z += bcmp (x, &buf4[0], sizeof (buf4));
+ z += bcmp (y, &y3, sizeof (y3));
+ z += bcmp (y, (char *) &y3, sizeof (y3));
+ z += bcmp (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp (x, (void *) y, sizeof (y));
+ z += bcmp (x, (char *) y1, sizeof (y2));
+ z += bcmp (x, y, sizeof (y) + 0);
+ z += bcmp (x, y1, 0 + sizeof (y2));
+ z += bcmp (x, (void *) &c, sizeof (&c));
+ z += bcmp (x, (signed char *) &c, sizeof (&c));
+ z += bcmp (x, &c, sizeof (&c) + 0);
+ z += bcmp (x, &c, 0 + sizeof (&c));
+
+ return z;
+}
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 00000000000..05e8dd14484
--- /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 c5b841a8496..332f3659f98 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 00000000000..f58e5a02cc6
--- /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/hoist-register-pressure.c b/gcc/testsuite/gcc.dg/hoist-register-pressure.c
new file mode 100644
index 00000000000..6077f1e5782
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hoist-register-pressure.c
@@ -0,0 +1,31 @@
+/* { dg-options "-Os -fdump-rtl-hoist" } */
+/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" } } */
+
+#define BUF 100
+int a[BUF];
+
+void com (int);
+void bar (int);
+
+int foo (int x, int y, int z)
+{
+ /* "x+y" won't be hoisted if "-fira-hoist-pressure" is disabled,
+ because its rtx_cost is too small. */
+ if (z)
+ {
+ a[1] = a[0] + a[2];
+ a[2] = a[1] + a[3];
+ a[3] = a[2] + a[4];
+ a[4] = a[3] + a[5];
+ a[5] = a[4] + a[6];
+ a[6] = a[5] + a[7];
+ a[7] = a[6] + a[8];
+ com (x+y);
+ }
+ else
+ {
+ bar (x+y);
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr44194-1.c b/gcc/testsuite/gcc.dg/pr44194-1.c
index 1772a9949d3..8c6547e87f4 100644
--- a/gcc/testsuite/gcc.dg/pr44194-1.c
+++ b/gcc/testsuite/gcc.dg/pr44194-1.c
@@ -15,5 +15,5 @@ void func() {
/* { dg-final { scan-rtl-dump "global deletions = (2|3)" "dse1" } } */
/* { dg-final { cleanup-rtl-dump "dse1" } } */
-/* { dg-final { scan-rtl-dump-not "set \\(mem" "final" } } */
+/* { dg-final { scan-rtl-dump-not "insn \[^\n\]*set \\(mem" "final" } } */
/* { dg-final { cleanup-rtl-dump "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr53060.c b/gcc/testsuite/gcc.dg/pr53060.c
index 3b2f193d9e3..db5acbdb6ea 100644
--- a/gcc/testsuite/gcc.dg/pr53060.c
+++ b/gcc/testsuite/gcc.dg/pr53060.c
@@ -22,3 +22,6 @@ int main()
if (i[0] != 3) abort();
return 0;
}
+
+/* Ignore a warning that is irrelevant to the purpose of this test. */
+/* { dg-prune-output ".*GCC vector returned by reference.*" } */
diff --git a/gcc/testsuite/gcc.dg/pr54919.c b/gcc/testsuite/gcc.dg/pr54919.c
new file mode 100644
index 00000000000..9f1affce234
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr54919.c
@@ -0,0 +1,27 @@
+/* PR tree-optimization/54919 */
+/* Testcase by Zdenek Sojka <zsojka@seznam.cz> */
+
+/* { dg-do run } */
+/* { dg-options "-O3 -ffast-math -funroll-loops -fvariable-expansion-in-unroller" } */
+
+int a[10];
+extern void abort(void) __attribute__((noreturn));
+
+int __attribute__((__noinline__, __noclone__))
+foo (void)
+{
+ double d;
+ int i;
+ for (i = 0, d = 0; i < 64; i++)
+ d--;
+ return (int) d;
+}
+
+int
+main (void)
+{
+ if (foo () != -64)
+ abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr54981.c b/gcc/testsuite/gcc.dg/pr54981.c
new file mode 100644
index 00000000000..aa77d60c44d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr54981.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-loop-distribute-patterns -fcompare-debug" } */
+
+extern void bar(unsigned *, char *);
+
+void foo(char *s)
+{
+ unsigned i;
+ char t[2];
+
+ bar(&i, t);
+
+ for (i = 0; i < 2; i++)
+ s[i] = t[i];
+}
diff --git a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
index 3897518de63..8d01bc616a7 100644
--- a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
+++ b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
@@ -12,6 +12,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t);
extern int memcmp (const void *, const void *, size_t);
extern char *strncpy (char *__restrict, const char *__restrict, size_t);
extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
extern char *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
@@ -54,6 +55,13 @@ strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___stpncpy_chk (dest, src, len, bos (dest));
+}
#endif
struct A { short a, b; int c, d; long e, f; };
@@ -123,23 +131,23 @@ f1 (void *x, int z)
memmove (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
- z += memcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
-
- z += memcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
- z += memcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += memcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += memcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += memcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
/* These are correct, no warning. */
memset (&a, 0, sizeof a);
@@ -327,23 +335,23 @@ f2 (void *x, int z)
memmove (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
- z += memcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
-
- z += memcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
- z += memcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += memcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += memcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += memcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
/* These are correct, no warning. */
memset (&b, 0, sizeof b);
@@ -515,17 +523,17 @@ f3 (void *x, char *y, int z, X w)
memmove (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
memmove (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += memcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += memcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += memcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
- z += memcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ z += memcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += memcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += memcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += memcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += memcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
- z += memcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += memcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += memcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += memcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
- z += memcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ z += memcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += memcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += memcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += memcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += memcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
/* These are correct, no warning. */
memset (y, 0, sizeof (*y));
@@ -669,23 +677,29 @@ f3 (void *x, char *y, int z, X w)
}
int
-f4 (char *x, char **y, int z)
+f4 (char *x, char **y, int z, char w[64])
{
const char *s1 = "foobarbaz";
const char *s2 = "abcde12345678";
strncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
strncat (x, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ stpncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
y[0] = strndup (s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += strncmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += strncmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += strncasecmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += strncasecmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ z += strncmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += strncmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += strncasecmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += strncasecmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+
+ strncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ strncat (w, s2, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ stpncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
/* These are correct, no warning. */
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
diff --git a/gcc/testsuite/gcc.dg/torture/pr54877.c b/gcc/testsuite/gcc.dg/torture/pr54877.c
new file mode 100644
index 00000000000..cee406e50d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr54877.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/54877 */
+/* { dg-do run } */
+/* { dg-options "-ffast-math" } */
+
+extern void abort (void);
+
+int
+foo (void)
+{
+ double d;
+ int i;
+ for (i = 0, d = 0; i < 64; i++)
+ d--;
+ return (int) d;
+}
+
+int
+main ()
+{
+ if (foo () != -64)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr54894.c b/gcc/testsuite/gcc.dg/torture/pr54894.c
new file mode 100644
index 00000000000..277e371de62
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr54894.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+typedef unsigned long long uint64_t;
+
+#define n 4096
+double A[n][n] __attribute__((aligned(16)));
+double B[n][n] __attribute__((aligned(16)));
+double C[n][n] __attribute__((aligned(16)));
+
+#define tilesize 128
+
+typedef double adouble __attribute__((__aligned__(16)));
+
+void foo ()
+{
+ int ih, jh, kh, il, kl, jl;
+ for (ih = 0; ih < n; ih += tilesize)
+ for (jh = 0; jh < n; jh += tilesize)
+ for (kh = 0; kh < n; kh += tilesize)
+ for (il = 0; il < tilesize; ++il)
+ {
+ adouble *Ap = (adouble *)&A[ih+il][kh];
+ for (kl = 0; kl < tilesize; ++kl)
+ for (jl = 0; jl < tilesize; ++jl)
+ C[ih+il][jh+jl] += Ap[kl] * B[kh+kl][jh+jl];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr54920.c b/gcc/testsuite/gcc.dg/torture/pr54920.c
new file mode 100644
index 00000000000..d1622f765a7
--- /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 6ba5871885a..cbb38efc899 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 00000000000..50ee9e44fd4
--- /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 00000000000..07d4363d395
--- /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/cunroll-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
new file mode 100644
index 00000000000..c302b17a86d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-cunroll-details" } */
+int a[2];
+test(int c)
+{
+ int i;
+ for (i=0;i<c;i++)
+ a[i]=5;
+}
+/* Array bounds says the loop will not roll much. */
+/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
new file mode 100644
index 00000000000..cd54c6695b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-cunroll-details" } */
+int a[2];
+test(int c)
+{
+ int i;
+ for (i=0;i<c;i++)
+ {
+ a[i]=5;
+ if (test2())
+ return;
+ }
+}
+/* We are not able to get rid of the final conditional because the loop has two exits. */
+/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 2 times.." "cunroll"} } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
new file mode 100644
index 00000000000..b621432c045
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cunrolli-details" } */
+int a[1];
+test(int c)
+{
+ int i;
+ for (i=0;i<c;i++)
+ {
+ a[i]=5;
+ }
+}
+/* If we start duplicating headers prior curoll, this loop will have 0 iterations. */
+
+/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunrolli"} } */
+/* { dg-final { cleanup-tree-dump "cunrolli" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
new file mode 100644
index 00000000000..02c94260a32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-cunroll-details" } */
+int a[1];
+test(int c)
+{
+ int i=0,j;
+ for (i=0;i<c;i++)
+ {
+ for (j=0;j<c;j++)
+ {
+ a[i]=5;
+ test2();
+ }
+ }
+}
+
+/* We should do this as part of cunrolli, but our cost model do not take into account early exit
+ from the last iteration. */
+/* { dg-final { scan-tree-dump "Turned loop 1 to non-loop; it never loops." "cunrolli"} } */
+/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunrolli"} } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
new file mode 100644
index 00000000000..8d1a14a7837
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-cunroll-details" } */
+int *a;
+test(int c)
+{
+ int i;
+ for (i=0;i<6;i++)
+ a[i]=5;
+}
+/* Basic testcase for complette unrolling. */
+/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 5 times.." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Exit condition of peeled iterations was eliminated." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c
index fe40bed5811..5c280b3f0c4 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 00000000000..1e11df19810
--- /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.dg/unroll_5.c b/gcc/testsuite/gcc.dg/unroll_5.c
new file mode 100644
index 00000000000..48259eb8447
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/unroll_5.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-rtl-loop2_unroll -funroll-loops" } */
+void abort (void);
+int *a;
+int t()
+{
+ int i;
+ for (i=0;i<1000000;i++)
+ if (a[i])
+ return 1;
+ return 0;
+}
+int t2()
+{
+ int i;
+ for (i=0;i<3000000;i++)
+ if (a[i])
+ abort ();
+ return 0;
+}
+/* { dg-final { scan-rtl-dump-times "upper bound: 999999" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-not "realistic bound: 999999" "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "upper bound: 2999999" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "realistic bound: 2999999" 1 "loop2_unroll" } } */
+/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c b/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c
index 60c344d05ee..526e70b1b88 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c
+++ b/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target vect_double } */
/* { dg-require-effective-target vect_perm } */
-/* { dg-options "-O -fdump-tree-copyprop1" } */
+/* { dg-additional-options "-fdump-tree-copyprop1" } */
typedef double vec __attribute__((vector_size (2 * sizeof (double))));
void f (vec *px, vec *y, vec *z)
diff --git a/gcc/testsuite/gcc.dg/vect/pr48765.c b/gcc/testsuite/gcc.dg/vect/pr48765.c
index 469c4f423ce..50839e389c7 100644
--- a/gcc/testsuite/gcc.dg/vect/pr48765.c
+++ b/gcc/testsuite/gcc.dg/vect/pr48765.c
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc*-*-* } } */
-/* { dg-options "-m64 -O3 -mcpu=power6" } */
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-options "-O3 -mcpu=power6" } */
enum reg_class
{
diff --git a/gcc/testsuite/gcc.dg/webizer.c b/gcc/testsuite/gcc.dg/webizer.c
new file mode 100644
index 00000000000..607bf6884d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/webizer.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -funroll-loops" } */
+typedef struct rowbox {
+ int startx ;
+ int endx ;
+ int endx1 ;
+ int startx2 ;
+ int ypos ;
+ int desiredL ;
+} ROWBOX ;
+ROWBOX rowArray1[2] ;
+ROWBOX *rowArray = rowArray1;
+
+int numRows = 2;
+
+int row = 1;
+int block = 0;
+double ckt_size_factor ;
+
+__attribute__ ((noinline))
+configure2()
+{
+ block = 0 ;
+ for( row = 1 ; row <= numRows ; row++ ) {
+ block++ ;
+ if( rowArray[row].endx1 > 0 ) {
+ block++ ;
+ }
+ }
+}
+
+main()
+{
+ configure2();
+}
diff --git a/gcc/testsuite/gcc.target/arm/div64-unwinding.c b/gcc/testsuite/gcc.target/arm/div64-unwinding.c
index d10fb2bdd5b..7f112eeab9f 100644
--- a/gcc/testsuite/gcc.target/arm/div64-unwinding.c
+++ b/gcc/testsuite/gcc.target/arm/div64-unwinding.c
@@ -1,7 +1,6 @@
/* Performing a 64-bit division should not pull in the unwinder. */
-/* The test is expected to fail for GNU/Linux; see PR54723. */
-/* { dg-do run { xfail *-*-linux* } } */
+/* { dg-do run { target { ! *-*-linux* } } } */
/* { dg-options "-O0" } */
#include <stdlib.h>
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 00000000000..1fab3c8a497
--- /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 00000000000..c57f4cec2b3
--- /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 512d50e8364..25920743282 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 99918310e30..a587999687a 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 c5f98105b78..5983760ee14 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 00000000000..d400163a191
--- /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 00000000000..988328dd08e
--- /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 00000000000..247a8edfd23
--- /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 00000000000..7f9e8570dc3
--- /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/pr54892.c b/gcc/testsuite/gcc.target/arm/pr54892.c
new file mode 100644
index 00000000000..a7fe1bc6676
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr54892.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+
+int set_role(unsigned char role_id, short m_role)
+{
+ return __sync_bool_compare_and_swap(&m_role, -1, role_id);
+}
+
diff --git a/gcc/testsuite/gcc.target/arm/synchronize.c b/gcc/testsuite/gcc.target/arm/synchronize.c
index 8626d8ee0a3..7ef10e2d97a 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 c2511c643b4..e7eef6d7a90 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 9d7167304e3..3f4fbf76479 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 efb5f573fae..b0e0e79bdd8 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 e527b381625..e0eb92b57c9 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 0b5839669a7..1a53ba14a00 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 eac460fef97..e98d1b684de 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 753625892d7..26c993be7e9 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 39b6f3bef16..6d734faa25e 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 87225ba3e5d..716acfef65c 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 8b00fe1ef85..01173afb223 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 37d062c3a2a..8cda521a870 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 7311913e837..9f2331b51e8 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 a7a337be1d9..9e33975b1e4 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 fcb596c550d..28d264dd20d 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 b85971ddb34..fea0b20619d 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 9cd02495b1b..dd5f543f58c 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 8388cfe03f3..38853353b01 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 bb8df69893b..5a7bb217836 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 3adf99f57fc..0b0454ed336 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 ddf05e200d8..03bf8e84835 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/mips/mips32-dsp-accinit-2.c b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
index 8d06a8039a1..74608d943b9 100644
--- a/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
+++ b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
@@ -5,7 +5,8 @@
/* { dg-skip-if "requires register frequencies" { *-*-* } { "-O0" "-Os" } { "" } } */
/* Check that the zero-initialization of the accumulator feeding into
- the madd is done by means of a mult instruction instead of mthi/mtlo. */
+ the madd is done by means of an mthi & mtlo pair instead of a
+ "mult $0,$0" instruction. */
NOMIPS16 long long f (int n, int *v, int m)
{
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-13.c b/gcc/testsuite/gcc.target/sh/pr51244-13.c
new file mode 100644
index 00000000000..7e823dc030c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-13.c
@@ -0,0 +1,85 @@
+/* This is a case extracted from CSiBE which contained the following
+ sequence:
+ shll r0
+ movt r0
+ tst r0,r0
+ bf .L11
+ where the 'tst r0,r0' before the branch can be omitted by inverting the
+ branch condition. The tested function contains two other tst insns. If
+ everything goes as expected we will be seeing only those other two tst
+ insns. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-times "tst" 2 } } */
+
+static __inline__ int
+__test_bit (unsigned long nr, volatile void * addr)
+{
+ /* This is on purpose. */
+ int oldbit;
+ return oldbit & 1;
+}
+
+static __inline__ int
+__constant_test_bit (unsigned long nr, volatile void * addr)
+{
+ return (((volatile char *) addr)[(nr>>3)^7] & (1<<(nr&7))) != 0;
+}
+
+struct list_head
+{
+ struct list_head *next, *prev;
+};
+
+static inline void
+__list_del (struct list_head *prev, struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void
+list_del (struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = 0;
+ entry->prev = 0;
+}
+
+extern int nr_active_pages;
+extern int nr_inactive_pages;
+extern struct list_head active_list;
+
+typedef struct page
+{
+ unsigned long flags;
+ struct list_head lru;
+} mem_map_t;
+
+void
+activate_page_nolock (struct page * page)
+{
+ if ((__builtin_constant_p((6))
+ ? __constant_test_bit((6),(&(page)->flags))
+ : __test_bit((6),(&(page)->flags)) )
+ && !(__builtin_constant_p((7))
+ ? __constant_test_bit((7),(&(page)->flags))
+ : __test_bit((7),(&(page)->flags)) ))
+ {
+ list_del(&(page)->lru);
+ nr_inactive_pages--;
+ if (!(__builtin_constant_p(6) ? __constant_test_bit((6),(&(page)->flags))
+ : __test_bit((6),(&(page)->flags))))
+ printk("", "", 43);
+
+ if ((__builtin_constant_p(7) ? __constant_test_bit((7),(&(page)->flags))
+ : __test_bit((7),(&(page)->flags))))
+ printk("", "", 43);
+
+ (__builtin_constant_p(7) ? __constant_set_bit((7),(&(page)->flags))
+ : __set_bit((7),(&(page)->flags)) );
+ list_add(&(page)->lru, &active_list);
+ nr_active_pages++;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-14.c b/gcc/testsuite/gcc.target/sh/pr51244-14.c
new file mode 100644
index 00000000000..0ff7008fbc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-14.c
@@ -0,0 +1,107 @@
+/* This is a case extracted from CSiBE which would sometimes contain the
+ following sequence:
+ cmp/eq r12,r13
+ movt r0
+ xor #1,r0
+ extu.b r0,r0
+ movt r3
+ tst r0,r0
+ bf/s .L35
+ where the negated T bit store did not combine properly. Since there are
+ other movt insns we only check for the xor and the extu. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-not "xor|extu" } } */
+
+typedef struct transaction_s transaction_t;
+
+struct journal_head
+{
+ transaction_t * b_transaction;
+ struct journal_head *b_cpnext, *b_cpprev;
+};
+
+struct transaction_s
+{
+ struct journal_head * t_checkpoint_list;
+ transaction_t *t_cpnext, *t_cpprev;
+};
+
+struct journal_s
+{
+ transaction_t * j_checkpoint_transactions;
+ unsigned long j_first, j_last;
+};
+
+typedef struct journal_s journal_t;
+
+extern int __try_to_free_cp_buf (struct journal_head *jh);
+extern int __cleanup_transaction (journal_t *journal, transaction_t *transaction);
+extern void __flush_batch (void **bhs, int *batch_count);
+extern void* jh2bh (void*);
+
+static int
+__flush_buffer (journal_t *journal, struct journal_head *jh,
+ void **bhs, int *batch_count, int *drop_count)
+{
+ void *bh = jh2bh (jh);
+ int ret = 0;
+ if (bh)
+ {
+ bhs[*batch_count] = bh;
+ (*batch_count)++;
+ if (*batch_count == 64)
+ ret = 1;
+ }
+ else
+ {
+ int last_buffer = 0;
+ if (jh->b_cpnext == jh)
+ last_buffer = 1;
+ if (__try_to_free_cp_buf (jh))
+ {
+ (*drop_count)++;
+ ret = last_buffer;
+ }
+ }
+ return ret;
+}
+
+int
+log_do_checkpoint (journal_t *journal, int nblocks)
+{
+ transaction_t *transaction, *last_transaction, *next_transaction;
+ int batch_count = 0;
+ void *bhs[64];
+
+repeat:
+ transaction = journal->j_checkpoint_transactions;
+ if (transaction == ((void *)0))
+ return 0;
+ last_transaction = transaction->t_cpprev;
+ next_transaction = transaction;
+ do
+ {
+ struct journal_head *jh, *last_jh, *next_jh;
+ int drop_count = 0;
+ int cleanup_ret, retry = 0;
+ transaction = next_transaction;
+ next_transaction = transaction->t_cpnext;
+ jh = transaction->t_checkpoint_list;
+ last_jh = jh->b_cpprev;
+ next_jh = jh;
+ do
+ {
+ jh = next_jh;
+ next_jh = jh->b_cpnext;
+ retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
+ } while (jh != last_jh && !retry);
+
+ if (retry)
+ goto repeat;
+
+ cleanup_ret = __cleanup_transaction(journal, transaction);
+ goto repeat;
+ } while (transaction != last_transaction);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-15.c b/gcc/testsuite/gcc.target/sh/pr51244-15.c
new file mode 100644
index 00000000000..ec98d5e6138
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-15.c
@@ -0,0 +1,71 @@
+/* Check that the redundant test removal code in the *cbranch_t split works
+ as expected on non-SH2A targets. Because on SH2A the movrt instruction
+ is used, this test is re-used and checked differently in pr51244-16.c. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */
+/* { dg-final { scan-assembler-times "tst" 6 } } */
+/* { dg-final { scan-assembler-times "movt" 6 } } */
+/* { dg-final { scan-assembler-times "xor" 3 } } */
+/* { dg-final { scan-assembler-not "extu|exts|negc" } } */
+
+typedef char bool;
+
+int
+test_0 (int a, int b, int c, int* d)
+{
+ /* non SH2A: 1x tst, 1x movt, 1x xor
+ SH2A: 1x tst, 1x movrt */
+ bool x = a == 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_1 (int a, int b, int c, int* d)
+{
+ /* 1x tst, 1x movt */
+ bool x = a != 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_2 (int a, int b, int c, char* d)
+{
+ /* Check that there is no sign/zero-extension before the store.
+ non SH2A: 1x tst, 1x movt, 1x xor
+ SH2A: 1x tst, 1x movrt */
+ bool x = a == 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_3 (int a, int b, int c, char* d)
+{
+ /* Check that there is no sign/zero-extension before the store.
+ 1x tst, 1x movt */
+ bool x = a != 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_4 (int a, int b, int c, char* d)
+{
+ /* 1x tst, 1x movt */
+ bool x = a != 0;
+ d[2] = !x;
+ return !x ? b : c;
+}
+
+int
+test_5 (int a, int b, int c, char* d)
+{
+ /* non SH2A: 1x tst, 1x movt, 1x xor
+ SH2A: 1x tst, 1x movrt */
+ bool x = a == 0;
+ d[2] = !x;
+ return !x ? b : c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-16.c b/gcc/testsuite/gcc.target/sh/pr51244-16.c
new file mode 100644
index 00000000000..8717df7f34a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-16.c
@@ -0,0 +1,11 @@
+/* Check that the redundant test removal code in the *cbranch_t split works
+ as expected on SH2A targets. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */
+/* { dg-final { scan-assembler-times "tst" 6 } } */
+/* { dg-final { scan-assembler-times "movt" 3 } } */
+/* { dg-final { scan-assembler-times "movrt" 3 } } */
+/* { dg-final { scan-assembler-not "extu|exts|negc" } } */
+
+#include "pr51244-15.c"
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 00000000000..e7d1ddd2ad0
--- /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/pr54602-1.c b/gcc/testsuite/gcc.target/sh/pr54602-1.c
new file mode 100644
index 00000000000..e5c035708e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-1.c
@@ -0,0 +1,15 @@
+/* Verify that the delay slot is stuffed with register pop insns for normal
+ (i.e. not interrupt handler) function returns. If everything goes as
+ expected we won't see any nop insns. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+int test00 (int a, int b);
+
+int
+test01 (int a, int b, int c, int d)
+{
+ return test00 (a, b) + c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-2.c b/gcc/testsuite/gcc.target/sh/pr54602-2.c
new file mode 100644
index 00000000000..4f3877c41b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-2.c
@@ -0,0 +1,15 @@
+/* Verify that the delay slot is not stuffed with register pop insns for
+ interrupt handler function returns on SH1* and SH2* targets, where the
+ rte insn uses the stack pointer. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m1*" "-m2*" } } */
+/* { dg-final { scan-assembler-times "nop" 1 } } */
+
+int test00 (int a, int b);
+
+int __attribute__ ((interrupt_handler))
+test01 (int a, int b, int c, int d)
+{
+ return test00 (a, b) + c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-3.c b/gcc/testsuite/gcc.target/sh/pr54602-3.c
new file mode 100644
index 00000000000..29292589c62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-3.c
@@ -0,0 +1,12 @@
+/* Verify that the rte delay slot is not stuffed with register pop insns
+ which touch the banked registers r0..r7 on SH3* and SH4* targets. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } } */
+/* { dg-final { scan-assembler-times "nop" 1 } } */
+
+int __attribute__ ((interrupt_handler))
+test00 (int a, int b, int c, int d)
+{
+ return a + b;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-4.c b/gcc/testsuite/gcc.target/sh/pr54602-4.c
new file mode 100644
index 00000000000..0b77d0983ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-4.c
@@ -0,0 +1,15 @@
+/* Verify that the delay slot is stuffed with register pop insns on SH3* and
+ SH4* targets, where the stack pointer is not used by the rte insn. If
+ everything works out, we won't see a nop insn. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } } */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+int test00 (int a, int b);
+
+int __attribute__ ((interrupt_handler))
+test01 (int a, int b, int c, int d)
+{
+ return test00 (a, b) + c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54680.c b/gcc/testsuite/gcc.target/sh/pr54680.c
new file mode 100644
index 00000000000..27c44d3ca4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54680.c
@@ -0,0 +1,66 @@
+/* Verify that the fsca input value is not converted to float and then back
+ to int. Notice that we can't count just "lds" insns because mode switches
+ use "lds.l". */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2 -mfsca -funsafe-math-optimizations" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m3*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-times "fsca" 7 } } */
+/* { dg-final { scan-assembler-times "shad" 1 } } */
+/* { dg-final { scan-assembler-times "lds\t" 6 } } */
+/* { dg-final { scan-assembler-times "fmul" 2 } } */
+/* { dg-final { scan-assembler-times "ftrc" 1 } } */
+
+#include <math.h>
+
+static const float pi = 3.14159265359f;
+
+float
+test00 (int x)
+{
+ /* 1x shad, 1x lds, 1x fsca */
+ return sinf ( (x >> 8) * (2*pi) / (1 << 16));
+}
+
+float
+test01 (int x)
+{
+ /* 1x lds, 1x fsca */
+ return sinf (x * (2*pi) / 65536);
+}
+
+float
+test02 (int x)
+{
+ /* 1x lds, 1x fsca */
+ return sinf (x * (2*pi / 65536));
+}
+
+float
+test03 (int x)
+{
+ /* 1x lds, 1x fsca */
+ float scale = 2*pi / 65536;
+ return sinf (x * scale);
+}
+
+float
+test04 (int x)
+{
+ /* 1x lds, 1x fsca */
+ return cosf (x / 65536.0f * 2*pi);
+}
+
+float
+test05 (int x)
+{
+ /* 1x lds, 1x fsca, 1x fmul */
+ float scale = 2*pi / 65536;
+ return sinf (x * scale) * cosf (x * scale);
+}
+
+float
+test_06 (float x)
+{
+ /* 1x fmul, 1x ftrc, 1x fsca */
+ return sinf (x);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54760-2.c b/gcc/testsuite/gcc.target/sh/pr54760-2.c
index b8a50184785..91f3648a599 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 00000000000..3ee36a31389
--- /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 00000000000..b2ec56adff7
--- /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 00000000000..f025aa3ef24
--- /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_allocate_13.f90 b/gcc/testsuite/gfortran.dg/class_allocate_13.f90
new file mode 100644
index 00000000000..64f37dc59b5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_allocate_13.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+!
+! PR 54784: [4.7/4.8 Regression] [OOP] wrong code in polymorphic allocation with SOURCE
+!
+! Contributed by Jeremy Kozdon <jkozdon@gmail.com>
+
+program bug
+ implicit none
+
+ type :: block
+ real, allocatable :: fields
+ end type
+
+ type :: list
+ class(block),allocatable :: B
+ end type
+
+ type :: domain
+ type(list),dimension(2) :: L
+ end type
+
+ type(domain) :: d
+ type(block) :: b1
+
+ allocate(b1%fields,source=5.)
+
+ allocate(d%L(2)%B,source=b1) ! wrong code
+
+ if (d%L(2)%B%fields/=5.) call abort()
+
+end program
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 00000000000..2b408dbda05
--- /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 00000000000..90b1719c117
--- /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 171275af3f2..8ed0f7fb6c2 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/dummy_procedure_9.f90 b/gcc/testsuite/gfortran.dg/dummy_procedure_9.f90
new file mode 100644
index 00000000000..16da37f1893
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dummy_procedure_9.f90
@@ -0,0 +1,37 @@
+! { dg-do compile }
+!
+! PR 40453: [F95] Enhanced (recursive) argument checking
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+program RecursiveInterface
+
+ call c(b2) ! { dg-error "Interface mismatch in dummy procedure" }
+
+ contains
+
+ subroutine a1(x)
+ real :: x
+ end subroutine
+
+ subroutine a2(i)
+ integer :: i
+ end subroutine
+
+ !!!!!!!!!!!!!!!
+
+ subroutine b1 (f1)
+ procedure(a1) :: f1
+ end subroutine
+
+ subroutine b2 (f2)
+ procedure(a2) :: f2
+ end subroutine
+
+ !!!!!!!!!!!!!!!
+
+ subroutine c(g)
+ procedure(b1) :: g
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gfortran.dg/enum_10.f90 b/gcc/testsuite/gfortran.dg/enum_10.f90
index b387fe339e9..80e7fca8013 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 8a5c60a10f4..d3187c75b9b 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 00000000000..68c6bee00b1
--- /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 00000000000..d03b7047a12
--- /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 00000000000..ffc516ff7ba
--- /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 00000000000..2d3b8e59f18
--- /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 00000000000..8f98b6e1f12
--- /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 00000000000..133f3b94c6a
--- /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 00000000000..d4595f52a02
--- /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 9098285267f..2ab630e4d5b 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2053,7 +2053,8 @@ proc check_effective_target_arm_vfp_ok { } {
# options.
proc check_effective_target_arm_hard_vfp_ok { } {
- if { [check_effective_target_arm32] } {
+ if { [check_effective_target_arm32]
+ && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
return [check_no_compiler_messages arm_hard_vfp_ok executable {
int main() { return 0;}
} "-mfpu=vfp -mfloat-abi=hard"]
@@ -2245,7 +2246,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" ] &&
@@ -3923,7 +3925,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 ()
@@ -3967,7 +3969,7 @@ proc check_effective_target_sync_int_long { } {
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
|| [istarget alpha*-*-*]
- || [istarget arm*-*-linux-gnueabi]
+ || [istarget arm*-*-linux-*]
|| [istarget bfin*-*linux*]
|| [istarget hppa*-*linux*]
|| [istarget s390*-*-*]
@@ -3998,7 +4000,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/testsuite/obj-c++.dg/tls/init-2.mm b/gcc/testsuite/obj-c++.dg/tls/init-2.mm
index dc886ba0107..327c309e985 100644
--- a/gcc/testsuite/obj-c++.dg/tls/init-2.mm
+++ b/gcc/testsuite/obj-c++.dg/tls/init-2.mm
@@ -2,13 +2,13 @@
/* { dg-require-effective-target tls } */
extern __thread int i;
-__thread int *p = &i; /* { dg-error "dynamically initialized" } */
+__thread int *p = &i; /* { dg-error "dynamic initialization" } */
extern int f();
-__thread int j = f(); /* { dg-error "dynamically initialized" } */
+__thread int j = f(); /* { dg-error "dynamic initialization" } */
struct S
{
S();
};
-__thread S s; /* { dg-error "" } two errors here */
+__thread S s; /* { dg-error "dynamic initialization" } */
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ef384acd7dc..211c45e48fb 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-loop-distribution.c b/gcc/tree-loop-distribution.c
index d29fe1cd386..1ffc434f4a4 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -125,8 +125,12 @@ ssa_name_has_uses_outside_loop_p (tree def, loop_p loop)
use_operand_p use_p;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
- if (loop != loop_containing_stmt (USE_STMT (use_p)))
- return true;
+ {
+ gimple use_stmt = USE_STMT (use_p);
+ if (!is_gimple_debug (use_stmt)
+ && loop != loop_containing_stmt (use_stmt))
+ return true;
+ }
return false;
}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index eb1af4e9e45..b6c5654da01 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 b790e1f43cc..81bf09e9f8a 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-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index cdcdb5c5ad8..3c39413ee1b 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2965,6 +2965,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
struct tree_niter_desc niter_desc;
edge ex;
double_int bound;
+ edge likely_exit;
/* Give up if we already have tried to compute an estimation. */
if (loop->estimate_state != EST_NOT_COMPUTED)
@@ -2975,6 +2976,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
loop->any_estimate = false;
exits = get_loop_exit_edges (loop);
+ likely_exit = single_likely_exit (loop);
FOR_EACH_VEC_ELT (edge, exits, i, ex)
{
if (!number_of_iterations_exit (loop, ex, &niter_desc, false))
@@ -2988,7 +2990,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
niter);
record_estimate (loop, niter, niter_desc.max,
last_stmt (ex->src),
- true, true, true);
+ true, ex == likely_exit, true);
}
VEC_free (edge, heap, exits);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index fe9186cefa9..548c110f6d2 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-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 2eee50ee1d6..ad64876c339 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -846,9 +846,15 @@ static bool
def_split_header_continue_p (const_basic_block bb, const void *data)
{
const_basic_block new_header = (const_basic_block) data;
- return (bb != new_header
- && (loop_depth (bb->loop_father)
- >= loop_depth (new_header->loop_father)));
+ const struct loop *l;
+
+ if (bb == new_header
+ || loop_depth (bb->loop_father) < loop_depth (new_header->loop_father))
+ return false;
+ for (l = bb->loop_father; l; l = loop_outer (l))
+ if (l == new_header->loop_father)
+ return true;
+ return false;
}
/* Thread jumps through the header of LOOP. Returns true if cfg changes.
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index cfaaf4538b7..f573659edd1 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,10 +376,44 @@ 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. */
+
+static void
+unpack_ts_target_option (struct bitpack_d *bp, tree expr)
+{
+ unsigned i, len;
+ struct cl_target_option *t = TREE_TARGET_OPTION (expr);
+
+ len = sizeof (struct cl_target_option);
+ for (i = 0; i < len; i++)
+ ((unsigned char *)t)[i] = bp_unpack_value (bp, 8);
+ if (bp_unpack_value (bp, 32) != 0x12345678)
+ fatal_error ("cl_target_option size mismatch in LTO reader and writer");
+}
+
+/* Unpack a TS_OPTIMIZATION tree from BP into EXPR. */
+
+static void
+unpack_ts_optimization (struct bitpack_d *bp, tree expr)
+{
+ unsigned i, len;
+ struct cl_optimization *t = TREE_OPTIMIZATION (expr);
+
+ len = sizeof (struct cl_optimization);
+ for (i = 0; i < len; i++)
+ ((unsigned char *)t)[i] = bp_unpack_value (bp, 8);
+ if (bp_unpack_value (bp, 32) != 0x12345678)
+ fatal_error ("cl_optimization size mismatch in LTO reader and writer");
+}
+
+
/* Unpack all the non-pointer fields in EXPR into a bit pack. */
static void
@@ -383,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);
@@ -414,7 +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);
+ }
}
@@ -590,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))
@@ -617,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)
@@ -776,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));
@@ -841,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
@@ -861,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);
@@ -886,65 +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_TARGET_OPTION tree from IB into EXPR. */
-
-static void
-lto_input_ts_target_option (struct lto_input_block *ib, tree expr)
-{
- unsigned i, len;
- struct bitpack_d bp;
- struct cl_target_option *t = TREE_TARGET_OPTION (expr);
-
- bp = streamer_read_bitpack (ib);
- len = sizeof (struct cl_target_option);
- for (i = 0; i < len; i++)
- ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8);
- if (bp_unpack_value (&bp, 32) != 0x12345678)
- fatal_error ("cl_target_option size mismatch in LTO reader and writer");
-}
-
-/* Input a TS_OPTIMIZATION tree from IB into EXPR. */
-
-static void
-lto_input_ts_optimization (struct lto_input_block *ib, tree expr)
-{
- unsigned i, len;
- struct bitpack_d bp;
- struct cl_optimization *t = TREE_OPTIMIZATION (expr);
-
- bp = streamer_read_bitpack (ib);
- len = sizeof (struct cl_optimization);
- for (i = 0; i < len; i++)
- ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8);
- if (bp_unpack_value (&bp, 32) != 0x12345678)
- fatal_error ("cl_optimization size mismatch in LTO reader and writer");
-}
-
-/* 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. */
@@ -1006,15 +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_TARGET_OPTION))
- lto_input_ts_target_option (ib, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
- lto_input_ts_optimization (ib, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- lto_input_ts_translation_unit_decl_tree_pointers (ib, data_in, expr);
}
@@ -1024,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 73ffb301fda..1f0eb55ec44 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,46 @@ 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. */
+
+static void
+pack_ts_target_option (struct bitpack_d *bp, tree expr)
{
+ struct cl_target_option *t = TREE_TARGET_OPTION (expr);
+ unsigned i, len;
+
+ /* The cl_target_option is target specific and generated by the options
+ awk script, so we just recreate a byte-by-byte copy here. */
+
+ len = sizeof (struct cl_target_option);
+ for (i = 0; i < len; i++)
+ bp_pack_value (bp, ((unsigned char *)t)[i], 8);
+ /* Catch struct size mismatches between reader and writer. */
+ bp_pack_value (bp, 0x12345678, 32);
+}
+
+/* Pack a TS_OPTIMIZATION tree in EXPR to BP. */
+
+static void
+pack_ts_optimization (struct bitpack_d *bp, tree expr)
+{
+ struct cl_optimization *t = TREE_OPTIMIZATION (expr);
+ unsigned i, len;
+
+ /* The cl_optimization is generated by the options
+ awk script, so we just recreate a byte-by-byte copy here. */
+
+ len = sizeof (struct cl_optimization);
+ for (i = 0; i < len; i++)
+ bp_pack_value (bp, ((unsigned char *)t)[i], 8);
+ /* Catch struct size mismatches between reader and writer. */
+ bp_pack_value (bp, 0x12345678, 32);
}
@@ -335,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);
@@ -366,7 +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));
}
@@ -412,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;
@@ -438,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);
}
@@ -513,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))
@@ -536,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)
@@ -683,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);
@@ -744,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);
@@ -765,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);
@@ -773,58 +832,6 @@ write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
}
}
-/* Write a TS_TARGET_OPTION tree in EXPR to OB. */
-
-static void
-write_ts_target_option (struct output_block *ob, tree expr)
-{
- struct cl_target_option *t = TREE_TARGET_OPTION (expr);
- struct bitpack_d bp;
- unsigned i, len;
-
- /* The cl_target_option is target specific and generated by the options
- awk script, so we just recreate a byte-by-byte copy here. */
-
- bp = bitpack_create (ob->main_stream);
- len = sizeof (struct cl_target_option);
- for (i = 0; i < len; i++)
- bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
- /* Catch struct size mismatches between reader and writer. */
- bp_pack_value (&bp, 0x12345678, 32);
- streamer_write_bitpack (&bp);
-}
-
-/* Write a TS_OPTIMIZATION tree in EXPR to OB. */
-
-static void
-write_ts_optimization (struct output_block *ob, tree expr)
-{
- struct cl_optimization *t = TREE_OPTIMIZATION (expr);
- struct bitpack_d bp;
- unsigned i, len;
-
- /* The cl_optimization is generated by the options
- awk script, so we just recreate a byte-by-byte copy here. */
-
- bp = bitpack_create (ob->main_stream);
- len = sizeof (struct cl_optimization);
- for (i = 0; i < len; i++)
- bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
- /* Catch struct size mismatches between reader and writer. */
- bp_pack_value (&bp, 0x12345678, 32);
- streamer_write_bitpack (&bp);
-}
-
-/* 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,15 +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_TARGET_OPTION))
- write_ts_target_option (ob, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
- write_ts_optimization (ob, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- write_ts_translation_unit_decl_tree_pointers (ob, expr);
}
@@ -951,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-loop.c b/gcc/tree-vect-loop.c
index 58edfcbe480..6b8ba3f7091 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2382,7 +2382,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (orig_code == MINUS_EXPR)
{
tree rhs = gimple_assign_rhs2 (def_stmt);
- tree negrhs = copy_ssa_name (rhs, NULL);
+ tree negrhs = make_ssa_name (TREE_TYPE (rhs), NULL);
gimple negate_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, negrhs,
rhs, NULL);
gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 92eaac48a41..09c85967d43 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));
@@ -6060,11 +6066,6 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
&& GET_MODE_CLASS (inner_mode) != MODE_FLOAT)
return NULL_TREE;
- /* We can't build a vector type of elements with alignment bigger than
- their size. */
- if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
- return NULL_TREE;
-
/* For vector types of elements whose mode precision doesn't
match their types precision we use a element type of mode
precision. The vectorization routines will have to make sure
@@ -6081,11 +6082,21 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
When the component mode passes the above test simply use a type
corresponding to that mode. The theory is that any use that
would cause problems with this will disable vectorization anyway. */
- if (!SCALAR_FLOAT_TYPE_P (scalar_type)
- && !INTEGRAL_TYPE_P (scalar_type)
- && !POINTER_TYPE_P (scalar_type))
+ else if (!SCALAR_FLOAT_TYPE_P (scalar_type)
+ && !INTEGRAL_TYPE_P (scalar_type)
+ && !POINTER_TYPE_P (scalar_type))
scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
+ /* We can't build a vector type of elements with alignment bigger than
+ their size. */
+ else if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
+ scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
+
+ /* If we felt back to using the mode fail if there was
+ no scalar type for it. */
+ if (scalar_type == NULL_TREE)
+ return NULL_TREE;
+
/* If no size was supplied use the mode the target prefers. Otherwise
lookup a vector mode of the specified size. */
if (size == 0)
diff --git a/gcc/tree.c b/gcc/tree.c
index 8df1b86d2be..d974362de27 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.def b/gcc/tree.def
index 70188ff0524..0f470006a70 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1093,8 +1093,11 @@ DEFTREECODE (TRANSACTION_EXPR, "transaction_expr", tcc_expression, 1)
Operations that take a vector of elements and "reduce" it to a scalar
result (e.g. summing the elements of the vector, finding the minimum over
the vector elements, etc).
- Operand 0 is a vector; the first element in the vector has the result.
- Operand 1 is a vector. */
+ Operand 0 is a vector.
+ The expression returns a vector of the same type, with the first
+ element in the vector holding the result of the reduction of all elements
+ of the operand. The content of the other elements in the returned vector
+ is undefined. */
DEFTREECODE (REDUC_MAX_EXPR, "reduc_max_expr", tcc_unary, 1)
DEFTREECODE (REDUC_MIN_EXPR, "reduc_min_expr", tcc_unary, 1)
DEFTREECODE (REDUC_PLUS_EXPR, "reduc_plus_expr", tcc_unary, 1)
diff --git a/gcc/tree.h b/gcc/tree.h
index 12e7948d318..c6a5eab5024 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 6a6cd420a0c..25973a9776e 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 f60b4b6ad84..d56563430c2 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));
}
}
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index ecb51dfd17d..952c96fbfea 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,13 @@
+2012-10-11 Ian Lance Taylor <iant@google.com>
+
+ * configure.ac: Do not use dl_iterate_phdr on Solaris 10.
+ * configure: Rebuild.
+
+2012-10-10 Ian Lance Taylor <iant@google.com>
+
+ * elf.c: Rename all Elf typedefs to start with b_elf, and be all
+ lower case.
+
2012-10-10 Hans-Peter Nilsson <hp@bitrange.com>
* elf.c (elf_add_syminfo_data): Add casts to avoid warning.
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 8d34856e693..9a88e8e48e8 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -12213,6 +12213,12 @@ else
fi
rm -f conftest*
+ case "${host}" in
+ *-*-solaris2.10*)
+ # Avoid dl_iterate_phdr on Solaris 10, where it is in the
+ # header file but is only in -ldl.
+ have_dl_iterate_phdr=no ;;
+ esac
else
ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr"
if test "x$ac_cv_func_dl_iterate_phdr" = x""yes; then :
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 083a086c85a..9633afd5ac3 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -235,6 +235,12 @@ else
# When built as a GCC target library, we can't do a link test.
AC_EGREP_HEADER([dl_iterate_phdr], [link.h], [have_dl_iterate_phdr=yes],
[have_dl_iterate_phdr=no])
+ case "${host}" in
+ *-*-solaris2.10*)
+ # Avoid dl_iterate_phdr on Solaris 10, where it is in the
+ # header file but is only in -ldl.
+ have_dl_iterate_phdr=no ;;
+ esac
else
AC_CHECK_FUNC([dl_iterate_phdr], [have_dl_iterate_phdr=yes],
[have_dl_iterate_phdr=no])
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 518e125a101..b396c47ef29 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -105,25 +105,25 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
/* Basic types. */
-typedef uint16_t Elf_Half;
-typedef uint32_t Elf_Word;
-typedef int32_t Elf_Sword;
+typedef uint16_t b_elf_half; /* Elf_Half. */
+typedef uint32_t b_elf_word; /* Elf_Word. */
+typedef int32_t b_elf_sword; /* Elf_Sword. */
#if BACKTRACE_ELF_SIZE == 32
-typedef uint32_t Elf_Addr;
-typedef uint32_t Elf_Off;
+typedef uint32_t b_elf_addr; /* Elf_Addr. */
+typedef uint32_t b_elf_off; /* Elf_Off. */
-typedef uint32_t Elf_WXword;
+typedef uint32_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
#else
-typedef uint64_t Elf_Addr;
-typedef uint64_t Elf_Off;
-typedef uint64_t Elf_Xword;
-typedef int64_t Elf_Sxword;
+typedef uint64_t b_elf_addr; /* Elf_Addr. */
+typedef uint64_t b_elf_off; /* Elf_Off. */
+typedef uint64_t b_elf_xword; /* Elf_Xword. */
+typedef int64_t b_elf_sxword; /* Elf_Sxword. */
-typedef uint64_t Elf_WXword;
+typedef uint64_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
#endif
@@ -133,20 +133,20 @@ typedef uint64_t Elf_WXword;
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
- Elf_Half e_type; /* Identifies object file type */
- Elf_Half e_machine; /* Specifies required architecture */
- Elf_Word e_version; /* Identifies object file version */
- Elf_Addr e_entry; /* Entry point virtual address */
- Elf_Off e_phoff; /* Program header table file offset */
- Elf_Off e_shoff; /* Section header table file offset */
- Elf_Word e_flags; /* Processor-specific flags */
- Elf_Half e_ehsize; /* ELF header size in bytes */
- Elf_Half e_phentsize; /* Program header table entry size */
- Elf_Half e_phnum; /* Program header table entry count */
- Elf_Half e_shentsize; /* Section header table entry size */
- Elf_Half e_shnum; /* Section header table entry count */
- Elf_Half e_shstrndx; /* Section header string table index */
-} Elf_Ehdr;
+ b_elf_half e_type; /* Identifies object file type */
+ b_elf_half e_machine; /* Specifies required architecture */
+ b_elf_word e_version; /* Identifies object file version */
+ b_elf_addr e_entry; /* Entry point virtual address */
+ b_elf_off e_phoff; /* Program header table file offset */
+ b_elf_off e_shoff; /* Section header table file offset */
+ b_elf_word e_flags; /* Processor-specific flags */
+ b_elf_half e_ehsize; /* ELF header size in bytes */
+ b_elf_half e_phentsize; /* Program header table entry size */
+ b_elf_half e_phnum; /* Program header table entry count */
+ b_elf_half e_shentsize; /* Section header table entry size */
+ b_elf_half e_shnum; /* Section header table entry count */
+ b_elf_half e_shstrndx; /* Section header string table index */
+} b_elf_ehdr; /* Elf_Ehdr. */
#define EI_MAG0 0
#define EI_MAG1 1
@@ -170,17 +170,17 @@ typedef struct {
#define EV_CURRENT 1
typedef struct {
- Elf_Word sh_name; /* Section name, index in string tbl */
- Elf_Word sh_type; /* Type of section */
- Elf_WXword sh_flags; /* Miscellaneous section attributes */
- Elf_Addr sh_addr; /* Section virtual addr at execution */
- Elf_Off sh_offset; /* Section file offset */
- Elf_WXword sh_size; /* Size of section in bytes */
- Elf_Word sh_link; /* Index of another section */
- Elf_Word sh_info; /* Additional section information */
- Elf_WXword sh_addralign; /* Section alignment */
- Elf_WXword sh_entsize; /* Entry size if section holds table */
-} Elf_Shdr;
+ b_elf_word sh_name; /* Section name, index in string tbl */
+ b_elf_word sh_type; /* Type of section */
+ b_elf_wxword sh_flags; /* Miscellaneous section attributes */
+ b_elf_addr sh_addr; /* Section virtual addr at execution */
+ b_elf_off sh_offset; /* Section file offset */
+ b_elf_wxword sh_size; /* Size of section in bytes */
+ b_elf_word sh_link; /* Index of another section */
+ b_elf_word sh_info; /* Additional section information */
+ b_elf_wxword sh_addralign; /* Section alignment */
+ b_elf_wxword sh_entsize; /* Entry size if section holds table */
+} b_elf_shdr; /* Elf_Shdr. */
#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
@@ -193,25 +193,25 @@ typedef struct {
typedef struct
{
- Elf_Word st_name; /* Symbol name, index in string tbl */
- Elf_Addr st_value; /* Symbol value */
- Elf_Word st_size; /* Symbol size */
+ b_elf_word st_name; /* Symbol name, index in string tbl */
+ b_elf_addr st_value; /* Symbol value */
+ b_elf_word st_size; /* Symbol size */
unsigned char st_info; /* Symbol binding and type */
unsigned char st_other; /* Visibility and other data */
- Elf_Half st_shndx; /* Symbol section index */
-} Elf_Sym;
+ b_elf_half st_shndx; /* Symbol section index */
+} b_elf_sym; /* Elf_Sym. */
#else /* BACKTRACE_ELF_SIZE != 32 */
typedef struct
{
- Elf_Word st_name; /* Symbol name, index in string tbl */
+ b_elf_word st_name; /* Symbol name, index in string tbl */
unsigned char st_info; /* Symbol binding and type */
unsigned char st_other; /* Visibility and other data */
- Elf_Half st_shndx; /* Symbol section index */
- Elf_Addr st_value; /* Symbol value */
- Elf_Xword st_size; /* Symbol size */
-} Elf_Sym;
+ b_elf_half st_shndx; /* Symbol section index */
+ b_elf_addr st_value; /* Symbol value */
+ b_elf_xword st_size; /* Symbol size */
+} b_elf_sym; /* Elf_Sym. */
#endif /* BACKTRACE_ELF_SIZE != 32 */
@@ -346,17 +346,17 @@ elf_initialize_syminfo (struct backtrace_state *state,
void *data, struct elf_syminfo_data *sdata)
{
size_t sym_count;
- const Elf_Sym *sym;
+ const b_elf_sym *sym;
size_t elf_symbol_count;
size_t elf_symbol_size;
struct elf_symbol *elf_symbols;
size_t i;
unsigned int j;
- sym_count = symtab_size / sizeof (Elf_Sym);
+ sym_count = symtab_size / sizeof (b_elf_sym);
/* We only care about function symbols. Count them. */
- sym = (const Elf_Sym *) symtab_data;
+ sym = (const b_elf_sym *) symtab_data;
elf_symbol_count = 0;
for (i = 0; i < sym_count; ++i, ++sym)
{
@@ -371,7 +371,7 @@ elf_initialize_syminfo (struct backtrace_state *state,
if (elf_symbols == NULL)
return 0;
- sym = (const Elf_Sym *) symtab_data;
+ sym = (const b_elf_sym *) symtab_data;
j = 0;
for (i = 0; i < sym_count; ++i, ++sym)
{
@@ -474,14 +474,14 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
fileline *fileline_fn, int *found_sym, int *found_dwarf)
{
struct backtrace_view ehdr_view;
- Elf_Ehdr ehdr;
+ b_elf_ehdr ehdr;
off_t shoff;
unsigned int shnum;
unsigned int shstrndx;
struct backtrace_view shdrs_view;
int shdrs_view_valid;
- const Elf_Shdr *shdrs;
- const Elf_Shdr *shstrhdr;
+ const b_elf_shdr *shdrs;
+ const b_elf_shdr *shstrhdr;
size_t shstr_size;
off_t shstr_off;
struct backtrace_view names_view;
@@ -558,13 +558,13 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
&& shoff != 0)
{
struct backtrace_view shdr_view;
- const Elf_Shdr *shdr;
+ const b_elf_shdr *shdr;
if (!backtrace_get_view (state, descriptor, shoff, sizeof shdr,
error_callback, data, &shdr_view))
goto fail;
- shdr = (const Elf_Shdr *) shdr_view.data;
+ shdr = (const b_elf_shdr *) shdr_view.data;
if (shnum == 0)
shnum = shdr->sh_size;
@@ -596,12 +596,12 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
/* Read the section headers, skipping the first one. */
- if (!backtrace_get_view (state, descriptor, shoff + sizeof (Elf_Shdr),
- (shnum - 1) * sizeof (Elf_Shdr),
+ if (!backtrace_get_view (state, descriptor, shoff + sizeof (b_elf_shdr),
+ (shnum - 1) * sizeof (b_elf_shdr),
error_callback, data, &shdrs_view))
goto fail;
shdrs_view_valid = 1;
- shdrs = (const Elf_Shdr *) shdrs_view.data;
+ shdrs = (const b_elf_shdr *) shdrs_view.data;
/* Read the section names. */
@@ -623,7 +623,7 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
/* Look for the symbol table. */
for (i = 1; i < shnum; ++i)
{
- const Elf_Shdr *shdr;
+ const b_elf_shdr *shdr;
unsigned int sh_name;
const char *name;
int j;
@@ -659,9 +659,9 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
symtab_shndx = dynsym_shndx;
if (symtab_shndx != 0)
{
- const Elf_Shdr *symtab_shdr;
+ const b_elf_shdr *symtab_shdr;
unsigned int strtab_shndx;
- const Elf_Shdr *strtab_shdr;
+ const b_elf_shdr *strtab_shdr;
struct elf_syminfo_data *sdata;
symtab_shdr = &shdrs[symtab_shndx - 1];
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 957b216d4a0..fdc151c9aa6 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 5b3a37b0279..6fc24e2af44 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 ab904db58be..23809bc4b0a 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 af11ac3a6e3..b57681392a6 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 d278f14370e..001bf3faeef 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 b09c22fe5f2..68b47d79d2b 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,36 @@
+2012-10-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config.host
+ (arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtemseabi*): Rename
+ "arm*-*-rtemseabi*" to "arm*-*-rtems*".
+
+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
+ instructions for 64bit targets only.
+
+2012-10-10 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/sfp-machine.h (FP_RND_NEAREST, FP_RND_ZERO, FP_RND_PINF,
+ FP_RND_MINF, FP_RND_MASK, FP_INIT_ROUNDMODE, _FP_DECL_EX): Move to ...
+ * config/i386/32/sfp-machine.h: ... here.
+ * config/i386/64/sfp-machine.h (FP_RND_NEAREST, FP_RND_ZERO,
+ FP_RND_PINF, FP_RND_MINF, FP_RND_MASK, FP_INIT_ROUNDMODE, _FP_DECL_EX):
+ New defines.
+
2012-10-07 Matthias Klose <doko@ubuntu.com>
* config/arm/unwind-arm.h (__gnu_unwind_24bit): Mark parameters
diff --git a/libgcc/config.host b/libgcc/config.host
index 763f6c3a252..8947e13ed33 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -316,7 +316,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
@@ -343,11 +343,11 @@ arm*-*-ecos-elf)
tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
extra_parts="$extra_parts crti.o crtn.o"
;;
-arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtemseabi*)
+arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
tmake_file="${tmake_file} arm/t-arm arm/t-elf t-fixedpoint-gnu-prefix"
tm_file="$tm_file arm/bpabi-lib.h"
case ${host} in
- arm*-*-eabi* | arm*-*-rtemseabi*)
+ arm*-*-eabi* | arm*-*-rtems*)
tmake_file="${tmake_file} arm/t-bpabi"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
;;
@@ -360,10 +360,6 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtemseabi*)
tmake_file="$tmake_file t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
unwind_header=config/arm/unwind-arm.h
;;
-arm*-*-rtems*)
- tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
arm*-*-elf)
tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
extra_parts="$extra_parts crti.o crtn.o"
diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
index 45c3251bd70..ac3c995a85f 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/config/i386/32/sfp-machine.h b/libgcc/config/i386/32/sfp-machine.h
index 7f0c099414d..474ade0d503 100644
--- a/libgcc/config/i386/32/sfp-machine.h
+++ b/libgcc/config/i386/32/sfp-machine.h
@@ -76,3 +76,18 @@
16byte since soft-fp emulation is done in 16byte. */
#define _FP_NANFRAC_E _FP_QNANBIT_E, 0, 0, 0
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 0xc00
+#define FP_RND_PINF 0x800
+#define FP_RND_MINF 0x400
+
+#define FP_RND_MASK 0xc00
+
+#define _FP_DECL_EX \
+ unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST;
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ __asm__ __volatile__ ("fnstcw\t%0" : "=m" (_fcw)); \
+ } while (0)
diff --git a/libgcc/config/i386/64/sfp-machine.h b/libgcc/config/i386/64/sfp-machine.h
index 8cc982ecc79..fc9a38af696 100644
--- a/libgcc/config/i386/64/sfp-machine.h
+++ b/libgcc/config/i386/64/sfp-machine.h
@@ -17,3 +17,18 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define _FP_NANFRAC_D _FP_QNANBIT_D
#define _FP_NANFRAC_E _FP_QNANBIT_E, 0
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 0x6000
+#define FP_RND_PINF 0x4000
+#define FP_RND_MINF 0x2000
+
+#define FP_RND_MASK 0x6000
+
+#define _FP_DECL_EX \
+ unsigned int _fcw __attribute__ ((unused)) = FP_RND_NEAREST;
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_fcw)); \
+ } while (0)
diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c
index 14b5ca1dbb3..0d5c2e0e3f5 100644
--- a/libgcc/config/i386/sfp-exceptions.c
+++ b/libgcc/config/i386/sfp-exceptions.c
@@ -46,7 +46,7 @@ __sfp_handle_exceptions (int _fex)
if (_fex & FP_EX_INVALID)
{
float f = 0.0f;
-#ifdef __SSE__
+#ifdef __x86_64__
asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
#else
asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
@@ -56,7 +56,7 @@ __sfp_handle_exceptions (int _fex)
if (_fex & FP_EX_DIVZERO)
{
float f = 1.0f, g = 0.0f;
-#ifdef __SSE__
+#ifdef __x86_64__
asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
#else
asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
diff --git a/libgcc/config/i386/sfp-machine.h b/libgcc/config/i386/sfp-machine.h
index 34b4ca10e14..01bf14ffbb0 100644
--- a/libgcc/config/i386/sfp-machine.h
+++ b/libgcc/config/i386/sfp-machine.h
@@ -55,21 +55,6 @@ void __sfp_handle_exceptions (int);
__sfp_handle_exceptions (_fex); \
} while (0);
-#define FP_RND_NEAREST 0
-#define FP_RND_ZERO 0xc00
-#define FP_RND_PINF 0x800
-#define FP_RND_MINF 0x400
-
-#define FP_RND_MASK 0xc00
-
-#define _FP_DECL_EX \
- unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE \
- do { \
- __asm__ __volatile__ ("fnstcw\t%0" : "=m" (_fcw)); \
- } while (0)
-
#define FP_ROUNDMODE (_fcw & FP_RND_MASK)
#define __LITTLE_ENDIAN 1234
diff --git a/libgcc/configure b/libgcc/configure
index a226f811659..ed6eabf2a5f 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 24b15f0b178..8b7aba5823b 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/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 74d6294b39d..d52648688f7 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-10 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/54878
+ * io/unix.c (tempfile_open): Set umask before calling mkstemp.
+
2012-10-06 Janne Blomqvist <jb@gcc.gnu.org>
* configure.ac: Check for presence of secure_getenv.
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 805d4bbd205..9d2e9d85087 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1051,6 +1051,9 @@ tempfile_open (const char *tempdir, char **fname)
{
int fd;
const char *slash = "/";
+#if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP)
+ mode_t mode_mask;
+#endif
if (!tempdir)
return -1;
@@ -1072,8 +1075,17 @@ tempfile_open (const char *tempdir, char **fname)
snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX",
tempdir, slash);
+#ifdef HAVE_UMASK
+ /* Temporarily set the umask such that the file has 0600 permissions. */
+ mode_mask = umask (S_IXUSR | S_IRWXG | S_IRWXO);
+#endif
+
fd = mkstemp (template);
+#ifdef HAVE_UMASK
+ (void) umask (mode_mask);
+#endif
+
#else /* HAVE_MKSTEMP */
fd = -1;
int count = 0;
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 69b13d7222c..1a586d10d71 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 7d6db50d14c..53ab75412a8 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 62c50003f3a..5fa75c6d573 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 d77d97d5516..1c92511644e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,232 @@
+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<>
+ and __gnu_cxx::hoyt_distribution<> classes.
+ * include/ext/random.tcc: Add out-of-line functions for
+ __gnu_cxx::arcsine_distribution<> and __gnu_cxx::hoyt_distribution<>.
+ * testsuite/ext/random/hoyt_distribution/cons/parms.cc: New file.
+ * testsuite/ext/random/hoyt_distribution/cons/default.cc: New file.
+ * testsuite/ext/random/hoyt_distribution/requirements/
+ explicit_instantiation/1.cc: New file.
+ * testsuite/ext/random/hoyt_distribution/requirements/typedefs.cc:
+ New file.
+ * testsuite/ext/random/hoyt_distribution/operators/inequal.cc: New file.
+ * testsuite/ext/random/hoyt_distribution/operators/equal.cc: New file.
+ * testsuite/ext/random/hoyt_distribution/operators/serialize.cc:
+ New file.
+ * testsuite/ext/random/arcsine_distribution/cons/parms.cc: New file.
+ * testsuite/ext/random/arcsine_distribution/cons/default.cc: New file.
+ * testsuite/ext/random/arcsine_distribution/requirements/
+ explicit_instantiation/1.cc: New file.
+ * testsuite/ext/random/arcsine_distribution/requirements/typedefs.cc:
+ New file.
+ * testsuite/ext/random/arcsine_distribution/operators/inequal.cc:
+ New file.
+ * testsuite/ext/random/arcsine_distribution/operators/equal.cc:
+ New file.
+ * testsuite/ext/random/arcsine_distribution/operators/serialize.cc:
+ New file.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/hashtable_policy.h: Revert libstdc++/53067 quick
+ hacks thanks to the resolution of c++/51213.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/23_containers/bitset/45713.cc: Tweak.
+
+2012-10-11 Hans-Peter Nilsson <hp@axis.com>
+
+ PR testsuite/54897
+ * testsuite/23_containers/bitset/45713.cc: Skip for avr*-*-*
+ cris*-*-* h8300*-*-* mcore*-*-* moxie*-*-*.
+
+2012-10-11 Daniel Krugler <daniel.kruegler@googlemail.com>
+
+ * testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc:
+ Update / extend.
+ * testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc:
+ Likewise.
+ * testsuite/20_util/duration/requirements/sfinae_friendly_1.cc:
+ Likewise.
+
+2012-10-11 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR libstdc++/54872
+ * config/abi/pre/gnu.ver (GLIBCXX_3.4.11) [!__sun__ && !__svr4__]:
+ Don't export _ZNSt12system_errorC*.
+
+2012-10-10 Jack Howarth <howarth@bromo.med.uc.edu>
+ Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR libstdc++/54847
+ * config/os/bsd/darwin/os_defines.h: Define _GLIBCXX_USE_NANOSLEEP
+ and _GLIBCXX_USE_SCHED_YIELD.
+ * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Add comment.
+
+2012-10-10 Mark Kettenis <kettenis@openbsd.org>
+
+ * configure.host (*-*-openbsd*) Set cpu_include_dir.
+ * config/os/bsd/openbsd/ctype_base.h: New file.
+ * config/os/bsd/openbsd/ctype_configure_char.cc: New file.
+ * config/os/bsd/openbsd/ctype_inline.h: New file.
+ * config/os/bsd/openbsd/os_defines.h: New file.
+ * acinclude.m4 (GLIBCXX_ENABLE_CLOCALE): Use newlib locale model
+ for OpenBSD.
+ * configure: Regenerated.
+
2012-10-10 Paolo Carlini <paolo.carlini@oracle.com>
* include/std/type_traits (__do_common_type_impl): Revert for now
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 921f4edfb83..ab7caafed95 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 \
@@ -244,7 +245,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -282,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 bf0edb8f285..10dac63dcf0 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -1158,6 +1158,11 @@ dnl --enable-libstdcxx-time=no
dnl --disable-libstdcxx-time
dnl disables the checks completely
dnl
+dnl N.B. Darwin provides nanosleep but doesn't support the whole POSIX
+dnl Timers option, so doesn't define _POSIX_TIMERS. Because the test
+dnl below fails Darwin unconditionally defines _GLIBCXX_USE_NANOSLEEP in
+dnl os_defines.h and also defines _GLIBCXX_USE_SCHED_YIELD.
+dnl
AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
AC_MSG_CHECKING([for clock_gettime, nanosleep and sched_yield])
@@ -1862,6 +1867,9 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
darwin* | freebsd*)
enable_clocale_flag=darwin
;;
+ openbsd*)
+ enable_clocale_flag=newlib
+ ;;
*)
if test x"$with_newlib" = x"yes"; then
enable_clocale_flag=newlib
@@ -3298,15 +3306,13 @@ 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 glibcxx_thread_h
+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])
-
- glibcxx_thread_h=gthr-$target_thread_file.h
- AC_SUBST(glibcxx_thread_h)
+ GCC_AC_THREAD_HEADER([$target_thread_file])
])
@@ -3613,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/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index e23fdfb63b0..949ab50e5e3 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1057,7 +1057,12 @@ GLIBCXX_3.4.11 {
_ZTISt12system_error;
_ZTVSt12system_error;
_ZNSt12system_errorD*Ev;
+ # Those template instantiations weren't exported on Solaris in GCC 4.6
+ # and aren't necessary for correct operation, so don't emit them now
+ # (PR libstdc++/54872).
+#if !defined(__sun__) && !defined(__svr4__)
_ZNSt12system_errorC*;
+#endif
_ZNKSt4hashISt10error_codeEclES0_;
diff --git a/libstdc++-v3/config/os/bsd/darwin/os_defines.h b/libstdc++-v3/config/os/bsd/darwin/os_defines.h
index 421478d82d4..be4aa149e21 100644
--- a/libstdc++-v3/config/os/bsd/darwin/os_defines.h
+++ b/libstdc++-v3/config/os/bsd/darwin/os_defines.h
@@ -42,4 +42,9 @@
// Static initializer macro is buggy in darwin, see libstdc++/51906
#define _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
+// Configure checks for nanosleep fail on Darwin, but nanosleep and
+// sched_yield are always available, so use them.
+#define _GLIBCXX_USE_NANOSLEEP 1
+#define _GLIBCXX_USE_SCHED_YIELD 1
+
#endif
diff --git a/libstdc++-v3/config/os/bsd/openbsd/ctype_base.h b/libstdc++-v3/config/os/bsd/openbsd/ctype_base.h
new file mode 100644
index 00000000000..895c4265ef5
--- /dev/null
+++ b/libstdc++-v3/config/os/bsd/openbsd/ctype_base.h
@@ -0,0 +1,59 @@
+// Locale support -*- C++ -*-
+
+// Copyright (C) 2000, 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
+// 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+// Information as gleaned from /usr/include/ctype.h on OpenBSD.
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /// @brief Base class for ctype.
+ struct ctype_base
+ {
+ // Non-standard typedefs.
+ typedef const short* __to_type;
+
+ // NB: Offsets into ctype<char>::_M_table force a particular size
+ // on the mask type. Because of this, we don't use an enum.
+ typedef char mask;
+
+ static const mask upper = _U;
+ static const mask lower = _L;
+ static const mask alpha = _U | _L;
+ static const mask digit = _N;
+ static const mask xdigit = _N | _X;
+ static const mask space = _S;
+ static const mask print = _P | _U | _L | _N | _B;
+ static const mask graph = _P | _U | _L | _N;
+ static const mask cntrl = _C;
+ static const mask punct = _P;
+ static const mask alnum = _U | _L | _N;
+ };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/os/bsd/openbsd/ctype_configure_char.cc b/libstdc++-v3/config/os/bsd/openbsd/ctype_configure_char.cc
new file mode 100644
index 00000000000..72e91239a2b
--- /dev/null
+++ b/libstdc++-v3/config/os/bsd/openbsd/ctype_configure_char.cc
@@ -0,0 +1,99 @@
+// Locale support -*- C++ -*-
+
+// Copyright (C) 2011 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file ctype_configure_char.cc */
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+#include <locale>
+#include <cstdlib>
+#include <cstring>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+// Information as gleaned from /usr/include/ctype.h
+
+ const ctype_base::mask*
+ ctype<char>::classic_table() throw()
+ { return _ctype_ + 1; }
+
+ ctype<char>::ctype(__c_locale, const mask* __table, bool __del,
+ size_t __refs)
+ : facet(__refs), _M_del(__table != 0 && __del),
+ _M_toupper(NULL), _M_tolower(NULL),
+ _M_table(__table ? __table : classic_table())
+ {
+ memset(_M_widen, 0, sizeof(_M_widen));
+ _M_widen_ok = 0;
+ memset(_M_narrow, 0, sizeof(_M_narrow));
+ _M_narrow_ok = 0;
+ }
+
+ ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
+ : facet(__refs), _M_del(__table != 0 && __del),
+ _M_toupper(NULL), _M_tolower(NULL),
+ _M_table(__table ? __table : classic_table())
+ {
+ memset(_M_widen, 0, sizeof(_M_widen));
+ _M_widen_ok = 0;
+ memset(_M_narrow, 0, sizeof(_M_narrow));
+ _M_narrow_ok = 0;
+ }
+
+ char
+ ctype<char>::do_toupper(char __c) const
+ { return ::toupper((int) __c); }
+
+ const char*
+ ctype<char>::do_toupper(char* __low, const char* __high) const
+ {
+ while (__low < __high)
+ {
+ *__low = ::toupper((int) *__low);
+ ++__low;
+ }
+ return __high;
+ }
+
+ char
+ ctype<char>::do_tolower(char __c) const
+ { return ::tolower((int) __c); }
+
+ const char*
+ ctype<char>::do_tolower(char* __low, const char* __high) const
+ {
+ while (__low < __high)
+ {
+ *__low = ::tolower((int) *__low);
+ ++__low;
+ }
+ return __high;
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/os/bsd/openbsd/ctype_inline.h b/libstdc++-v3/config/os/bsd/openbsd/ctype_inline.h
new file mode 100644
index 00000000000..e7b8d5c8305
--- /dev/null
+++ b/libstdc++-v3/config/os/bsd/openbsd/ctype_inline.h
@@ -0,0 +1,74 @@
+// Locale support -*- C++ -*-
+
+// Copyright (C) 2010 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/ctype_inline.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{locale}
+ */
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*)
+// functions go in ctype.cc
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ bool
+ ctype<char>::
+ is(mask __m, char __c) const
+ { return _M_table[static_cast<unsigned char>(__c)] & __m; }
+
+ const char*
+ ctype<char>::
+ is(const char* __low, const char* __high, mask* __vec) const
+ {
+ while (__low < __high)
+ *__vec++ = _M_table[static_cast<unsigned char>(*__low++)];
+ return __high;
+ }
+
+ const char*
+ ctype<char>::
+ scan_is(mask __m, const char* __low, const char* __high) const
+ {
+ while (__low < __high && !this->is(__m, *__low))
+ ++__low;
+ return __low;
+ }
+
+ const char*
+ ctype<char>::
+ scan_not(mask __m, const char* __low, const char* __high) const
+ {
+ while (__low < __high && this->is(__m, *__low) != 0)
+ ++__low;
+ return __low;
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/config/os/bsd/openbsd/os_defines.h b/libstdc++-v3/config/os/bsd/openbsd/os_defines.h
new file mode 100644
index 00000000000..b57d951e3c5
--- /dev/null
+++ b/libstdc++-v3/config/os/bsd/openbsd/os_defines.h
@@ -0,0 +1,41 @@
+// Specific definitions for OpenBSD -*- C++ -*-
+
+// Copyright (C) 2000, 2002, 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
+// 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/os_defines.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{iosfwd}
+ */
+
+#ifndef _GLIBCXX_OS_DEFINES
+#define _GLIBCXX_OS_DEFINES 1
+
+// System-specific #define, typedefs, corrections, etc, go here. This
+// file will come before all others.
+
+#define _GLIBCXX_USE_C99_DYNAMIC (!(__ISO_C_VISIBLE >= 1999))
+#define _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC _GLIBCXX_USE_C99_DYNAMIC
+#define _GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC _GLIBCXX_USE_C99_DYNAMIC
+#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC _GLIBCXX_USE_C99_DYNAMIC
+
+#endif
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index e828643df03..0c939ed90b8 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -708,7 +708,7 @@ BASIC_FILE_H
CSTDIO_H
SECTION_FLAGS
WERROR
-glibcxx_thread_h
+thread_header
glibcxx_PCHFLAGS
GLIBCXX_BUILD_PCH_FALSE
GLIBCXX_BUILD_PCH_TRUE
@@ -15161,7 +15161,19 @@ $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; }
- glibcxx_thread_h=gthr-$target_thread_file.h
+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
+
@@ -15371,7 +15383,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
# Fake what AC_TRY_COMPILE does.
cat > conftest.$ac_ext << EOF
-#line 15374 "configure"
+#line 15386 "configure"
int main()
{
typedef bool atomic_type;
@@ -15406,7 +15418,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15409 "configure"
+#line 15421 "configure"
int main()
{
typedef short atomic_type;
@@ -15441,7 +15453,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15444 "configure"
+#line 15456 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
@@ -15477,7 +15489,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15480 "configure"
+#line 15492 "configure"
int main()
{
typedef long long atomic_type;
@@ -15556,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 15559 "configure"
+#line 15571 "configure"
int main()
{
_Decimal32 d1;
@@ -15598,7 +15610,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15601 "configure"
+#line 15613 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -15632,7 +15644,7 @@ $as_echo "$enable_int128" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15635 "configure"
+#line 15647 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -15816,6 +15828,9 @@ fi
darwin* | freebsd*)
enable_clocale_flag=darwin
;;
+ openbsd*)
+ enable_clocale_flag=newlib
+ ;;
*)
if test x"$with_newlib" = x"yes"; then
enable_clocale_flag=newlib
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index bcc11befbfc..cdd0fb219bc 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -291,6 +291,9 @@ case "${host_os}" in
netbsd*)
os_include_dir="os/bsd/netbsd"
;;
+ openbsd*)
+ os_include_dir="os/bsd/openbsd"
+ ;;
qnx6.[12]*)
os_include_dir="os/qnx/qnx6.1"
c_model=c
@@ -345,7 +348,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 f7aa484c6e2..3c1a0d5d1ac 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
@@ -218,7 +219,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -264,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 1e149f0318d..ba37e0eccb6 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 aecc9a7bb02..c2487d3c4ae 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_srcdir}/libgcc/${glibcxx_thread_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 fa52fd7b2d4..666ed19ee8c 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
@@ -216,7 +217,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -254,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@
@@ -1546,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_srcdir}/libgcc/${glibcxx_thread_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 ce355048a86..a5c9f434b35 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 3c9f2380b27..5d18a6ebf44 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/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 6350ae622e4..c1331ce6588 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -921,8 +921,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Specialization using EBO.
template<int _Nm, typename _Tp>
struct _Hashtable_ebo_helper<_Nm, _Tp, true>
- // See PR53067.
- : public _Tp
+ : private _Tp
{
_Hashtable_ebo_helper() = default;
@@ -989,9 +988,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Key, typename _Value, typename _ExtractKey,
typename _H1, typename _H2, typename _Hash>
struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false>
- // See PR53067.
- : public _Hashtable_ebo_helper<0, _ExtractKey>,
- public _Hashtable_ebo_helper<1, _Hash>
+ : private _Hashtable_ebo_helper<0, _ExtractKey>,
+ private _Hashtable_ebo_helper<1, _Hash>
{
private:
typedef _Hashtable_ebo_helper<0, _ExtractKey> _EboExtractKey;
@@ -1066,10 +1064,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _H1, typename _H2>
struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
_Default_ranged_hash, false>
- // See PR53067.
- : public _Hashtable_ebo_helper<0, _ExtractKey>,
- public _Hashtable_ebo_helper<1, _H1>,
- public _Hashtable_ebo_helper<2, _H2>
+ : private _Hashtable_ebo_helper<0, _ExtractKey>,
+ private _Hashtable_ebo_helper<1, _H1>,
+ private _Hashtable_ebo_helper<2, _H2>
{
private:
typedef _Hashtable_ebo_helper<0, _ExtractKey> _EboExtractKey;
@@ -1150,10 +1147,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _H1, typename _H2>
struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
_Default_ranged_hash, true>
- // See PR53067.
- : public _Hashtable_ebo_helper<0, _ExtractKey>,
- public _Hashtable_ebo_helper<1, _H1>,
- public _Hashtable_ebo_helper<2, _H2>
+ : private _Hashtable_ebo_helper<0, _ExtractKey>,
+ private _Hashtable_ebo_helper<1, _H1>,
+ private _Hashtable_ebo_helper<2, _H2>
{
private:
typedef _Hashtable_ebo_helper<0, _ExtractKey> _EboExtractKey;
@@ -1272,8 +1268,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _H1, typename _H2, typename _Hash>
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash, true>
- // See PR53067.
- : public _H2
+ : private _H2
{
_Local_iterator_base() = default;
_Local_iterator_base(_Hash_node<_Value, true>* __p,
@@ -1305,9 +1300,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _H1, typename _H2, typename _Hash>
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash, false>
- // See PR53067.
- : public _Hash_code_base<_Key, _Value, _ExtractKey,
- _H1, _H2, _Hash, false>
+ : private _Hash_code_base<_Key, _Value, _ExtractKey,
+ _H1, _H2, _Hash, false>
{
_Local_iterator_base() = default;
_Local_iterator_base(_Hash_node<_Value, false>* __p,
@@ -1470,10 +1464,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash, typename _Traits>
struct _Hashtable_base
- // See PR53067.
- : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
- _Traits::__hash_cached::value>,
- public _Hashtable_ebo_helper<0, _Equal>
+ : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
+ _Traits::__hash_cached::value>,
+ private _Hashtable_ebo_helper<0, _Equal>
{
public:
typedef _Key key_type;
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 353c466d8fc..236f0de300a 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 8f36285ff17..1d29d8ce55a 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 1b7871957ee..3df0c9bd31d 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 96cb148ebb5..b03772d4cae 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 7996763829f..07d2893b839 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/ext/random b/libstdc++-v3/include/ext/random
index 0207d392261..adf8a241187 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -1856,6 +1856,473 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const k_distribution<_RealType>& __d2)
{ return !(__d1 == __d2); }
+
+ /**
+ * @brief An arcsine continuous distribution for random numbers.
+ *
+ * The formula for the arcsine probability density function is
+ * @f[
+ * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
+ * @f]
+ * where @f$x >= a@f$ and @f$x <= b@f$.
+ *
+ * <table border=1 cellpadding=10 cellspacing=0>
+ * <caption align=top>Distribution Statistics</caption>
+ * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
+ * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
+ * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
+ * </table>
+ */
+ template<typename _RealType = double>
+ class
+ arcsine_distribution
+ {
+ static_assert(std::is_floating_point<_RealType>::value,
+ "template argument not a floating point type");
+
+ public:
+ /** The type of the range of the distribution. */
+ typedef _RealType result_type;
+ /** Parameter type. */
+ struct param_type
+ {
+ typedef arcsine_distribution<result_type> distribution_type;
+
+ param_type(result_type __a = result_type(0),
+ result_type __b = result_type(1))
+ : _M_a(__a), _M_b(__b)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
+ }
+
+ result_type
+ a() const
+ { return _M_a; }
+
+ result_type
+ b() const
+ { return _M_b; }
+
+ friend bool
+ operator==(const param_type& __p1, const param_type& __p2)
+ { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
+
+ private:
+ void _M_initialize();
+
+ result_type _M_a;
+ result_type _M_b;
+ };
+
+ /**
+ * @brief Constructors.
+ */
+ explicit
+ arcsine_distribution(result_type __a = result_type(0),
+ result_type __b = result_type(1))
+ : _M_param(__a, __b),
+ _M_ud(-1.5707963267948966192313216916397514L,
+ +1.5707963267948966192313216916397514L)
+ { }
+
+ explicit
+ arcsine_distribution(const param_type& __p)
+ : _M_param(__p),
+ _M_ud(-1.5707963267948966192313216916397514L,
+ +1.5707963267948966192313216916397514L)
+ { }
+
+ /**
+ * @brief Resets the distribution state.
+ */
+ void
+ reset()
+ { _M_ud.reset(); }
+
+ /**
+ * @brief Return the parameters of the distribution.
+ */
+ result_type
+ a() const
+ { return _M_param.a(); }
+
+ result_type
+ b() const
+ { return _M_param.b(); }
+
+ /**
+ * @brief Returns the parameter set of the distribution.
+ */
+ param_type
+ param() const
+ { return _M_param; }
+
+ /**
+ * @brief Sets the parameter set of the distribution.
+ * @param __param The new parameter set of the distribution.
+ */
+ void
+ param(const param_type& __param)
+ { _M_param = __param; }
+
+ /**
+ * @brief Returns the greatest lower bound value of the distribution.
+ */
+ result_type
+ min() const
+ { return this->a(); }
+
+ /**
+ * @brief Returns the least upper bound value of the distribution.
+ */
+ result_type
+ max() const
+ { return this->b(); }
+
+ /**
+ * @brief Generating functions.
+ */
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ result_type __x = std::sin(this->_M_ud(__urng));
+ return (__x * (this->b() - this->a())
+ + this->a() + this->b()) / result_type(2);
+ }
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ {
+ result_type __x = std::sin(this->_M_ud(__urng));
+ return (__x * (__p.b() - __p.a())
+ + __p.a() + __p.b()) / result_type(2);
+ }
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng)
+ { this->__generate(__f, __t, __urng, this->param()); }
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ template<typename _UniformRandomNumberGenerator>
+ void
+ __generate(result_type* __f, result_type* __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ /**
+ * @brief Return true if two arcsine distributions have
+ * the same parameters and the sequences that would
+ * be generated are equal.
+ */
+ friend bool
+ operator==(const arcsine_distribution& __d1,
+ const arcsine_distribution& __d2)
+ { return (__d1.param() == __d2.param()
+ && __d1._M_ud == __d2._M_ud); }
+
+ /**
+ * @brief Inserts a %arcsine_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %arcsine_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>&,
+ const arcsine_distribution<_RealType1>&);
+
+ /**
+ * @brief Extracts a %arcsine_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %arcsine_distribution random number
+ * generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>&,
+ arcsine_distribution<_RealType1>&);
+
+ private:
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ param_type _M_param;
+
+ std::uniform_real_distribution<result_type> _M_ud;
+ };
+
+ /**
+ * @brief Return true if two arcsine distributions are not equal.
+ */
+ template<typename _RealType>
+ inline bool
+ operator!=(const arcsine_distribution<_RealType>& __d1,
+ const arcsine_distribution<_RealType>& __d2)
+ { return !(__d1 == __d2); }
+
+
+ /**
+ * @brief A Hoyt continuous distribution for random numbers.
+ *
+ * The formula for the Hoyt probability density function is
+ * @f[
+ * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
+ * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
+ * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
+ * @f]
+ * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
+ * of order 0 and @f$0 < q < 1@f$.
+ *
+ * <table border=1 cellpadding=10 cellspacing=0>
+ * <caption align=top>Distribution Statistics</caption>
+ * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
+ * E(1 - q^2) @f$</td></tr>
+ * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
+ * {\pi (1 + q^2)}\right) @f$</td></tr>
+ * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
+ * </table>
+ * where @f$E(x)@f$ is the elliptic function of the second kind.
+ */
+ template<typename _RealType = double>
+ class
+ hoyt_distribution
+ {
+ static_assert(std::is_floating_point<_RealType>::value,
+ "template argument not a floating point type");
+
+ public:
+ /** The type of the range of the distribution. */
+ typedef _RealType result_type;
+ /** Parameter type. */
+ struct param_type
+ {
+ typedef hoyt_distribution<result_type> distribution_type;
+
+ param_type(result_type __q = result_type(0.5L),
+ result_type __omega = result_type(1))
+ : _M_q(__q), _M_omega(__omega)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_q > result_type(0));
+ _GLIBCXX_DEBUG_ASSERT(_M_q < result_type(1));
+ }
+
+ result_type
+ q() const
+ { return _M_q; }
+
+ result_type
+ omega() const
+ { return _M_omega; }
+
+ friend bool
+ operator==(const param_type& __p1, const param_type& __p2)
+ { return __p1._M_q == __p2._M_q
+ && __p1._M_omega == __p2._M_omega; }
+
+ private:
+ void _M_initialize();
+
+ result_type _M_q;
+ result_type _M_omega;
+ };
+
+ /**
+ * @brief Constructors.
+ */
+ explicit
+ hoyt_distribution(result_type __q = result_type(0.5L),
+ result_type __omega = result_type(1))
+ : _M_param(__q, __omega),
+ _M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
+ result_type(0.5L) * (result_type(1) + __q * __q)
+ / (__q * __q)),
+ _M_ed(result_type(1))
+ { }
+
+ explicit
+ hoyt_distribution(const param_type& __p)
+ : _M_param(__p),
+ _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
+ result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
+ / (__p.q() * __p.q())),
+ _M_ed(result_type(1))
+ { }
+
+ /**
+ * @brief Resets the distribution state.
+ */
+ void
+ reset()
+ {
+ _M_ad.reset();
+ _M_ed.reset();
+ }
+
+ /**
+ * @brief Return the parameters of the distribution.
+ */
+ result_type
+ q() const
+ { return _M_param.q(); }
+
+ result_type
+ omega() const
+ { return _M_param.omega(); }
+
+ /**
+ * @brief Returns the parameter set of the distribution.
+ */
+ param_type
+ param() const
+ { return _M_param; }
+
+ /**
+ * @brief Sets the parameter set of the distribution.
+ * @param __param The new parameter set of the distribution.
+ */
+ void
+ param(const param_type& __param)
+ { _M_param = __param; }
+
+ /**
+ * @brief Returns the greatest lower bound value of the distribution.
+ */
+ result_type
+ min() const
+ { return result_type(0); }
+
+ /**
+ * @brief Returns the least upper bound value of the distribution.
+ */
+ result_type
+ max() const
+ { return std::numeric_limits<result_type>::max(); }
+
+ /**
+ * @brief Generating functions.
+ */
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng);
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng)
+ { this->__generate(__f, __t, __urng, this->param()); }
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ template<typename _UniformRandomNumberGenerator>
+ void
+ __generate(result_type* __f, result_type* __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ /**
+ * @brief Return true if two Hoyt distributions have
+ * the same parameters and the sequences that would
+ * be generated are equal.
+ */
+ friend bool
+ operator==(const hoyt_distribution& __d1,
+ const hoyt_distribution& __d2)
+ { return (__d1.param() == __d2.param()
+ && __d1._M_ad == __d2._M_ad
+ && __d1._M_ed == __d2._M_ed); }
+
+ /**
+ * @brief Inserts a %hoyt_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %hoyt_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>&,
+ const hoyt_distribution<_RealType1>&);
+
+ /**
+ * @brief Extracts a %hoyt_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %hoyt_distribution random number
+ * generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _RealType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>&,
+ hoyt_distribution<_RealType1>&);
+
+ private:
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ param_type _M_param;
+
+ __gnu_cxx::arcsine_distribution<result_type> _M_ad;
+ std::exponential_distribution<result_type> _M_ed;
+ };
+
+ /**
+ * @brief Return true if two Hoyt distributions are not equal.
+ */
+ template<typename _RealType>
+ inline bool
+ operator!=(const hoyt_distribution<_RealType>& __d1,
+ const hoyt_distribution<_RealType>& __d2)
+ { return !(__d1 == __d2); }
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index a196f74bdc4..ba6aaf2e111 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -1015,6 +1015,178 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __is;
}
+
+ template<typename _RealType>
+ template<typename _OutputIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ arcsine_distribution<_RealType>::
+ __generate_impl(_OutputIterator __f, _OutputIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ {
+ __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator>)
+
+ result_type __dif = __p.b() - __p.a();
+ result_type __sum = __p.a() + __p.b();
+ while (__f != __t)
+ {
+ result_type __x = std::sin(this->_M_ud(__urng));
+ *__f++ = (__x * __dif + __sum) / result_type(2);
+ }
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const arcsine_distribution<_RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(std::numeric_limits<_RealType>::max_digits10);
+
+ __os << __x.a() << __space << __x.b();
+ __os << __space << __x._M_ud;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ arcsine_distribution<_RealType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ _RealType __a, __b;
+ __is >> __a >> __b;
+ __is >> __x._M_ud;
+ __x.param(typename arcsine_distribution<_RealType>::
+ param_type(__a, __b));
+
+ __is.flags(__flags);
+ return __is;
+ }
+
+
+ template<typename _RealType>
+ template<typename _UniformRandomNumberGenerator>
+ typename hoyt_distribution<_RealType>::result_type
+ hoyt_distribution<_RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng)
+ {
+ result_type __x = this->_M_ad(__urng);
+ result_type __y = this->_M_ed(__urng);
+ return (result_type(2) * this->q()
+ / (result_type(1) + this->q() * this->q()))
+ * std::sqrt(this->omega() * __x * __y);
+ }
+
+ template<typename _RealType>
+ template<typename _UniformRandomNumberGenerator>
+ typename hoyt_distribution<_RealType>::result_type
+ hoyt_distribution<_RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ {
+ result_type __q2 = __p.q() * __p.q();
+ result_type __num = result_type(0.5L) * (result_type(1) + __q2);
+ typename __gnu_cxx::arcsine_distribution<result_type>::param_type
+ __pa(__num, __num / __q2);
+ result_type __x = this->_M_ad(__pa, __urng);
+ result_type __y = this->_M_ed(__urng);
+ return (result_type(2) * __p.q() / (result_type(1) + __q2))
+ * std::sqrt(__p.omega() * __x * __y);
+ }
+
+ template<typename _RealType>
+ template<typename _OutputIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ hoyt_distribution<_RealType>::
+ __generate_impl(_OutputIterator __f, _OutputIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ {
+ __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator>)
+
+ result_type __2q = result_type(2) * __p.q();
+ result_type __q2 = __p.q() * __p.q();
+ result_type __q2p1 = result_type(1) + __q2;
+ result_type __num = result_type(0.5L) * __q2p1;
+ result_type __omega = __p.omega();
+ typename __gnu_cxx::arcsine_distribution<result_type>::param_type
+ __pa(__num, __num / __q2);
+ while (__f != __t)
+ {
+ result_type __x = this->_M_ad(__pa, __urng);
+ result_type __y = this->_M_ed(__urng);
+ *__f++ = (__2q / __q2p1) * std::sqrt(__omega * __x * __y);
+ }
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const hoyt_distribution<_RealType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(std::numeric_limits<_RealType>::max_digits10);
+
+ __os << __x.q() << __space << __x.omega();
+ __os << __space << __x._M_ad;
+ __os << __space << __x._M_ed;
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ hoyt_distribution<_RealType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ _RealType __q, __omega;
+ __is >> __q >> __omega;
+ __is >> __x._M_ad;
+ __is >> __x._M_ed;
+ __x.param(typename hoyt_distribution<_RealType>::
+ param_type(__q, __omega));
+
+ __is.flags(__flags);
+ return __is;
+ }
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index c7c0a5ae824..15dd6c13222 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 209f395ed3d..d920a7dd379 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 fb9e09fffe8..b4985d280d8 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 8422d407048..8bf86f35af6 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 \
@@ -276,7 +277,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -314,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 5e47708d934..95bdcf09dec 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 ad583c3ea63..bb0f5908436 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
@@ -216,7 +217,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -254,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 fa0e99d45ee..49f71a1175e 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
@@ -240,7 +241,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -278,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 6cd16c3476d..f9ff31943e9 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
@@ -266,7 +267,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -304,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 dc46f29f148..793bbae40ea 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
@@ -233,7 +234,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -271,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 f0ab4bc4ec6..8a18026a44e 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 d897274345d..d154b983922 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
@@ -249,7 +250,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -287,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/common_type/requirements/sfinae_friendly_1.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
index c23521f9d4c..f73c6cc6dd5 100644
--- a/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
+++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc
@@ -163,20 +163,23 @@ namespace std {
};
}
-static_assert(is_type<std::common_type<int, int>, int>(), "");
-static_assert(is_type<std::common_type<ScEn, ScEn>, ScEn>(), "");
-static_assert(is_type<std::common_type<UnscEn, UnscEn>, UnscEn>(), "");
-static_assert(is_type<std::common_type<int, int>, int>(), "");
+#ifdef HAS_53000_FIXED
+static_assert(is_type<std::common_type<int, int>, int&&>(), "");
+static_assert(is_type<std::common_type<ScEn, ScEn>, ScEn&&>(), "");
+static_assert(is_type<std::common_type<UnscEn, UnscEn>, UnscEn&&>(), "");
+#endif
static_assert(is_type<std::common_type<UnscEn, int>, int>(), "");
-static_assert(is_type<std::common_type<int, int, int>, int>(), "");
-static_assert(is_type<std::common_type<int, int, int, int>, int>(), "");
-static_assert(is_type<std::common_type<int, int, int, int, int>, int>(), "");
-static_assert(is_type<std::common_type<S, S>, S>(), "");
-static_assert(is_type<std::common_type<const S, const S>, const S>(), "");
+#ifdef HAS_53000_FIXED
+static_assert(is_type<std::common_type<int, int, int>, int&&>(), "");
+static_assert(is_type<std::common_type<int, int, int, int>, int&&>(), "");
+static_assert(is_type<std::common_type<int, int, int, int, int>, int&&>(), "");
+static_assert(is_type<std::common_type<S, S>, S&&>(), "");
+static_assert(is_type<std::common_type<const S, const S>, const S&&>(), "");
static_assert(is_type<std::common_type<std::initializer_list<int>,
- std::initializer_list<int>>, std::initializer_list<int>>(), "");
-static_assert(is_type<std::common_type<B, D>, B>(), "");
-static_assert(is_type<std::common_type<D, B>, B>(), "");
+ std::initializer_list<int>>, std::initializer_list<int>&&>(), "");
+static_assert(is_type<std::common_type<B, D>, B&&>(), "");
+static_assert(is_type<std::common_type<D, B>, B&&>(), "");
+#endif
static_assert(is_type<std::common_type<F1, F2>, void*>(), "");
static_assert(is_type<std::common_type<F2, F1>, void*>(), "");
static_assert(is_type<std::common_type<G1, G2>, const volatile void*>(), "");
@@ -189,10 +192,15 @@ static_assert(is_type<std::common_type<void, void>, void>(), "");
static_assert(is_type<std::common_type<const void, const void>, void>(), "");
static_assert(is_type<std::common_type<int&, int&&>, int>(), "");
static_assert(is_type<std::common_type<int&, int&>, int&>(), "");
-static_assert(is_type<std::common_type<int&&, int&&>, int>(), "");
+#ifdef HAS_53000_FIXED
+static_assert(is_type<std::common_type<int&&, int&&>, int&&>(), "");
+static_assert(is_type<std::common_type<int&&, const int&&>, const int&&>(), "");
+#endif
static_assert(is_type<std::common_type<U&, const U&&>, const U>(), "");
static_assert(is_type<std::common_type<U&, U&>, U&>(), "");
-static_assert(is_type<std::common_type<U&&, U&&>, U>(), "");
+#ifdef HAS_53000_FIXED
+static_assert(is_type<std::common_type<U&&, U&&>, U&&>(), "");
+#endif
static_assert(is_type<std::common_type<int B::*, int D::*>, int D::*>(), "");
static_assert(is_type<std::common_type<int D::*, int B::*>, int D::*>(), "");
static_assert(is_type<std::common_type<const int B::*, volatile int D::*>,
@@ -201,7 +209,9 @@ static_assert(is_type<std::common_type<int (B::*)(), int (D::*)()>,
int (D::*)()>(), "");
static_assert(is_type<std::common_type<int (B::*)() const, int (D::*)() const>,
int (D::*)() const>(), "");
-static_assert(is_type<std::common_type<int[3], int[3]>, int*>(), "");
+#ifdef HAS_53000_FIXED
+static_assert(is_type<std::common_type<int[3], int[3]>, int(&&)[3]>(), "");
+#endif
static_assert(is_type<std::common_type<int[1], const int[3]>,
const int*>(), "");
static_assert(is_type<std::common_type<void(), void()>, void(&)()>(), "");
@@ -213,14 +223,18 @@ static_assert(is_type<std::common_type<void(&&)(), void(&)()>,
static_assert(is_type<std::common_type<void(&&)(), void(&&)()>,
void(&)()>(), "");
static_assert(is_type<std::common_type<ImplicitTo<int>, int>, int>(), "");
+#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<ImplicitTo<int>, ImplicitTo<int>>,
- ImplicitTo<int>>(), "");
+ ImplicitTo<int>&&>(), "");
+#endif
static_assert(is_type<std::common_type<ImplicitTo<int>, int,
ImplicitTo<int>>, int>(), "");
+#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<ExplicitTo<int>, ExplicitTo<int>>,
- ExplicitTo<int>>(), "");
+ ExplicitTo<int>&&>(), "");
static_assert(is_type<std::common_type<decltype(lmd1), decltype(lmd1)>,
- decltype(lmd1)>(), "");
+ decltype(lmd1)&&>(), "");
+#endif
static_assert(is_type<std::common_type<decltype(lmd1)&, decltype(lmd1)&>,
decltype(lmd1)&>(), "");
static_assert(is_type<std::common_type<decltype(lmd1)&, decltype(lmd2)&>,
@@ -248,12 +262,12 @@ static_assert(is_type<std::common_type<UConv1&, UConv2&>, Abstract*>(), "");
#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<Abstract&&, Abstract&&>,
- Abstract>(), "");
+ Abstract&&>(), "");
static_assert(is_type<std::common_type<const Abstract&&,
- volatile Abstract&&>, Abstract>(), "");
-static_assert(is_type<std::common_type<Ukn&&, Ukn&&>, Ukn>(), "");
+ volatile Abstract&&>, const volatile Abstract&&>(), "");
+static_assert(is_type<std::common_type<Ukn&&, Ukn&&>, Ukn&&>(), "");
static_assert(is_type<std::common_type<const Ukn&&, volatile Ukn&&>,
- Ukn>(), "");
+ const volatile Ukn&&>(), "");
#endif
static_assert(is_type<std::common_type<X1, X2>, RX12>(), "");
@@ -323,8 +337,10 @@ void test(int i)
auto local_lmd1 = [=](int, double) { return i + i; };
auto local_lmd2 = [=](int, double) { return i - i; };
+#ifdef HAS_53000_FIXED
static_assert(is_type<std::common_type<decltype(local_lmd1),
- decltype(local_lmd1)>, decltype(local_lmd1)>(), "");
+ decltype(local_lmd1)>, decltype(local_lmd1)&&>(), "");
+#endif
static_assert(is_type<std::common_type<decltype(local_lmd1)&,
decltype(local_lmd1)>, decltype(local_lmd1)>(), "");
static_assert(is_type<std::common_type<decltype(local_lmd1)&,
diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
index e4d4fa0d0c4..2f667919ea5 100644
--- a/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
+++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
@@ -24,10 +24,12 @@
template<typename... Args>
constexpr
-std::array<typename std::common_type<Args...>::type, sizeof...(Args)>
+std::array<typename std::decay<typename std::common_type<Args...>::type>::type,
+ sizeof...(Args)>
make_array(Args&&... args) // { dg-error "invalid use" }
{
- typedef typename std::common_type<Args...>::type CT;
+ typedef typename std::decay<typename std::common_type<Args...>::type>::type
+ CT;
return std::array<CT, sizeof...(Args)>{static_cast<CT>
(std::forward<Args>(args))...};
}
diff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/sfinae_friendly_1.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/sfinae_friendly_1.cc
index 48b0197d911..cf53a21752d 100644
--- a/libstdc++-v3/testsuite/20_util/duration/requirements/sfinae_friendly_1.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/sfinae_friendly_1.cc
@@ -21,6 +21,9 @@
#include <type_traits>
#include <chrono>
+//TODO: Uncomment this once gcc bug 53000 has been resolved:
+//#define HAS_53000_FIXED
+
// Helper types:
struct has_type_impl
{
@@ -52,8 +55,10 @@ typedef std::chrono::duration<int, std::nano> din;
typedef std::chrono::duration<double, std::nano> ddn;
typedef std::chrono::duration<int, std::milli> dim;
-static_assert(is_type<std::common_type<din, din>, din>(), "");
-static_assert(is_type<std::common_type<din, din, din>, din>(), "");
+#ifdef HAS_53000_FIXED
+static_assert(is_type<std::common_type<din, din>, din&&>(), "");
+static_assert(is_type<std::common_type<din, din, din>, din&&>(), "");
+#endif
static_assert(is_type<std::common_type<din, ddn>, ddn>(), "");
static_assert(is_type<std::common_type<din, din, ddn>, ddn>(), "");
diff --git a/libstdc++-v3/testsuite/20_util/forward/c_neg.cc b/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
index 01128245d7e..1e573ec2757 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 9e5b78a04db..d4a9c7a2af6 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 adf3af4abd8..39117dee59f 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 a1465d39fb2..11e13532d38 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 00000000000..4811b17cbd9
--- /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 eb22938261a..eb4c213eddb 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 00000000000..0efb4c3da91
--- /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 bf2a8573abf..6c260605c05 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 c2f301adcd4..ec46ac0d388 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 e74af1b4f43..7c7a365cb4e 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 b9ce910f61a..3c642c800b0 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/bitset/45713.cc b/libstdc++-v3/testsuite/23_containers/bitset/45713.cc
index 8d369d63e18..fe2068c3171 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/45713.cc
+++ b/libstdc++-v3/testsuite/23_containers/bitset/45713.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 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
@@ -15,11 +15,12 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-do compile }
+// The testcase requires bitsizetype to be wider than sizetype,
+// otherwise types/vars with 0x20000000 bytes or larger can't be used.
+// See http://gcc.gnu.org/PR54897
+// { dg-do compile { target { ! { avr*-*-* cris*-*-* h8300*-*-* mcore*-*-* moxie*-*-* } } } }
#include <bitset>
// libstdc++/45713
-#if __SIZEOF_SIZE_T__ >= 4
-int test[sizeof(std::bitset<0xffffffff>) != 1 ? 1 : -1];
-#endif
+int test[sizeof(std::bitset<__SIZE_MAX__>) != 1 ? 1 : -1];
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 00000000000..c388ef3d453
--- /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 00000000000..e78856ae8a8
--- /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 00000000000..51033f125b2
--- /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 00000000000..18539ffa386
--- /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 00000000000..77d2c21ccc0
--- /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 00000000000..60d83d4507b
--- /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 00000000000..63bdb53b0aa
--- /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 00000000000..5f8c177a2ae
--- /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 00000000000..17e2875fbd7
--- /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 00000000000..8147256a725
--- /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 00000000000..0eb4800dbe8
--- /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 00000000000..028efed06ce
--- /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 00000000000..fe25ad6b921
--- /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 00000000000..57664890672
--- /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 00000000000..bf70732e3e6
--- /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 00000000000..5f8c177a2ae
--- /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 00000000000..17e2875fbd7
--- /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 00000000000..8147256a725
--- /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 00000000000..0eb4800dbe8
--- /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 00000000000..028efed06ce
--- /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 00000000000..fe25ad6b921
--- /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 00000000000..b4b15decf77
--- /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 00000000000..1f2ee73487b
--- /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 00000000000..e768a548067
--- /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 00000000000..14928c62ef9
--- /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 00000000000..0e5a26c31bc
--- /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 00000000000..55d2bb20488
--- /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 00000000000..4fc054a276e
--- /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 00000000000..e05782859cb
--- /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 00000000000..797eeaafeed
--- /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 00000000000..2d3b2742831
--- /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 00000000000..7836ec25ce6
--- /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 00000000000..5a6f5bbcdb9
--- /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 00000000000..5e444ad725a
--- /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 00000000000..9fb847b5c16
--- /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 00000000000..704e6103721
--- /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 00000000000..ff645b5f106
--- /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 00000000000..b18e6e592ea
--- /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 9169956e9af..96b3f9f4b1a 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
@@ -216,7 +217,6 @@ glibcxx_localedir = @glibcxx_localedir@
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
glibcxx_prefixdir = @glibcxx_prefixdir@
glibcxx_srcdir = @glibcxx_srcdir@
-glibcxx_thread_h = @glibcxx_thread_h@
glibcxx_toolexecdir = @glibcxx_toolexecdir@
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
gxx_include_dir = @gxx_include_dir@
@@ -254,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/testsuite/ext/random/arcsine_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc
new file mode 100644
index 00000000000..c149bd08fc9
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc
@@ -0,0 +1,43 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::arcsine_distribution<> u;
+ VERIFY( u.a() == 0.0 );
+ VERIFY( u.b() == 1.0 );
+ VERIFY( u.min() == 0.0 );
+ VERIFY( u.max() == 1.0 );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/parms.cc
new file mode 100644
index 00000000000..50c5cb2c9b5
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/parms.cc
@@ -0,0 +1,43 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::arcsine_distribution<> u(-1.5, 3.0);
+ VERIFY( u.a() == -1.5 );
+ VERIFY( u.b() == 3.0 );
+ VERIFY( u.min() == -1.5 );
+ VERIFY( u.max() == 3.0 );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/equal.cc
new file mode 100644
index 00000000000..210ac1a91eb
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/equal.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::arcsine_distribution<double> u(-2.0, 3.0), v, w;
+
+ VERIFY( v == w );
+ VERIFY( !(u == v) );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/inequal.cc
new file mode 100644
index 00000000000..fba59052e5d
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/inequal.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::arcsine_distribution<double> u(-2.0, 3.0), v, w;
+
+ VERIFY( u != v );
+ VERIFY( !(v != w) );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/serialize.cc
new file mode 100644
index 00000000000..7cbed402f17
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/operators/serialize.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::stringstream str;
+ __gnu_cxx::arcsine_distribution<double> u(-1.5, 3.0), v;
+ std::minstd_rand0 rng;
+
+ u(rng); // advance
+ str << u;
+
+ str >> v;
+ VERIFY( u == v );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/explicit_instantiation/1.cc
new file mode 100644
index 00000000000..102b22f9df5
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/explicit_instantiation/1.cc
@@ -0,0 +1,26 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 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 <ext/random>
+
+template class __gnu_cxx::arcsine_distribution<float>;
+template class __gnu_cxx::arcsine_distribution<double>;
+template class __gnu_cxx::arcsine_distribution<long double>;
diff --git a/libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/typedefs.cc
new file mode 100644
index 00000000000..b4a79403922
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/arcsine_distribution/requirements/typedefs.cc
@@ -0,0 +1,33 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+
+void
+test01()
+{
+ typedef __gnu_cxx::arcsine_distribution<double> test_type;
+
+ typedef test_type::result_type result_type;
+ typedef test_type::param_type param_type;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/default.cc
new file mode 100644
index 00000000000..39940facc1f
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/default.cc
@@ -0,0 +1,44 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::hoyt_distribution<> u;
+ VERIFY( u.q() == 0.5 );
+ VERIFY( u.omega() == 1.0 );
+ VERIFY( u.min() == 0.0 );
+ typedef __gnu_cxx::hoyt_distribution<>::result_type result_type;
+ VERIFY( u.max() == std::numeric_limits<result_type>::max() );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/parms.cc
new file mode 100644
index 00000000000..22c8b66dfa9
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/cons/parms.cc
@@ -0,0 +1,44 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::hoyt_distribution<> u(0.05, 3.0);
+ VERIFY( u.q() == 0.05 );
+ VERIFY( u.omega() == 3.0 );
+ VERIFY( u.min() == 0.0 );
+ typedef __gnu_cxx::hoyt_distribution<>::result_type result_type;
+ VERIFY( u.max() == std::numeric_limits<result_type>::max() );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/equal.cc
new file mode 100644
index 00000000000..4496be67562
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/equal.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::hoyt_distribution<double> u(0.05, 3.0), v, w;
+
+ VERIFY( v == w );
+ VERIFY( !(u == v) );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/inequal.cc
new file mode 100644
index 00000000000..914e8d933ae
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/inequal.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ __gnu_cxx::hoyt_distribution<double> u(0.05, 3.0), v, w;
+
+ VERIFY( u != v );
+ VERIFY( !(v != w) );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/serialize.cc
new file mode 100644
index 00000000000..cdf2e63dc48
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/operators/serialize.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::stringstream str;
+ __gnu_cxx::hoyt_distribution<double> u(0.05, 3.0), v;
+ std::minstd_rand0 rng;
+
+ u(rng); // advance
+ str << u;
+
+ str >> v;
+ VERIFY( u == v );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/explicit_instantiation/1.cc
new file mode 100644
index 00000000000..abdc59943eb
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/explicit_instantiation/1.cc
@@ -0,0 +1,26 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 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 <ext/random>
+
+template class __gnu_cxx::hoyt_distribution<float>;
+template class __gnu_cxx::hoyt_distribution<double>;
+template class __gnu_cxx::hoyt_distribution<long double>;
diff --git a/libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/typedefs.cc
new file mode 100644
index 00000000000..846b1f31552
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hoyt_distribution/requirements/typedefs.cc
@@ -0,0 +1,33 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+// { dg-require-cstdint "" }
+//
+// 2012-10-12 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// 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 <ext/random>
+
+void
+test01()
+{
+ typedef __gnu_cxx::hoyt_distribution<double> test_type;
+
+ typedef test_type::result_type result_type;
+ typedef test_type::param_type param_type;
+}