summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/ChangeLog4
-rw-r--r--config/picflag.m43
-rw-r--r--gcc/ChangeLog1508
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in5
-rw-r--r--gcc/acinclude.m49
-rw-r--r--gcc/ada/ChangeLog34
-rw-r--r--gcc/ada/gcc-interface/Makefile.in4
-rw-r--r--gcc/ada/gcc-interface/trans.c2
-rw-r--r--gcc/ada/gcc-interface/utils2.c1
-rw-r--r--gcc/ada/s-linux-alpha.ads6
-rw-r--r--gcc/ada/s-linux-hppa.ads6
-rw-r--r--gcc/ada/s-linux-mipsel.ads6
-rw-r--r--gcc/ada/s-linux-sparc.ads6
-rw-r--r--gcc/ada/s-linux-x32.ads110
-rw-r--r--gcc/ada/s-linux.ads6
-rw-r--r--gcc/ada/s-osinte-linux.ads5
-rw-r--r--gcc/ada/s-osinte-posix.adb2
-rw-r--r--gcc/ada/s-osprim-x32.adb173
-rw-r--r--gcc/ada/s-taprop-linux.adb2
-rw-r--r--gcc/asan.c5
-rw-r--r--gcc/basic-block.h15
-rw-r--r--gcc/c-family/ChangeLog52
-rw-r--r--gcc/c-family/c-cilkplus.c93
-rw-r--r--gcc/c-family/c-common.c122
-rw-r--r--gcc/c-family/c-common.h9
-rw-r--r--gcc/c-family/c-gimplify.c1
-rw-r--r--gcc/c-family/c-omp.c50
-rw-r--r--gcc/c-family/c-pragma.c4
-rw-r--r--gcc/c-family/c-pragma.h14
-rw-r--r--gcc/c-family/c-pretty-print.c8
-rw-r--r--gcc/c-family/c-ubsan.c1
-rw-r--r--gcc/c-family/cilk.c1
-rw-r--r--gcc/c/ChangeLog54
-rw-r--r--gcc/c/c-decl.c113
-rw-r--r--gcc/c/c-parser.c414
-rw-r--r--gcc/c/c-tree.h7
-rw-r--r--gcc/c/c-typeck.c14
-rw-r--r--gcc/calls.c7
-rw-r--r--gcc/cfgexpand.c49
-rw-r--r--gcc/cfgloop.c1
-rw-r--r--gcc/cfgloopmanip.c2
-rw-r--r--gcc/cfgrtl.c14
-rw-r--r--gcc/cgraph.c76
-rw-r--r--gcc/cgraph.h3
-rw-r--r--gcc/cgraphbuild.c18
-rw-r--r--gcc/cgraphclones.c1
-rw-r--r--gcc/cgraphunit.c3
-rw-r--r--gcc/cilk-common.c1
-rw-r--r--gcc/config.gcc12
-rw-r--r--gcc/config/aarch64/aarch64-arches.def2
-rw-r--r--gcc/config/aarch64/aarch64-builtins.c1
-rw-r--r--gcc/config/aarch64/aarch64-cores.def4
-rw-r--r--gcc/config/aarch64/aarch64-generic.md40
-rw-r--r--gcc/config/aarch64/aarch64-protos.h21
-rw-r--r--gcc/config/aarch64/aarch64-simd.md1007
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/aarch64/aarch64.c70
-rw-r--r--gcc/config/aarch64/aarch64.h8
-rw-r--r--gcc/config/aarch64/aarch64.md54
-rw-r--r--gcc/config/aarch64/large.md312
-rw-r--r--gcc/config/aarch64/small.md287
-rw-r--r--gcc/config/alpha/alpha.c1
-rw-r--r--gcc/config/arc/arc.h16
-rw-r--r--gcc/config/arc/arc.md3
-rw-r--r--gcc/config/arm/aarch-cost-tables.h126
-rw-r--r--gcc/config/arm/arm-cores.def4
-rw-r--r--gcc/config/arm/arm.c159
-rw-r--r--gcc/config/arm/cortex-a15.md2
-rw-r--r--gcc/config/c6x/c6x.c1
-rw-r--r--gcc/config/darwin.c1
-rw-r--r--gcc/config/i386/i386.c26
-rw-r--r--gcc/config/i386/i386.h4
-rw-r--r--gcc/config/i386/i386.md13
-rw-r--r--gcc/config/i386/predicates.md10
-rw-r--r--gcc/config/i386/sse.md1440
-rw-r--r--gcc/config/i386/subst.md56
-rw-r--r--gcc/config/i386/x86-tune.def28
-rw-r--r--gcc/config/ia64/ia64.c12
-rw-r--r--gcc/config/mep/mep.c1
-rw-r--r--gcc/config/mips/mips.c1
-rw-r--r--gcc/config/nds32/nds32.c2
-rw-r--r--gcc/config/rs6000/altivec.md76
-rw-r--r--gcc/config/rs6000/linux64.h21
-rw-r--r--gcc/config/rs6000/option-defaults.h1
-rw-r--r--gcc/config/rs6000/ppc-asm.h25
-rw-r--r--gcc/config/rs6000/predicates.md23
-rw-r--r--gcc/config/rs6000/rs6000-c.c11
-rw-r--r--gcc/config/rs6000/rs6000-opts.h3
-rw-r--r--gcc/config/rs6000/rs6000-protos.h4
-rw-r--r--gcc/config/rs6000/rs6000.c1475
-rw-r--r--gcc/config/rs6000/rs6000.h42
-rw-r--r--gcc/config/rs6000/rs6000.md452
-rw-r--r--gcc/config/rs6000/rs6000.opt8
-rw-r--r--gcc/config/rs6000/sysv4.h12
-rw-r--r--gcc/config/rs6000/sysv4le.h4
-rw-r--r--gcc/config/rs6000/vector.md4
-rw-r--r--gcc/config/rx/rx.c4
-rw-r--r--gcc/config/s390/s390.c1
-rw-r--r--gcc/config/sh/sh.c40
-rw-r--r--gcc/config/sparc/sparc.c1
-rw-r--r--gcc/config/spu/spu.c1
-rw-r--r--gcc/config/stormy16/stormy16.c1
-rw-r--r--gcc/config/tilegx/tilegx.c1
-rw-r--r--gcc/config/tilepro/tilepro.c1
-rw-r--r--gcc/config/xtensa/xtensa.c1
-rwxr-xr-xgcc/configure136
-rw-r--r--gcc/configure.ac109
-rw-r--r--gcc/cp/ChangeLog117
-rw-r--r--gcc/cp/Make-lang.in1
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-cilkplus.c77
-rw-r--r--gcc/cp/cp-gimplify.c1
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/cvt.c6
-rw-r--r--gcc/cp/decl.c30
-rw-r--r--gcc/cp/decl2.c1
-rw-r--r--gcc/cp/except.c1
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/parser.c912
-rw-r--r--gcc/cp/parser.h20
-rw-r--r--gcc/cp/pt.c125
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/cp/tree.c3
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/cp/typeck2.c2
-rw-r--r--gcc/cp/vtable-class-hierarchy.c1
-rw-r--r--gcc/doc/extend.texi31
-rw-r--r--gcc/doc/generic.texi36
-rw-r--r--gcc/doc/install.texi14
-rw-r--r--gcc/doc/invoke.texi31
-rw-r--r--gcc/dwarf2out.c17
-rw-r--r--gcc/expmed.c7
-rw-r--r--gcc/expr.h4
-rw-r--r--gcc/final.c2
-rw-r--r--gcc/fold-const.c17
-rw-r--r--gcc/fortran/ChangeLog14
-rw-r--r--gcc/fortran/f95-lang.c1
-rw-r--r--gcc/fortran/trans-array.c2
-rw-r--r--gcc/fortran/trans-decl.c2
-rw-r--r--gcc/fortran/trans-expr.c2
-rw-r--r--gcc/fortran/trans-openmp.c3
-rw-r--r--gcc/fortran/trans.c2
-rw-r--r--gcc/function.c39
-rw-r--r--gcc/gcov-io.h15
-rw-r--r--gcc/gengtype.c6
-rw-r--r--gcc/gimple-expr.c154
-rw-r--r--gcc/gimple-expr.h8
-rw-r--r--gcc/gimple-fold.c4
-rw-r--r--gcc/gimple-iterator.c1
-rw-r--r--gcc/gimple-iterator.h298
-rw-r--r--gcc/gimple-low.c1
-rw-r--r--gcc/gimple-pretty-print.c20
-rw-r--r--gcc/gimple-ssa-isolate-paths.c218
-rw-r--r--gcc/gimple-ssa-strength-reduction.c2
-rw-r--r--gcc/gimple-streamer-in.c81
-rw-r--r--gcc/gimple-streamer-out.c9
-rw-r--r--gcc/gimple-walk.c871
-rw-r--r--gcc/gimple-walk.h99
-rw-r--r--gcc/gimple.c1143
-rw-r--r--gcc/gimple.h565
-rw-r--r--gcc/gimplify-me.c317
-rw-r--r--gcc/gimplify-me.h37
-rw-r--r--gcc/gimplify.c845
-rw-r--r--gcc/gimplify.h132
-rw-r--r--gcc/ginclude/stdatomic.h42
-rw-r--r--gcc/go/ChangeLog8
-rw-r--r--gcc/go/go-lang.c1
-rw-r--r--gcc/go/gofrontend/expressions.cc276
-rw-r--r--gcc/go/gofrontend/expressions.h25
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc1
-rw-r--r--gcc/go/gofrontend/types.cc4
-rw-r--r--gcc/graphite-blocking.c1
-rw-r--r--gcc/graphite-clast-to-gimple.c2
-rw-r--r--gcc/graphite-dependences.c1
-rw-r--r--gcc/graphite-interchange.c1
-rw-r--r--gcc/graphite-optimize-isl.c1
-rw-r--r--gcc/graphite-poly.c1
-rw-r--r--gcc/graphite-scop-detection.c1
-rw-r--r--gcc/graphite-sese-to-poly.c3
-rw-r--r--gcc/graphite.c1
-rw-r--r--gcc/haifa-sched.c10
-rw-r--r--gcc/ifcvt.c2
-rw-r--r--gcc/ipa-inline-analysis.c1
-rw-r--r--gcc/ipa-inline.c2
-rw-r--r--gcc/ipa-profile.c1
-rw-r--r--gcc/ipa-prop.c6
-rw-r--r--gcc/ipa-pure-const.c3
-rw-r--r--gcc/ipa-split.c4
-rw-r--r--gcc/ipa.c3
-rw-r--r--gcc/ira-color.c359
-rw-r--r--gcc/ira-costs.c3
-rw-r--r--gcc/ira.c225
-rw-r--r--gcc/java/ChangeLog10
-rw-r--r--gcc/java/java-gimplify.c1
-rw-r--r--gcc/langhooks.c1
-rw-r--r--gcc/loop-init.c1
-rw-r--r--gcc/lto-cgraph.c5
-rw-r--r--gcc/lto-streamer-in.c5
-rw-r--r--gcc/lto-streamer-out.c1
-rw-r--r--gcc/lto/lto-symtab.c7
-rw-r--r--gcc/mode-switching.c7
-rw-r--r--gcc/objc/ChangeLog8
-rw-r--r--gcc/objc/objc-act.c1
-rw-r--r--gcc/omp-low.c120
-rw-r--r--gcc/passes.c9
-rw-r--r--gcc/predict.c121
-rw-r--r--gcc/predict.h1
-rw-r--r--gcc/profile.c32
-rw-r--r--gcc/reload1.c3
-rw-r--r--gcc/reorg.c7
-rw-r--r--gcc/sese.c3
-rw-r--r--gcc/stor-layout.c1
-rw-r--r--gcc/targhooks.c1
-rw-r--r--gcc/testsuite/ChangeLog299
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/body.c33
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/clauses1.c80
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/clauses2.c18
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c39
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c132
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c8
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/for3.c14
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-1.c38
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-2.c36
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c43
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/run-1.c28
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/safelen.c14
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/vectorlength.c21
-rw-r--r--gcc/testsuite/c-c++-common/cpp/ucnid-2011-1.c15
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp19
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/for.C26
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/for2.C43
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/for3.C18
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/for4.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C47
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template3.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template4.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template5.C38
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template6.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template7.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template8.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C42
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C51
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58533.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58534.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58536.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58548.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58549.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr58637.C7
-rw-r--r--gcc/testsuite/g++.dg/dg.exp1
-rw-r--r--gcc/testsuite/g++.dg/eh/ppc64-sighandle-cr.C54
-rw-r--r--gcc/testsuite/g++.dg/plugin/selfassign.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr59102.c28
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr59119.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr59101.c15
-rw-r--r--gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c68
-rw-r--r--gcc/testsuite/gcc.dg/auto-type-1.c37
-rw-r--r--gcc/testsuite/gcc.dg/auto-type-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/c11-complex-1.c42
-rw-r--r--gcc/testsuite/gcc.dg/c11-thread-local-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/c11-thread-local-2.c46
-rw-r--r--gcc/testsuite/gcc.dg/c90-thread-local-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/c99-thread-local-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp31
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/for1.c12
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/for2.c11
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/jump.c27
-rw-r--r--gcc/testsuite/gcc.dg/cpp/ucnid-9.c8
-rw-r--r--gcc/testsuite/gcc.dg/guality/param-4.c20
-rw-r--r--gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c36
-rw-r--r--gcc/testsuite/gcc.dg/plugin/selfassign.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr10474.c16
-rw-r--r--gcc/testsuite/gcc.dg/stack-usage-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-1f.c4
-rw-r--r--gcc/testsuite/gcc.dg/tail-merge-store.c22
-rw-r--r--gcc/testsuite/gcc.dg/tls/diag-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/20131115-1.c38
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-div-underflow.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-extend-nan.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c50
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-27.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-28.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c62
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp47.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp87.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-alias-check.c12
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-15.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr58853.c9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/no-r11-1.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/no-r11-2.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/no-r11-3.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/ppc64-abi-dfp-1.c30
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr57949-1.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr57949-2.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr59054.c18
-rw-r--r--gcc/testsuite/gnat.dg/aggr21.adb14
-rw-r--r--gcc/testsuite/gnat.dg/aggr21_pkg.adb8
-rw-r--r--gcc/testsuite/gnat.dg/aggr21_pkg.ads11
-rw-r--r--gcc/testsuite/gnat.dg/stack_usage1b.adb39
-rw-r--r--gcc/testsuite/gnat.dg/stack_usage1c.adb39
-rw-r--r--gcc/testsuite/lib/g++.exp5
-rw-r--r--gcc/testsuite/lib/gcc.exp5
-rw-r--r--gcc/testsuite/lib/target-supports.exp19
-rw-r--r--gcc/testsuite/objc.dg/tls/diag-2.m2
-rw-r--r--gcc/toplev.c6
-rw-r--r--gcc/tracer.c1
-rw-r--r--gcc/trans-mem.c20
-rw-r--r--gcc/tree-affine.c1
-rw-r--r--gcc/tree-call-cdce.c1
-rw-r--r--gcc/tree-cfg.c3
-rw-r--r--gcc/tree-cfgcleanup.c2
-rw-r--r--gcc/tree-complex.c3
-rw-r--r--gcc/tree-core.h3
-rw-r--r--gcc/tree-data-ref.c1
-rw-r--r--gcc/tree-dfa.c2
-rw-r--r--gcc/tree-eh.c1
-rw-r--r--gcc/tree-emutls.c2
-rw-r--r--gcc/tree-if-conv.c3
-rw-r--r--gcc/tree-inline.c60
-rw-r--r--gcc/tree-into-ssa.c1
-rw-r--r--gcc/tree-iterator.c1
-rw-r--r--gcc/tree-loop-distribution.c5
-rw-r--r--gcc/tree-nested.c3
-rw-r--r--gcc/tree-nrv.c2
-rw-r--r--gcc/tree-object-size.c1
-rw-r--r--gcc/tree-outof-ssa.c1
-rw-r--r--gcc/tree-parloops.c4
-rw-r--r--gcc/tree-phinodes.c14
-rw-r--r--gcc/tree-phinodes.h16
-rw-r--r--gcc/tree-predcom.c3
-rw-r--r--gcc/tree-pretty-print.c4
-rw-r--r--gcc/tree-profile.c42
-rw-r--r--gcc/tree-scalar-evolution.c3
-rw-r--r--gcc/tree-sra.c4
-rw-r--r--gcc/tree-ssa-address.c2
-rw-r--r--gcc/tree-ssa-alias.c58
-rw-r--r--gcc/tree-ssa-alias.h10
-rw-r--r--gcc/tree-ssa-ccp.c2
-rw-r--r--gcc/tree-ssa-coalesce.c17
-rw-r--r--gcc/tree-ssa-copy.c1
-rw-r--r--gcc/tree-ssa-copyrename.c1
-rw-r--r--gcc/tree-ssa-dce.c2
-rw-r--r--gcc/tree-ssa-dom.c1
-rw-r--r--gcc/tree-ssa-dse.c1
-rw-r--r--gcc/tree-ssa-forwprop.c3
-rw-r--r--gcc/tree-ssa-ifcombine.c2
-rw-r--r--gcc/tree-ssa-live.c1
-rw-r--r--gcc/tree-ssa-loop-ch.c1
-rw-r--r--gcc/tree-ssa-loop-im.c3
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c1
-rw-r--r--gcc/tree-ssa-loop-ivopts.c44
-rw-r--r--gcc/tree-ssa-loop-manip.c3
-rw-r--r--gcc/tree-ssa-loop-niter.c2
-rw-r--r--gcc/tree-ssa-loop-prefetch.c3
-rw-r--r--gcc/tree-ssa-loop-unswitch.c1
-rw-r--r--gcc/tree-ssa-loop.c1
-rw-r--r--gcc/tree-ssa-math-opts.c2
-rw-r--r--gcc/tree-ssa-phiopt.c3
-rw-r--r--gcc/tree-ssa-phiprop.c2
-rw-r--r--gcc/tree-ssa-pre.c3
-rw-r--r--gcc/tree-ssa-propagate.c2
-rw-r--r--gcc/tree-ssa-reassoc.c2
-rw-r--r--gcc/tree-ssa-sccvn.c1
-rw-r--r--gcc/tree-ssa-sink.c1
-rw-r--r--gcc/tree-ssa-strlen.c3
-rw-r--r--gcc/tree-ssa-structalias.c102
-rw-r--r--gcc/tree-ssa-tail-merge.c71
-rw-r--r--gcc/tree-ssa-ter.c1
-rw-r--r--gcc/tree-ssa-threadedge.c67
-rw-r--r--gcc/tree-ssa-threadupdate.c85
-rw-r--r--gcc/tree-ssa-uncprop.c1
-rw-r--r--gcc/tree-ssa-uninit.c1
-rw-r--r--gcc/tree-ssa.c3
-rw-r--r--gcc/tree-stdarg.c2
-rw-r--r--gcc/tree-switch-conversion.c3
-rw-r--r--gcc/tree-tailcall.c2
-rw-r--r--gcc/tree-vect-data-refs.c125
-rw-r--r--gcc/tree-vect-generic.c8
-rw-r--r--gcc/tree-vect-loop-manip.c13
-rw-r--r--gcc/tree-vect-loop.c3
-rw-r--r--gcc/tree-vect-patterns.c11
-rw-r--r--gcc/tree-vect-slp.c1
-rw-r--r--gcc/tree-vect-stmts.c3
-rw-r--r--gcc/tree-vectorizer.c2
-rw-r--r--gcc/tree-vectorizer.h31
-rw-r--r--gcc/tree-vrp.c2
-rw-r--r--gcc/tree.c24
-rw-r--r--gcc/tree.def19
-rw-r--r--gcc/tree.h12
-rw-r--r--gcc/tsan.c2
-rw-r--r--gcc/value-prof.c25
-rw-r--r--gcc/value-prof.h4
-rw-r--r--gcc/vtable-verify.c1
-rw-r--r--libada/ChangeLog4
-rwxr-xr-xlibada/configure3
-rw-r--r--libatomic/ChangeLog4
-rw-r--r--libatomic/config/x86/fenv.c116
-rw-r--r--libcilkrts/ChangeLog8
-rw-r--r--libcilkrts/Makefile.am2
-rw-r--r--libcilkrts/Makefile.in6
-rw-r--r--libcilkrts/configure13
-rw-r--r--libcilkrts/configure.ac3
-rw-r--r--libcpp/ChangeLog49
-rw-r--r--libcpp/charset.c88
-rw-r--r--libcpp/include/cpplib.h4
-rw-r--r--libcpp/init.c32
-rw-r--r--libcpp/internal.h11
-rw-r--r--libcpp/lex.c17
-rw-r--r--libcpp/makeucnid.c168
-rw-r--r--libcpp/ucnid.h5217
-rw-r--r--libcpp/ucnid.tab36
-rw-r--r--libgcc/ChangeLog49
-rw-r--r--libgcc/Makefile.in35
-rw-r--r--libgcc/config.host2
-rw-r--r--libgcc/config/arm/t-vxworks1
-rw-r--r--libgcc/config/i386/cygming-crtbegin.c14
-rw-r--r--libgcc/config/rs6000/linux-unwind.h51
-rw-r--r--libgcc/config/rs6000/tramp.S66
-rw-r--r--libgcc/configure3
-rw-r--r--libgcc/libgcov-driver-system.c203
-rw-r--r--libgcc/libgcov-driver.c872
-rw-r--r--libgcc/libgcov-interface.c279
-rw-r--r--libgcc/libgcov-merge.c181
-rw-r--r--libgcc/libgcov-profiler.c223
-rw-r--r--libgcc/libgcov.c1374
-rw-r--r--libgfortran/ChangeLog27
-rw-r--r--libgfortran/Makefile.in43
-rw-r--r--libgfortran/aclocal.m474
-rw-r--r--libgfortran/config.h.in3
-rwxr-xr-xlibgfortran/configure35
-rw-r--r--libgfortran/configure.ac10
-rw-r--r--libgfortran/io/unix.c63
-rw-r--r--libgo/Makefile.am46
-rw-r--r--libgo/Makefile.in63
-rw-r--r--libgo/go/go/build/syslist.go8
-rw-r--r--libgo/go/net/fd_unix.go2
-rw-r--r--libgo/go/os/os_test.go1
-rwxr-xr-xlibgo/mksysinfo.sh5
-rw-r--r--libgo/runtime/go-caller.c7
-rw-r--r--libgo/runtime/malloc.goc4
-rw-r--r--libgo/runtime/malloc.h1
-rw-r--r--libgo/runtime/mgc0.c1
-rw-r--r--libgo/runtime/netpoll_epoll.c7
-rw-r--r--libgo/runtime/netpoll_kqueue.c10
-rw-r--r--libgo/runtime/netpoll_select.c223
-rw-r--r--libgo/runtime/netpoll_stub.c7
-rw-r--r--libgo/runtime/proc.c5
-rw-r--r--libiberty/ChangeLog19
-rwxr-xr-xlibiberty/configure3
-rw-r--r--libiberty/cp-demangle.c10
-rw-r--r--libitm/ChangeLog10
-rw-r--r--libitm/config/powerpc/sjlj.S24
-rw-r--r--libsanitizer/ChangeLog20
-rw-r--r--libsanitizer/asan/asan_interceptors.cc16
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc2
-rw-r--r--libstdc++-v3/ChangeLog153
-rw-r--r--libstdc++-v3/doc/xml/manual/build_hacking.xml8
-rw-r--r--libstdc++-v3/doc/xml/manual/configure.xml2
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2011.xml20
-rw-r--r--libstdc++-v3/include/bits/alloc_traits.h18
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h2
-rw-r--r--libstdc++-v3/include/bits/forward_list.h2
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h2
-rw-r--r--libstdc++-v3/include/bits/random.h8
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h10
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h13
-rw-r--r--libstdc++-v3/include/bits/stl_map.h59
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h59
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h60
-rw-r--r--libstdc++-v3/include/bits/stl_set.h60
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h202
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h38
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h1
-rw-r--r--libstdc++-v3/include/bits/unordered_map.h4
-rw-r--r--libstdc++-v3/include/bits/unordered_set.h4
-rw-r--r--libstdc++-v3/include/ext/cast.h2
-rw-r--r--libstdc++-v3/include/ext/pod_char_traits.h34
-rw-r--r--libstdc++-v3/include/std/mutex24
-rw-r--r--libstdc++-v3/libsupc++/cxxabi.h2
-rwxr-xr-xlibstdc++-v3/scripts/extract_symvers.in1
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc41
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc41
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc41
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc41
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc15
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc76
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc67
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc52
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/move.cc63
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc67
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc83
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc86
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc76
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc67
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc52
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc63
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc67
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc83
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc86
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc74
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc65
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc50
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc61
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc65
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc81
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc84
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc74
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc65
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc50
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/move.cc63
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc65
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc81
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc84
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc25
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc14
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc71
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc14
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc71
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc13
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc69
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc13
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc69
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc15
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/bool/emplace.cc51
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy/58982.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc42
-rw-r--r--libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc2
-rw-r--r--libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/testcase.h2
-rw-r--r--libstdc++-v3/testsuite/util/exception/safety.h2
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h10
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_containers.h4
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_hooks.cc2
569 files changed, 24906 insertions, 9075 deletions
diff --git a/config/ChangeLog b/config/ChangeLog
index e3f6f456695..83273a0816c 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ * picflag.m4 (m68k-*-*): Use default PIC flag.
+
2013-09-29 Iain Sandoe <iain@codesourcery.com>
* mh-darwin (BOOT_CFLAGS): Only add -mdynamic-no-pic for m32 hosts.
diff --git a/config/picflag.m4 b/config/picflag.m4
index 2ee5cd0785f..3bcdbf1de30 100644
--- a/config/picflag.m4
+++ b/config/picflag.m4
@@ -50,9 +50,6 @@ case "${$2}" in
i[[34567]]86-*-* | x86_64-*-*)
$1=-fpic
;;
- m68k-*-*)
- $1=-fpic
- ;;
# FIXME: Override -fPIC default in libgcc only?
sh-*-linux* | sh[[2346lbe]]*-*-linux*)
$1=-fpic
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f91e443e88b..64405b694b1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1469 @@
+2013-11-15 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (barrier_align): Return 0 when barrier_or_label
+ is null.
+
+2013-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in (C_COMMON_OBJS): Depend on c-cilkplus.o.
+ * gimple-pretty-print.c (dump_omp_for): Add case for
+ GF_OMP_FOR_KIND_CILKSIMD.
+ * gimple.h (enum gf_mask): Restructure entries to add
+ GF_OMP_FOR_KIND_CILKSIMD.
+ * gimplify.c (is_gimple_stmt): Add case for CILK_SIMD.
+ (gimplify_omp_for): Handle CILK_SIMD.
+ (gimplify_expr): Add ccase for CILK_SIMD.
+ * omp-low.c (extract_omp_for_data): Handle CILK_SIMD.
+ (build_outer_var_ref): Same.
+ (check_omp_nesting_restrictions): Same.
+ (lower_rec_input_clauses): Same.
+ (lower_lastprivate_clauses): Same.
+ (expand_omp_for): Same.
+ (execute_expand_omp): Check flag_enable_cilkplus.
+ (execute_lower_omp): Same.
+ (diagnose_sb_0): Handle CILK_SIMD.
+ (diagnose_omp_structured_block_errors): Check
+ flag_enable_cilkplus.
+ (setjmp_or_longjmp_p): New.
+ (scan_omp_1_stmt): Error on setjmp/longjmp in a simd construct.
+ * tree-pretty-print.c (dump_generic_node): Add case for CILK_SIMD.
+ * tree.def: Add tree code for CILK_SIMD.
+
+2013-11-15 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * config/rs6000/altivec.md (UNSPEC_VPERM_X, UNSPEC_VPERM_UNS_X):
+ Remove.
+ (altivec_vperm_<mode>): Revert earlier little endian change.
+ (*altivec_vperm_<mode>_internal): Remove.
+ (altivec_vperm_<mode>_uns): Revert earlier little endian change.
+ (*altivec_vperm_<mode>_uns_internal): Remove.
+ * config/rs6000/vector.md (vec_realign_load_<mode>): Revise
+ commentary.
+
+2013-11-15 Jeff Law <law@redhat.com>
+
+ * basic-block.h (has_abnormal_or_eh_outgoing_edge): Renamed from
+ has_abnormal_or_outgoing_edge. Check for EH edges as well.
+ * gimple-ssa-isolate-paths.c
+ (find_implicit_erroneous_behaviour): Corresponding changes.
+ Do not check stmt_ends_bb_p or GIMPLE_RETURN anymore.
+ (find_explicit_erroneous_behaviour): Likewise.
+
+2013-11-15 Jeff Law <law@redhat.com>
+
+ * ifcvt.c (find_cond_trap): Properly handle case where
+ trap_bb == else_bb.
+
+2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ * configure: Regenerate.
+
+2013-11-15 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-simd.md: Remove simd_type from all
+ patterns.
+ * config/aarch64/aarch64.md: Likewise, correct "type" attribute
+ where it is incorrect or missing.
+
+2013-11-15 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * dwarf2out.c (gen_enumeration_type_die): Remove unnecessary
+ host_integerp test.
+ * tree-vect-patterns.c (vect_recog_divmod_pattern): Likewise.
+ Use TREE_INT_CST_LOW rather than tree_low_cst when reading the
+ constant.
+ * fold-const.c (fold_binary_loc): Replace a host_integerp/tree_low_cst
+ pair with a TREE_CODE test and TREE_INT_CST_LOW.
+ * tree-vect-generic.c (expand_vector_divmod): Likewise.
+
+2013-11-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/50262
+ * tree-ssa-alias.h (struct pt_solution): Split
+ vars_contains_global into vars_contains_nonlocal,
+ vars_contains_escaped and vars_contains_escaped_heap.
+ * tree-ssa-structalias.c (label_visit): Expand comment.
+ (handle_lhs_call): Adjust comment.
+ (set_uids_in_ptset): Set the new flags appropriately.
+ (pt_solution_set): Adjust.
+ (pt_solution_set_var): Likewise.
+ (pt_solution_ior_into): Likewise.
+ (pt_solution_includes_global): Likewise.
+ (pt_solutions_intersect_1): Optimize escaped handling.
+ (compute_points_to_sets): Remove heap variable globalization.
+ (ipa_escaped_pt): Adjust initializer.
+ (pass_data_ipa_pta): Do not run TODO_update_ssa.
+ * gimple-pretty-print.c (pp_points_to_solution): Print split
+ flags.
+ * tree-ssa-alias.c (dump_points_to_solution): Likewise.
+
+2013-11-15 Richard Biener <rguenther@suse.de>
+
+ * tree-loop-distribution.c (tree_loop_distribution): Make sure
+ to distribute all stores.
+
+2013-11-15 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * doc/invoke.texi (-mabi=elfv1, -mabi=elfv2): Document.
+
+2013-11-15 Joseph Myers <joseph@codesourcery.com>
+
+ * acinclude.m4 (GCC_GLIBC_VERSION_GTE_IFELSE): New configure
+ macro.
+ * configure.ac: Determine target_header_dir earlier.
+ (--with-glibc-version): New configure option.
+ Use GCC_GLIBC_VERSION_GTE_IFELSE in enable_gnu_unique_object,
+ gcc_cv_libc_provides_ssp and gcc_cv_target_ldbl128 tests.
+ * configure: Regenerate.
+ * doc/install.texi (--enable-gnu-unique-object): Don't refer to
+ native toolchains for default.
+ (--with-glibc-version): Document.
+
+2013-11-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * fold-const.c (fold_binary_loc) <comparisons>: Reuse local variable.
+
+2013-11-15 Uros Bizjak <ubizjak@gmail.com>
+
+ * lto-streamer-in.c (input function): Call cgraph_create_node if
+ cgraph_get_node failed.
+
+2013-11-14 Olivier Hainque <hainque@adacore.com>
+
+ * cfgexpand.c (defer_stack_allocation): When optimization is enabled,
+ defer allocation of DECL_IGNORED_P variables at toplevel unless really
+ small. Factorize size threshold computation from the existing one.
+ (expand_used_vars): Refine comment.
+
+2013-11-14 Cong Hou <congh@google.com>
+
+ * tree-vectorizer.h (struct dr_with_seg_len): Remove the base
+ address field as it can be obtained from dr. Rename the struct.
+ * tree-vect-data-refs.c (comp_dr_with_seg_len_pair): Consider
+ steps of data references during sort.
+ (vect_prune_runtime_alias_test_list): Adjust with the change to
+ struct dr_with_seg_len.
+ * tree-vect-loop-manip.c (vect_create_cond_for_alias_checks):
+ Adjust with the change to struct dr_with_seg_len.
+
+2013-11-14 Jeff Law <law@redhat.com>
+
+ PR middle-end/59127
+ * basic-block.h (has_abnormal_outgoing_edge_p): Moved here from...
+ * tree-inline.c (has_abnormal_outgoing_edge_p): Remove.
+ * gimple-ssa-isolate-paths.c: Include tree-cfg.h.
+ (find_implicit_erroneous_behaviour): If a block has abnormal outgoing
+ edges, then ignore it. If the statement exhibiting erroneous
+ behaviour ends basic blocks, with the exception of GIMPLE_RETURNs,
+ then we can not optimize.
+ (find_explicit_erroneous_behaviour): Likewise.
+
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimplify-me.h: New file. Add prototypes.
+ * gimplify.h: Don't include gimple.h.
+ (struct gimplify_hasher, struct gimplify_ctx, is_gimple_sizepos):
+ Relocate from gimple.h.
+ * gimple.h (struct gimplify_hasher, struct gimplify_ctx,
+ is_gimple_sizepos): Move to gimplify.h.
+ (gimplify_hasher::hash, gimplify_hasher::equal): Move to gimplify.c.
+ (enum gsi_iterator_update): Move to gimple-iterator.h.
+ * gimple-iterator.h (enum gsi_iterator_update): Relocate from gimple.h.
+ * gimplify-me.c: New File.
+ (force_gimple_operand_1, force_gimple_operand,
+ force_gimple_operand_gsi_1, force_gimple_operand_gsi,
+ gimple_regimplify_operands): Relocate from gimplify.c.
+ * gimplify.c (force_gimple_operand_1, force_gimple_operand,
+ force_gimple_operand_gsi_1, force_gimple_operand_gsi,
+ gimple_regimplify_operands): Move to gimplify-me.c.
+ (gimplify_hasher::hash, gimplify_hasher::equal): Relocate
+ from gimple.h.
+ * Makefile.in (OBJS): Add gimplify-me.o
+ * asan.c: Include only gimplify.h, gimplify-me.h, and/or gimple.h as
+ required.
+ * cfgloopmanip.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cilk-common.c: Likewise.
+ * fold-const.c: Likewise.
+ * function.c: Likewise.
+ * gimple-expr.c: Likewise.
+ * gimple-fold.c: Likewise.
+ * gimple-ssa-strength-reduction.c: Likewise.
+ * gimple.c: Likewise.
+ * graphite-clast-to-gimple.c: Likewise.
+ * graphite-sese-to-poly.c: Likewise.
+ * ipa-prop.c: Likewise.
+ * ipa-split.c: Likewise.
+ * ipa.c: Likewise.
+ * langhooks.c: Likewise.
+ * omp-low.c: Likewise.
+ * sese.c: Likewise.
+ * stor-layout.c: Likewise.
+ * targhooks.c: Likewise.
+ * trans-mem.c: Likewise.
+ * tree-affine.c: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-cfgcleanup.c: Likewise.
+ * tree-complex.c: Likewise.
+ * tree-if-conv.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-loop-distribution.c: Likewise.
+ * tree-nested.c: Likewise.
+ * tree-parloops.c: Likewise.
+ * tree-predcom.c: Likewise.
+ * tree-profile.c: Likewise.
+ * tree-scalar-evolution.c: Likewise.
+ * tree-sra.c: Likewise.
+ * tree-ssa-address.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-forwprop.c: Likewise.
+ * tree-ssa-ifcombine.c: Likewise.
+ * tree-ssa-loop-im.c: Likewise.
+ * tree-ssa-loop-ivopts.c: Likewise.
+ * tree-ssa-loop-manip.c: Likewise.
+ * tree-ssa-loop-niter.c: Likewise.
+ * tree-ssa-loop-prefetch.c: Likewise.
+ * tree-ssa-loop-unswitch.c: Likewise.
+ * tree-ssa-math-opts.c: Likewise.
+ * tree-ssa-phiopt.c: Likewise.
+ * tree-ssa-phiprop.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa-propagate.c: Likewise.
+ * tree-ssa-reassoc.c: Likewise.
+ * tree-ssa-sccvn.c: Likewise.
+ * tree-ssa-strlen.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-switch-conversion.c: Likewise.
+ * tree-tailcall.c: Likewise.
+ * tree-vect-data-refs.c: Likewise.
+ * tree-vect-generic.c: Likewise.
+ * tree-vect-loop-manip.c: Likewise.
+ * tree-vect-loop.c: Likewise.
+ * tree-vect-patterns.c: Likewise.
+ * tree-vect-stmts.c: Likewise.
+ * tree.c: Likewise.
+ * tsan.c: Likewise.
+ * value-prof.c: Likewise.
+ * config/aarch64/aarch64.c: Likewise.
+ * config/alpha/alpha.c: Likewise.
+ * config/darwin.c: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/mep/mep.c: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/spu/spu.c: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/tilegx/tilegx.c: Likewise.
+ * config/tilepro/tilepro.c: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+
+2013-11-14 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/arc/arc.md (doloop_begin_i): Remove extra alignment;
+ use (.&-4) idiom.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/sysv4le.h (LINUX64_DEFAULT_ABI_ELFv2): Define.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.h (RS6000_SAVE_AREA): Handle ABI_ELFv2.
+ (RS6000_SAVE_TOC): Remove.
+ (RS6000_TOC_SAVE_SLOT): New macro.
+ * config/rs6000/rs6000.c (rs6000_parm_offset): New function.
+ (rs6000_parm_start): Use it.
+ (rs6000_function_arg_advance_1): Likewise.
+ (rs6000_emit_prologue): Use RS6000_TOC_SAVE_SLOT.
+ (rs6000_emit_epilogue): Likewise.
+ (rs6000_call_aix): Likewise.
+ (rs6000_output_function_prologue): Do not save/restore r11
+ around calling _mcount for ABI_ELFv2.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000-protos.h (rs6000_reg_parm_stack_space):
+ Add prototype.
+ * config/rs6000/rs6000.h (RS6000_REG_SAVE): Remove.
+ (REG_PARM_STACK_SPACE): Call rs6000_reg_parm_stack_space.
+ * config/rs6000/rs6000.c (rs6000_parm_needs_stack): New function.
+ (rs6000_function_parms_need_stack): Likewise.
+ (rs6000_reg_parm_stack_space): Likewise.
+ (rs6000_function_arg): Do not replace BLKmode by Pmode when
+ returning a register argument.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Michael Gschwind <mkg@us.ibm.com>
+
+ * config/rs6000/rs6000.h (FP_ARG_MAX_RETURN): New macro.
+ (ALTIVEC_ARG_MAX_RETURN): Likewise.
+ (FUNCTION_VALUE_REGNO_P): Use them.
+ * config/rs6000/rs6000.c (TARGET_RETURN_IN_MSB): Define.
+ (rs6000_return_in_msb): New function.
+ (rs6000_return_in_memory): Handle ELFv2 homogeneous aggregates.
+ Handle aggregates of up to 16 bytes for ELFv2.
+ (rs6000_function_value): Handle ELFv2 homogeneous aggregates.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Michael Gschwind <mkg@us.ibm.com>
+
+ * config/rs6000/rs6000.h (AGGR_ARG_NUM_REG): Define.
+ * config/rs6000/rs6000.c (rs6000_aggregate_candidate): New function.
+ (rs6000_discover_homogeneous_aggregate): Likewise.
+ (rs6000_function_arg_boundary): Handle homogeneous aggregates.
+ (rs6000_function_arg_advance_1): Likewise.
+ (rs6000_function_arg): Likewise.
+ (rs6000_arg_partial_bytes): Likewise.
+ (rs6000_psave_function_arg): Handle BLKmode arguments.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Michael Gschwind <mkg@us.ibm.com>
+
+ * config/rs6000/rs6000.h (AGGR_ARG_NUM_REG): Define.
+ * config/rs6000/rs6000.c (rs6000_aggregate_candidate): New function.
+ (rs6000_discover_homogeneous_aggregate): Likewise.
+ (rs6000_function_arg_boundary): Handle homogeneous aggregates.
+ (rs6000_function_arg_advance_1): Likewise.
+ (rs6000_function_arg): Likewise.
+ (rs6000_arg_partial_bytes): Likewise.
+ (rs6000_psave_function_arg): Handle BLKmode arguments.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (machine_function): New member
+ r2_setup_needed.
+ (rs6000_emit_prologue): Set r2_setup_needed if necessary.
+ (rs6000_output_mi_thunk): Set r2_setup_needed.
+ (rs6000_output_function_prologue): Output global entry point
+ prologue and local entry point marker if needed for ABI_ELFv2.
+ Output -mprofile-kernel code here.
+ (output_function_profiler): Do not output -mprofile-kernel
+ code here; moved to rs6000_output_function_prologue.
+ (rs6000_file_start): Output ".abiversion 2" for ABI_ELFv2.
+
+ (rs6000_emit_move): Do not handle dot symbols for ABI_ELFv2.
+ (rs6000_output_function_entry): Likewise.
+ (rs6000_assemble_integer): Likewise.
+ (rs6000_elf_encode_section_info): Likewise.
+ (rs6000_elf_declare_function_name): Do not create dot symbols
+ or .opd section for ABI_ELFv2.
+
+ (rs6000_trampoline_size): Update for ABI_ELFv2 trampolines.
+ (rs6000_trampoline_init): Likewise.
+ (rs6000_elf_file_end): Call file_end_indicate_exec_stack for ABI_ELFv2.
+
+ (rs6000_call_aix): Handle ELFv2 indirect calls. Do not check
+ for function descriptors in ABI_ELFv2.
+
+ * config/rs6000/rs6000.md ("*call_indirect_aix<mode>"): Support
+ on ABI_AIX only, not ABI_ELFv2.
+ ("*call_value_indirect_aix<mode>"): Likewise.
+ ("*call_indirect_elfv2<mode>"): New pattern.
+ ("*call_value_indirect_elfv2<mode>"): Likewise.
+
+ * config/rs6000/predicates.md ("symbol_ref_operand"): Do not
+ check for function descriptors in ABI_ELFv2.
+ ("current_file_function_operand"): Likewise.
+
+ * config/rs6000/ppc-asm.h [__powerpc64__ && _CALL_ELF == 2]:
+ (toc): Undefine.
+ (FUNC_NAME): Define ELFv2 variant.
+ (JUMP_TARGET): Likewise.
+ (FUNC_START): Likewise.
+ (HIDDEN_FUNC): Likewise.
+ (FUNC_END): Likeiwse.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config.gcc [powerpc*-*-* | rs6000-*-*]: Support --with-abi=elfv1
+ and --with-abi=elfv2.
+ * config/rs6000/option-defaults.h (OPTION_DEFAULT_SPECS): Add "abi".
+ * config/rs6000/rs6000.opt (mabi=elfv1): New option.
+ (mabi=elfv2): Likewise.
+ * config/rs6000/rs6000-opts.h (enum rs6000_abi): Add ABI_ELFv2.
+ * config/rs6000/linux64.h (DEFAULT_ABI): Do not hard-code to AIX_ABI
+ if !RS6000_BI_ARCH.
+ (ELFv2_ABI_CHECK): New macro.
+ (SUBSUBTARGET_OVERRIDE_OPTIONS): Use it to decide whether to set
+ rs6000_current_abi to ABI_AIX or ABI_ELFv2.
+ (GLIBC_DYNAMIC_LINKER64): Support ELFv2 ld.so version.
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Predefine
+ _CALL_ELF and __STRUCT_PARM_ALIGN__ if appropriate.
+
+ * config/rs6000/rs6000.c (rs6000_debug_reg_global): Handle ABI_ELFv2.
+ (debug_stack_info): Likewise.
+ (rs6000_file_start): Treat ABI_ELFv2 the same as ABI_AIX.
+ (rs6000_legitimize_tls_address): Likewise.
+ (rs6000_conditional_register_usage): Likewise.
+ (rs6000_emit_move): Likewise.
+ (init_cumulative_args): Likewise.
+ (rs6000_function_arg_advance_1): Likewise.
+ (rs6000_function_arg): Likewise.
+ (rs6000_arg_partial_bytes): Likewise.
+ (rs6000_output_function_entry): Likewise.
+ (rs6000_assemble_integer): Likewise.
+ (rs6000_savres_strategy): Likewise.
+ (rs6000_stack_info): Likewise.
+ (rs6000_function_ok_for_sibcall): Likewise.
+ (rs6000_emit_load_toc_table): Likewise.
+ (rs6000_savres_routine_name): Likewise.
+ (ptr_regno_for_savres): Likewise.
+ (rs6000_emit_prologue): Likewise.
+ (rs6000_emit_epilogue): Likewise.
+ (rs6000_output_function_epilogue): Likewise.
+ (output_profile_hook): Likewise.
+ (output_function_profiler): Likewise.
+ (rs6000_trampoline_size): Likewise.
+ (rs6000_trampoline_init): Likewise.
+ (rs6000_elf_output_toc_section_asm_op): Likewise.
+ (rs6000_elf_encode_section_info): Likewise.
+ (rs6000_elf_reloc_rw_mask): Likewise.
+ (rs6000_elf_declare_function_name): Likewise.
+ (rs6000_function_arg_boundary): Treat ABI_ELFv2 the same as ABI_AIX,
+ except that rs6000_compat_align_parm is always assumed false.
+ (rs6000_gimplify_va_arg): Likewise.
+ (rs6000_call_aix): Update comment.
+ (rs6000_sibcall_aix): Likewise.
+ * config/rs6000/rs6000.md ("tls_gd_aix<TLSmode:tls_abi_suffix>"):
+ Treat ABI_ELFv2 the same as ABI_AIX.
+ ("*tls_gd_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
+ ("tls_ld_aix<TLSmode:tls_abi_suffix>"): Likewise.
+ ("*tls_ld_call_aix<TLSmode:tls_abi_suffix>"): Likewise.
+ ("load_toc_aix_si"): Likewise.
+ ("load_toc_aix_di"): Likewise.
+ ("call"): Likewise.
+ ("call_value"): Likewise.
+ ("*call_local_aix<mode>"): Likewise.
+ ("*call_value_local_aix<mode>"): Likewise.
+ ("*call_nonlocal_aix<mode>"): Likewise.
+ ("*call_value_nonlocal_aix<mode>"): Likewise.
+ ("*call_indirect_aix<mode>"): Likewise.
+ ("*call_value_indirect_aix<mode>"): Likewise.
+ ("sibcall"): Likewise.
+ ("sibcall_value"): Likewise.
+ ("*sibcall_aix<mode>"): Likewise.
+ ("*sibcall_value_aix<mode>"): Likewise.
+ * config/rs6000/predicates.md ("symbol_ref_operand"): Likewise.
+ ("current_file_function_operand"): Likewise.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_arg_partial_bytes): Simplify logic
+ by making use of the fact that for vector / floating point arguments
+ passed both in VRs/FPRs and in the fixed parameter area, the partial
+ bytes mechanism is in fact not used.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_psave_function_arg): New function.
+ (rs6000_finish_function_arg): Likewise.
+ (rs6000_function_arg): Use rs6000_psave_function_arg and
+ rs6000_finish_function_arg to handle both vector and floating
+ point arguments that are also passed in GPRs / the stack.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Remove TYPE argument.
+ (USE_ALTIVEC_FOR_ARG_P): Likewise.
+ (rs6000_darwin64_record_arg_advance_recurse): Update uses.
+ (rs6000_function_arg_advance_1):Likewise.
+ (rs6000_darwin64_record_arg_recurse): Likewise.
+ (rs6000_function_arg): Likewise.
+ (rs6000_arg_partial_bytes): Likewise.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): Replace
+ "DEFAULT_ABI != ABI_AIX" test by testing for ABI_V4 or ABI_DARWIN.
+ (rs6000_savres_strategy): Likewise.
+ (rs6000_return_addr): Likewise.
+ (rs6000_emit_load_toc_table): Replace "DEFAULT_ABI != ABI_AIX" by
+ testing for ABI_V4 (since ABI_DARWIN is impossible here).
+ (rs6000_emit_prologue): Likewise.
+ (legitimate_lo_sum_address_p): Simplify DEFAULT_ABI test.
+ (rs6000_elf_declare_function_name): Remove duplicated test.
+ * config/rs6000/rs6000.md ("load_toc_v4_PIC_1"): Explicitly test
+ for ABI_V4 (instead of "DEFAULT_ABI != ABI_AIX" test).
+ ("load_toc_v4_PIC_1_normal"): Likewise.
+ ("load_toc_v4_PIC_1_476"): Likewise.
+ ("load_toc_v4_PIC_1b"): Likewise.
+ ("load_toc_v4_PIC_1b_normal"): Likewise.
+ ("load_toc_v4_PIC_1b_476"): Likewise.
+ ("load_toc_v4_PIC_2"): Likewise.
+ ("load_toc_v4_PIC_3b"): Likewise.
+ ("load_toc_v4_PIC_3c"): Likewise.
+ * config/rs6000/rs6000.h (RS6000_REG_SAVE): Simplify DEFAULT_ABI test.
+ (RS6000_SAVE_AREA): Likewise.
+ (FP_ARG_MAX_REG): Likewise.
+ (RETURN_ADDRESS_OFFSET): Likewise.
+ * config/rs6000/sysv.h (TARGET_TOC): Test for ABI_V4 instead
+ of ABI_AIX.
+ (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ (MINIMAL_TOC_SECTION_ASM_OP): Likewise.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_call_indirect_aix): Rename to ...
+ (rs6000_call_aix): ... this. Handle both direct and indirect calls.
+ Create call insn directly instead of via various gen_... routines.
+ Mention special registers used by the call in CALL_INSN_FUNCTION_USAGE.
+ (rs6000_sibcall_aix): New function.
+ * config/rs6000/rs6000.md (TOC_SAVE_OFFSET_32BIT): Remove.
+ (TOC_SAVE_OFFSET_64BIT): Likewise.
+ (AIX_FUNC_DESC_TOC_32BIT): Likewise.
+ (AIX_FUNC_DESC_TOC_64BIT): Likewise.
+ (AIX_FUNC_DESC_SC_32BIT): Likewise.
+ (AIX_FUNC_DESC_SC_64BIT): Likewise.
+ ("call" expander): Call rs6000_call_aix.
+ ("call_value" expander): Likewise.
+ ("call_indirect_aix<ptrsize>"): Replace this pattern ...
+ ("call_indirect_aix<ptrsize>_nor11"): ... and this pattern ...
+ ("*call_indirect_aix<mode>"): ... by this insn pattern.
+ ("call_value_indirect_aix<ptrsize>"): Replace this pattern ...
+ ("call_value_indirect_aix<ptrsize>_nor11"): ... and this pattern ...
+ ("*call_value_indirect_aix<mode>"): ... by this insn pattern.
+ ("*call_nonlocal_aix32", "*call_nonlocal_aix64"): Replace by ...
+ ("*call_nonlocal_aix<mode>"): ... this pattern.
+ ("*call_value_nonlocal_aix32", "*call_value_nonlocal_aix64"): Replace
+ ("*call_value_nonlocal_aix<mode>"): ... by this pattern.
+ ("*call_local_aix<mode>"): New insn pattern.
+ ("*call_value_local_aix<mode>"): Likewise.
+ ("sibcall" expander): Call rs6000_sibcall_aix.
+ ("sibcall_value" expander): Likewise. Move earlier in file.
+ ("*sibcall_nonlocal_aix<mode>"): Replace by ...
+ ("*sibcall_aix<mode>"): ... this pattern.
+ ("*sibcall_value_nonlocal_aix<mode>"): Replace by ...
+ ("*sibcall_value_aix<mode>"): ... this pattern.
+ * config/rs6000/rs6000-protos.h (rs6000_call_indirect_aix): Remove.
+ (rs6000_call_aix): Add prototype.
+ (rs6000_sibcall_aix): Likewise.
+
+2013-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/59122
+ * asan.c (asan_emit_stack_protection): Ensure -fsection-anchors
+ isn't confused by the artificial decl.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Do not place a
+ RTX_FRAME_RELATED_P marker on the UNSPEC_MOVESI_FROM_CR insn.
+ Instead, add USEs of all modified call-saved CR fields to the
+ insn storing the result to the stack slot, and provide an
+ appropriate REG_FRAME_RELATED_EXPR for that insn.
+ * config/rs6000/rs6000.md ("*crsave"): New insn pattern.
+ * config/rs6000/predicates.md ("crsave_operation"): New predicate.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * function.c (assign_parms): Use all.reg_parm_stack_space instead
+ of re-evaluating REG_PARM_STACK_SPACE target macro.
+ (locate_and_pad_parm): New parameter REG_PARM_STACK_SPACE. Use it
+ instead of evaluating target macro REG_PARM_STACK_SPACE every time.
+ (assign_parm_find_entry_rtl): Update call.
+ * calls.c (initialize_argument_information): Update call.
+ (emit_library_call_value_1): Likewise.
+ * expr.h (locate_and_pad_parm): Update prototype.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * calls.c (store_unaligned_arguments_into_pseudos): Skip PARALLEL
+ arguments.
+
+2013-11-14 DJ Delorie <dj@redhat.com>
+
+ * config/rx/rx.c (rx_mode_dependent_address_p): Allow offsets up
+ to 16 bits.
+
+2013-11-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (thread_through_normal_block): Only push the
+ EDGE_START_JUMP_THREAD marker if the jump threading path is empty.
+
+2013-11-14 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * doc/invoke.texi: Update documentation for AArch64's -mcpu
+ and -mtune options.
+
+2013-11-14 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-cores.def (example-1): Remove.
+ (example-2): Likewise.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * config/aarch64/aarch64.md: Do not include "large.md" or "small.md".
+ (generic_sched): Remove "large", "small".
+ * config/aarch64/large.md: Delete.
+ * config/aarch64/small.md: Delete.
+
+2013-11-14 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-cores.def (cortex-a57): Tune for cortexa15.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * config/aarch64/aarch64.md: Include cortex-a15 pipeline model.
+ (generic_sched): "no" if we are tuning for cortexa15.
+ * config/arm/cortex-a15.md: Include cortex-a15-neon.md by
+ relative path.
+
+2013-11-14 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-arches.def (armv8-a): Tune for cortex-a53.
+ * config/aarch64/aarch64.md: Do not include aarch64-generic.md.
+ * config/aarch64/aarch64.c (aarch64_tune): Initialize to cortexa53.
+ (all_cores): Use cortexa53 when tuning for "generic".
+ (aarch64_override_options): Fix comment.
+ * config/aarch64/aarch64.h (TARGET_CPU_DEFAULT): Set to cortexa53.
+ * config/aarch64/aarch64-generic.md: Delete.
+
+2013-11-14 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.c (all_architectures): Remove "generic".
+
+2013-11-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.c: Include aarch-cost-tables.h.
+ (generic_rtx_cost_table): Remove.
+ (aarch64_rtx_costs): Use fields from cpu_cost_table.
+ * config/aarch64/aarch64-protos.h (tune_params): Use cpu_cost_table for
+ insn_extra_cost.
+ (cpu_rtx_cost_table): Remove.
+
+2013-11-14 Julian Brown <julian@codesourcery.com>
+ Joey Ye <joey.ye@arm.com>
+
+ * config/arm/arm.c (arm_cortex_m_branch_cost): New.
+ (arm_v7m_tune): New.
+ (arm_slowmul_tune, arm_fastmul_tune, arm_strongarm_tune, arm_9e_tune,
+ arm_v6t2_tune, arm_cortex_tune, arm_cortex_a15_tune,
+ arm_cortex_a5_tune, arm_v6m_tune): Add comments for Sched adj cost.
+ * config/arm/arm-cores.def (cortex-m4, cortex-m3): Use arm_v7m_tune.
+
+2013-11-14 Kirill Yukhin <kirill.yukhin@intel.com>
+
+ PR target/57491
+ * config/ia64/ia64.c (ia64_split_tmode_move): Relax `dead'
+ flag setting.
+
+2013-11-14 Jakub Jelinek <jakub@redhat.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/59101
+ * config/i386/i386.md (*anddi_2): Only allow CCZmode if
+ operands[2] satisfies_constraint_Z that might have bit 31 set.
+
+2013-11-13 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/59102
+ * gimple-ssa-isolate-paths.c
+ (insert_trap_and_remove_trailing_statments): Ensure STMT is a
+ gimple assignment before looking at gimple_assign_lhs.
+
+2013-11-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ * ira.c: Add comment about threads at the top of file.
+
+2013-11-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ * ira-color.c (coalesce_allocnos): Don't allocate and free
+ sorted_copies.
+
+2013-11-14 Tom de Vries <tom@codesourcery.com>
+
+ * tree-ssa-tail-merge.c (gimple_equal_p): Add test for structural
+ equality for GIMPLE_ASSIGN.
+
+2013-11-14 Tom de Vries <tom@codesourcery.com>
+
+ * tree-ssa-tail-merge.c (gimple_operand_equal_value_p): Factor new
+ function out of ...
+ (gimple_equal_p): ... here.
+
+2013-11-14 Tom de Vries <tom@codesourcery.com>
+
+ * trans-mem.c (is_tm_ending): New function.
+ * gimple.h (is_tm_ending): Declare.
+ * tree-ssa-tail-merge.c (gimple_equal_p): Remove test on
+ BUILT_IN_TM_COMMIT.
+ (find_duplicate): Use is_tm_ending instead of is_tm_ending_fndecl.
+
+2013-11-14 Tom de Vries <tom@codesourcery.com>
+
+ * tree-ssa-tail-merge.c (gimple_equal_p): Remove equal variable.
+
+2013-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-walk.h: New File. Relocate prototypes from gimple.h.
+ (struct walk_stmt_info): Relocate here from gimple.h.
+ * gimple-iterator.h: New File. Relocate prototypes from gimple.h.
+ (struct gimple_stmt_iterator_d): Relocate here from gimple.h.
+ (gsi_start_1, gsi_none, gsi_start_bb, gsi_last_1, gsi_last_bb,
+ gsi_end_p, gsi_one_before_end_p, gsi_next, gsi_prev, gsi_stmt,
+ gsi_after_labels, gsi_next_nondebug, gsi_prev_nondebug,
+ gsi_start_nondebug_bb, gsi_start_nondebug_after_labels_bb,
+ gsi_last_nondebug_bb, gsi_bb, gsi_seq): Relocate here from gimple.h.
+ * gimple.h (struct gimple_stmt_iterator_d): Move to gimple-iterator.h.
+ (gsi_start_1, gsi_none, gsi_start_bb, gsi_last_1, gsi_last_bb,
+ gsi_end_p, gsi_one_before_end_p, gsi_next, gsi_prev, gsi_stmt,
+ gsi_after_labels, gsi_next_nondebug, gsi_prev_nondebug,
+ gsi_start_nondebug_bb, gsi_start_nondebug_after_labels_bb,
+ gsi_last_nondebug_bb, gsi_bb, gsi_seq): Move to gimple-iterator.h.
+ (struct walk_stmt_info): Move to gimple-walk.h.
+ (gimple_seq_set_location): Move to gimple.c
+ * gimple-walk.c: New File.
+ (walk_gimple_seq_mod, walk_gimple_seq, walk_gimple_asm, walk_gimple_op,
+ walk_gimple_stmt, get_base_loadstore, walk_stmt_load_store_addr_ops,
+ walk_stmt_load_store_ops): Relocate here from gimple.c.
+ * gimple-iterator.c: Include gimple-iterator.h.
+ * gimple.c (walk_gimple_seq_mod, walk_gimple_seq, walk_gimple_asm,
+ walk_gimple_op, walk_gimple_stmt, get_base_loadstore,
+ walk_stmt_load_store_addr_ops, walk_stmt_load_store_ops): Move to
+ gimple-walk.c.
+ (gimple_seq_set_location): Relocate from gimple.h.
+ * tree-phinodes.h (set_phi_nodes): Move to tree-phinodes.c.
+ * tree-phinodes.c (set_phi_nodes): Relocate from tree-phinodes.h.
+ * gengtype.c (open_base_files): Add gimple-iterator.h to include list.
+ * Makefile.in (OBJS): Add gimple-walk.o
+ * asan.c: Update Include list as required for gimple-iterator.h and
+ gimple-walk.h.
+ * cfgexpand.c: Likewise.
+ * cfgloop.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cgraph.c: Likewise.
+ * cgraphbuild.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * gimple-fold.c: Likewise.
+ * gimple-low.c: Likewise.
+ * gimple-pretty-print.c: Likewise.
+ * gimple-ssa-isolate-paths.c: Likewise.
+ * gimple-ssa-strength-reduction.c: Likewise.
+ * gimple-streamer-in.c: Likewise.
+ * gimple-streamer-out.c: Likewise.
+ * gimplify.c: Likewise.
+ * graphite-blocking.c: Likewise.
+ * graphite-clast-to-gimple.c: Likewise.
+ * graphite-dependences.c: Likewise.
+ * graphite-interchange.c: Likewise.
+ * graphite-optimize-isl.c: Likewise.
+ * graphite-poly.c: Likewise.
+ * graphite-scop-detection.c: Likewise.
+ * graphite-sese-to-poly.c: Likewise.
+ * graphite.c: Likewise.
+ * ipa-inline-analysis.c: Likewise.
+ * ipa-profile.c: Likewise.
+ * ipa-prop.c: Likewise.
+ * ipa-pure-const.c: Likewise.
+ * ipa-split.c: Likewise.
+ * lto-streamer-in.c: Likewise.
+ * lto-streamer-out.c: Likewise.
+ * omp-low.c: Likewise.
+ * predict.c: Likewise.
+ * profile.c: Likewise.
+ * sese.c: Likewise.
+ * tracer.c: Likewise.
+ * trans-mem.c: Likewise.
+ * tree-call-cdce.c: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-cfgcleanup.c: Likewise.
+ * tree-complex.c: Likewise.
+ * tree-data-ref.c: Likewise.
+ * tree-dfa.c: Likewise.
+ * tree-eh.c: Likewise.
+ * tree-emutls.c: Likewise.
+ * tree-if-conv.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-into-ssa.c: Likewise.
+ * tree-loop-distribution.c: Likewise.
+ * tree-nested.c: Likewise.
+ * tree-nrv.c: Likewise.
+ * tree-object-size.c: Likewise.
+ * tree-outof-ssa.c: Likewise.
+ * tree-parloops.c: Likewise.
+ * tree-predcom.c: Likewise.
+ * tree-profile.c: Likewise.
+ * tree-scalar-evolution.c: Likewise.
+ * tree-sra.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-coalesce.c: Likewise.
+ * tree-ssa-copy.c: Likewise.
+ * tree-ssa-copyrename.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa-dse.c: Likewise.
+ * tree-ssa-forwprop.c: Likewise.
+ * tree-ssa-ifcombine.c: Likewise.
+ * tree-ssa-live.c: Likewise.
+ * tree-ssa-loop-ch.c: Likewise.
+ * tree-ssa-loop-im.c: Likewise.
+ * tree-ssa-loop-ivcanon.c: Likewise.
+ * tree-ssa-loop-ivopts.c: Likewise.
+ * tree-ssa-loop-manip.c: Likewise.
+ * tree-ssa-loop-niter.c: Likewise.
+ * tree-ssa-loop-prefetch.c: Likewise.
+ * tree-ssa-loop.c: Likewise.
+ * tree-ssa-math-opts.c: Likewise.
+ * tree-ssa-phiopt.c: Likewise.
+ * tree-ssa-phiprop.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa-propagate.c: Likewise.
+ * tree-ssa-reassoc.c: Likewise.
+ * tree-ssa-sink.c: Likewise.
+ * tree-ssa-strlen.c: Likewise.
+ * tree-ssa-structalias.c: Likewise.
+ * tree-ssa-tail-merge.c: Likewise.
+ * tree-ssa-ter.c: Likewise.
+ * tree-ssa-threadedge.c: Likewise.
+ * tree-ssa-threadupdate.c: Likewise.
+ * tree-ssa-uncprop.c: Likewise.
+ * tree-ssa-uninit.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-stdarg.c: Likewise.
+ * tree-switch-conversion.c: Likewise.
+ * tree-tailcall.c: Likewise.
+ * tree-vect-data-refs.c: Likewise.
+ * tree-vect-generic.c: Likewise.
+ * tree-vect-loop-manip.c: Likewise.
+ * tree-vect-loop.c: Likewise.
+ * tree-vect-patterns.c: Likewise.
+ * tree-vect-slp.c: Likewise.
+ * tree-vect-stmts.c: Likewise.
+ * tree-vectorizer.c: Likewise.
+ * tree-vrp.c: Likewise.
+ * tree.c: Likewise.
+ * tsan.c: Likewise.
+ * value-prof.c: Likewise.
+ * vtable-verify.c: Likewise.
+
+2013-11-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * gimple-ssa-isolate-paths.c (pass_isolate_erroneous_paths): Comment
+ fix.
+
+2013-11-13 Jeff Law <law@redhat.com>
+
+ * PR middle-end/59119
+ * gimple-ssa-isolate-paths.c (find_implicit_erroneous_behaviour): New
+ function, extracted from gimple_ssa_isolate_erroneous_paths.
+ (find_explicit_erroneous_behaviour): Similarly.
+ (insert_trap_and_remove_trailing_statements): Remove statements
+ in reverse order.
+
+2013-11-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cfgrtl.c (can_fallthru): Reorder code to move tablejump check up.
+ Make that check explicit. BB_HEAD cannot be NULL, remove check for it.
+ * haifa-sched.c (ready_remove_first_dispatch): Check INSN_P before
+ looking at INSN_CODE.
+ * reload1.c (delete_dead_insn) Do not expect JUMP_TABLE_DATA to be an
+ active_insn_p object, respect basic block boundaries.
+ * reorg.c (follow_jumps): Use invariant that JUMP_TABLE_DATA always
+ follows immediately after the jump table data label.
+ * config/nds32/nds32.c (nds32_output_casesi_pc_relative): Likewise.
+ * config/sh/sh.c (barrier_align): Likewise. Rearrange code such
+ that JUMP_TABLE_DATA is not expected to be an active_insn_p object.
+
+2013-11-13 Teresa Johnson <tejohnson@google.com>
+
+ PR ipa/58862
+ * predict.c (drop_profile): Error is currently too strict.
+ (handle_missing_profiles): Pass call_count to drop_profile.
+
+2013-11-13 Teresa Johnson <tejohnson@google.com>
+
+ PR ipa/58862
+ * ipa-inline.c (edge_badness): Fix overflow.
+
+2013-11-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/59036
+ * ira-color.c (struct allocno_color_data): Add new members
+ first_thread_allocno, next_thread_allocno, thread_freq.
+ (sorted_copies): New static var.
+ (allocnos_conflict_by_live_ranges_p, copy_freq_compare_func): Move up.
+ (allocno_thread_conflict_p, merge_threads)
+ (form_threads_from_copies, form_threads_from_bucket)
+ (form_threads_from_colorable_allocno, init_allocno_threads): New
+ functions.
+ (bucket_allocno_compare_func): Add comparison by thread frequency
+ and threads.
+ (add_allocno_to_ordered_bucket): Rename to
+ add_allocno_to_ordered_colorable_bucket. Remove parameter.
+ (push_only_colorable): Call form_threads_from_bucket.
+ (color_pass): Call init_allocno_threads. Use
+ consideration_allocno_bitmap instead of coloring_allocno_bitmap
+ for nuillify allocno color data.
+ (ira_initiate_assign, ira_finish_assign): Allocate/free sorted_copies.
+ (coalesce_allocnos): Use static sorted copies.
+
+2013-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ * passes.c (execute_todo): Don't call do_per_function if
+ flags are zero.
+ (execute_one_ipa_transform_pass, execute_one_pass): Don't call
+ execute_function_dump if dump_file is NULL.
+
+2013-11-13 Martin Jambor <mjambor@suse.cz>
+
+ * cgraph.c (cgraph_get_create_node): Do what
+ cgraph_get_create_real_symbol_node used to do.
+ (cgraph_get_create_real_symbol_node): Removed. Changed all users to
+ call cgraph_get_create_node.
+ * cgraph.h (cgraph_get_create_real_symbol_node): Removed.
+ * lto-streamer-in.c (input_function): Call cgraph_get_node instead of
+ cgraph_get_create_node. Assert we get a node.
+
+2013-11-13 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vec_extract): New.
+
+2013-11-13 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vec_set<mode>): Add w -> w option to
+ the constraint.
+
+2013-11-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cfgexpand.c (expand_used_vars): Allocate space for partitions based
+ on PARM_DECLs or RESULT_DECLs only if they are ignored for debug info
+ or if optimization is enabled.
+ * tree-ssa-coalesce.c (coalesce_ssa_name): If optimization is disabled,
+ require that all the names based on a PARM_DECL or a RESULT_DECL that
+ isn't ignored for debug info be coalesced.
+
+2013-11-13 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * config/c6x/c6x.c: Include "gimple-expr.h".
+
+2013-11-13 Richard Biener <rguenther@suse.de>
+
+ * gimple-streamer-out.c (output_gimple_stmt): Also wrap
+ decls in ADDR_EXPR operands inside a MEM_REF and optimize that.
+ * gimple-streamer-in.c (input_gimple_stmt): Remove now dead code
+ dealing with type mismatches inside component reference chains.
+
+2013-11-13 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/59077
+ * ipa-pure-const.c (better_state): Update *state.
+
+2013-11-13 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/aarch64/aarch64.h (FRAME_GROWS_DOWNWARD): Define to 1.
+ * config/aarch64/aarch64.c (aarch64_initial_elimination_offset):
+ Update offset calculations.
+
+2013-11-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/35998
+ * dwarf2out.c (add_byte_size_attribute): Also use int_size_in_bytes
+ for fields. Do not add the attribute if the size is negative.
+
+2013-11-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c: Include aarch-cost-tables.h.
+ (generic_extra_costs): Move from here...
+ * config/arm/aarch-cost-tables.h: ... To here. New file.
+
+2013-11-13 Alexander Ivchenko <alexander.ivchenko@intel.com>
+ Maxim Kuznetsov <maxim.kuznetsov@intel.com>
+ Sergey Lega <sergey.s.lega@intel.com>
+ Anna Tikhonova <anna.tikhonova@intel.com>
+ Ilya Tocar <ilya.tocar@intel.com>
+ Andrey Turetskiy <andrey.turetskiy@intel.com>
+ Ilya Verbin <ilya.verbin@intel.com>
+ Kirill Yukhin <kirill.yukhin@intel.com>
+ Michael Zolotukhin <michael.v.zolotukhin@intel.com>
+
+ * config/i386/i386.c (ix86_print_operand): Support z-masking.
+ * config/i386/predicate.md (const_0_to_4_operand): New.
+ (const_0_to_5_operand): Ditto.
+ * config/i386/sse.md (UNSPEC_COMPRESS): New.
+ (UNSPEC_COMPRESS_STORE): Ditto.
+ (UNSPEC_EXPAND): Ditto.
+ (UNSPEC_EMBEDDED_ROUNDING): Ditto.
+ (define_mode_attr ssescalarsize): Ditto.
+ (avx512f_load<mode>_mask): Ditto.
+ (avx512f_store<mode>_mask): Ditto.
+ (avx512f_storedqu<mode>_mask): Ditto.
+ (avx512f_vmcmp<mode>3_mask): Ditto.
+ (avx512f_fmadd_<mode>_mask): Ditto.
+ (avx512f_fmadd_<mode>_mask3): Ditto.
+ (avx512f_fmsub_<mode>_mask): Ditto.
+ (avx512f_fmsub_<mode>_mask3): Ditto.
+ (avx512f_fnmadd_<mode>_mask): Ditto.
+ (avx512f_fnmadd_<mode>_mask3): Ditto.
+ (avx512f_fnmsub_<mode>_mask): Ditto.
+ (avx512f_fnmsub_<mode>_mask3): Ditto.
+ (avx512f_fmaddsub_<mode>_mask): Ditto.
+ (avx512f_fmaddsub_<mode>_mask3): Ditto.
+ (avx512f_fmsubadd_<mode>_mask): Ditto.
+ (avx512f_fmsubadd_<mode>_mask3): Ditto.
+ (vec_unpacku_float_lo_v16si): Ditto.
+ (avx512f_vextract<shuffletype>32x4_mask): Ditto.
+ (avx512f_vextract<shuffletype>32x4_1_maskm): Ditto.
+ (avx512f_vextract<shuffletype>64x4_mask): Ditto.
+ (vec_extract_lo_<mode>_maskm): Ditto.
+ (vec_extract_hi_<mode>_maskm): Ditto.
+ (avx512f_vternlog<mode>_mask): Ditto.
+ (avx512f_shufps512_mask): Ditto.
+ (avx512f_fixupimm<mode>_mask): Ditto.
+ (avx512f_shufpd512_mask): Ditto.
+ (avx512f_<code><pmov_src_lower><mode>2_mask): Ditto.
+ (avx512f_<code>v8div16qi2_mask/trunc): Ditto.
+ (*avx512f_<code>v8div16qi2_store_mask): Ditto.
+ (ashr<mode>3<mask_name>): Ditto.
+ (avx512f_vinsert<shuffletype>32x4_mask): Ditto.
+ (avx512f_vinsert<shuffletype>64x4_mask): Ditto.
+ (avx512f_shuf_<shuffletype>64x2_mask): Ditto.
+ (avx512f_shuf_<shuffletype>32x4_mask): Ditto.
+ (avx512f_pshufdv3_mask): Ditto.
+ (avx512f_perm<mode>_mask): Ditto.
+ (avx512f_vpermi2var<mode>3_mask): Ditto.
+ (avx512f_vpermt2var<mode>3_mask): Ditto.
+ (avx512f_compress<mode>_mask): Ditto.
+ (avx512f_compressstore<mode>_mask): Ditto.
+ (avx512f_expand<mode>_mask): Ditto.
+ (<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>): Extend
+ to support masking.
+ (avx512f_storeu<ssemodesuffix>512_mask): Ditto.
+ (<plusminus_insn><mode>3<mask_name>): Ditto.
+ (*<plusminus_insn><mode>3<mask_name>): Ditto.
+ (mul<mode>3<mask_name>): Ditto.
+ (*mul<mode>3<mask_name>): Ditto.
+ (<sse>_div<mode>3<mask_name>): Ditto.
+ (<mask_codefor>rcp14<mode><mask_name>): Ditto.
+ (<sse>_sqrt<mode>2<mask_name>): Ditto.
+ (<mask_codefor>rsqrt14<mode><mask_name>): Ditto.
+ (<code><mode>3<mask_name>/smaxmin): Ditto.
+ (*<code><mode>3_finite<mask_name>/smaxmin): Ditto.
+ (*<code><mode>3<mask_name>/smaxmin): Ditto.
+ (float<sseintvecmodelower><mode>2<mask_name>): Ditto.
+ (ufloatv16siv16sf2<mask_name>): Ditto.
+ (<mask_codefor>avx512f_fix_notruncv16sfv16si<mask_name>): Ditto.
+ (<mask_codefor>avx512f_ufix_notruncv16sfv16si<mask_name>): Ditto.
+ (<fixsuffix>fix_truncv16sfv16si2<mask_name>): Ditto.
+ (float<si2dfmodelower><mode>2<mask_name>): Ditto.
+ (ufloatv8siv8df<mask_name>): Ditto.
+ (<mask_codefor>avx512f_cvtpd2dq512<mask_name>): Ditto.
+ (avx512f_ufix_notruncv8dfv8si<mask_name>): Ditto.
+ (<fixsuffix>fix_truncv8dfv8si2<mask_name>): Ditto.
+ (<mask_codefor>avx512f_cvtpd2ps512<mask_name>): Ditto.
+ (<sse2_avx_avx512f>_cvtps2pd<avxsizesuffix><mask_name>): Ditto.
+ (<mask_codefor>avx512f_unpckhps512<mask_name>): Ditto.
+ (<mask_codefor>avx512f_unpcklps512<mask_name>): Ditto.
+ (<mask_codefor>avx512f_movshdup512<mask_name>): Ditto.
+ (<mask_codefor>avx512f_movsldup512<mask_name>): Ditto.
+ (<mask_codefor>avx512f_vextract<shuffletype>32x4_1<mask_name>): Ditto.
+ (vec_extract_lo_<mode><mask_name>): Ditto.
+ (vec_extract_hi_<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512f_unpckhpd512<mask_name>): Ditto.
+ (avx512f_movddup512<mask_name>): Ditto.
+ (avx512f_unpcklpd512<mask_name>): Ditto.
+ (*avx512f_unpcklpd512<mask_name>): Ditto.
+ (*avx512f_vmscalef<mode>): Ditto.
+ (avx512f_scalef<mode><mask_name>): Ditto.
+ (avx512f_getexp<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512f_align<mode><mask_name>): Ditto.
+ (avx512f_rndscale<mode><mask_name>): Ditto.
+ (avx512f_shufps512_1<mask_name>): Ditto.
+ (avx512f_shufpd512_1<mask_name>): Ditto.
+ (<plusminus_insn><mode>3<mask_name>): Ditto.
+ (*<plusminus_insn><mode>3<mask_name>): Ditto.
+ (vec_widen_umult_even_v16si<mask_name>): Ditto.
+ (*vec_widen_umult_even_v16si<mask_name>): Ditto.
+ (vec_widen_smult_even_v16si<mask_name>): Ditto.
+ (*vec_widen_smult_even_v16si<mask_name>): Ditto.
+ (mul<mode>3<mask_name>): Ditto.
+ (*<sse4_1_avx2>_mul<mode>3<mask_name>): Ditto.
+ (<shift_insn><mode>3<mask_name>): Ditto.
+ (avx512f_<rotate>v<mode><mask_name>/rotate): Ditto.
+ (avx512f_<rotate><mode><mask_name>): Ditto.
+ (<code><mode>3<mask_name>/maxmin): Ditto.
+ (*avx2_<code><mode>3<mask_name>/maxmin): Ditto.
+ (<sse2_avx2>_andnot<mode>3<mask_name>): Ditto.
+ (*andnot<mode>3<mask_name>): Ditto.
+ (<mask_codefor><code><mode>3<mask_name>/any_logic): Ditto.
+ (<mask_codefor>avx512f_interleave_highv16si<mask_name>): Ditto.
+ (<mask_codefor>avx512f_interleave_lowv16si<mask_name>): Ditto.
+ (<mask_codefor>avx512f_vinsert<shuffletype>32x4_1<mask_name>): Ditto.
+ (vec_set_lo_<mode><mask_name>): Ditto.
+ (vec_set_hi_<mode><mask_name>): Ditto.
+ (avx512f_shuf_<shuffletype>64x2_1<mask_name>): Ditto.
+ (avx512f_shuf_<shuffletype>32x4_1<mask_name>): Ditto.
+ (avx512f_pshufd_1<mask_name>): Ditto.
+ (<mask_codefor>abs<mode>2<mask_name>): Ditto.
+ (<mask_codefor>avx512f_<code>v16qiv16si2<mask_name>): Ditto.
+ (avx512f_<code>v16hiv16si2<mask_name>/any_extend): Ditto.
+ (avx512f_<code>v8qiv8di2<mask_name>/any_extend): Ditto.
+ (avx512f_<code>v8hiv8di2<mask_name>/any_extend): Ditto.
+ (avx512f_<code>v8siv8di2<mask_name>/any_extend): Ditto.
+ (avx512er_exp2<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512er_rcp28<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512er_rsqrt28<mode><mask_name>): Ditto.
+ (<avx2_avx512f>_permvar<mode><mask_name>): Ditto.
+ (<avx2_avx512f>_perm<mode>_1<mask_name>): Ditto.
+ (<mask_codefor>avx512f_vec_dup<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512f_broadcast<mode><mask_name>/V16FI): Ditto.
+ (<mask_codefor>avx512f_broadcast<mode><mask_name>/V8FI): Ditto.
+ (<mask_codefor>avx512f_vec_dup_gpr<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512f_vec_dup_mem<mode><mask_name>): Ditto.
+ (<sse2_avx_avx512f>_vpermil<mode><mask_name>/VF2): Ditto.
+ (<sse2_avx_avx512f>_vpermil<mode><mask_name>/VF1): Ditto.
+ (*<sse2_avx_avx512f>_vpermilp<mode><mask_name>): Ditto.
+ (<sse2_avx_avx512f>_vpermilvar<mode>3<mask_name>): Ditto.
+ (<avx2_avx512f>_ashrv<mode><mask_name>): Ditto.
+ (<avx2_avx512f>_<shift_insn>v<mode><mask_name>): Ditto.
+ (<mask_codefor>avx512f_vcvtph2ps512<mask_name>): Ditto.
+ (<mask_codefor>avx512f_vcvtps2ph512<mask_name>): Ditto.
+ (avx512f_getmant<mode><mask_name>): Ditto.
+ (clz<mode>2<mask_name>): Ditto.
+ (<mask_codefor>conflict<mode><mask_name>): Ditto.
+ (*srcp14<mode>): Remove visibility.
+ (*rsqrt14<mode>): Ditto.
+ (*fma_fmsub_<mode>): Ditto.
+ (*fma_fnmadd_<mode>): Ditto.
+ (*avx512f_rndscale<mode>): Ditto.
+ * config/i386/subst.md: New file.
+
+2013-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * doc/extend.texi (Statement Exprs, Typeof): Discuss __auto_type.
+ * ginclude/stdatomic.h (kill_dependency, atomic_store_explicit)
+ (atomic_load_explicit, atomic_exchange_explicit)
+ (atomic_compare_exchange_strong_explicit)
+ (atomic_compare_exchange_weak_explicit): Use __auto_type to
+ declare variable initialized with PTR argument.
+
+2013-11-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (thread_around_empty_blocks): New argument
+ backedge_seen_p. Set, use and pass it to children appropriately.
+ (thread_through_normal_block): Similarly.
+ (thread_across_edge): Similarly.
+
+ * gimple-ssa-isolate-paths.c (check_loadstore): Mark discovered
+ memory references as volatile.
+ (insert_trap_and_remove_trailing_statements): Fix comment.
+
+2013-11-12 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR other/58712
+ * ira-costs.c (record_operand_costs): Check operands number for
+ the single set.
+
+2013-11-12 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/59054
+ * config/rs6000/rs6000.md (movdi_internal32): Eliminate
+ constraints that would allow DImode into the traditional Altivec
+ registers, but cause undesirable code generation when loading 0 as
+ a constant.
+ (movdi_internal64): Likewise.
+ (cmp<mode>_fpr): Do not use %x for CR register output.
+ (extendsfdf2_fpr): Fix constraints when -mallow-upper-df and
+ -mallow-upper-sf debug switches are used.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-expr.h (create_tmp_var_name, create_tmp_var_raw,
+ create_tmp_var, create_tmp_reg, mark_addressable, is_gimple_reg_rhs):
+ Relocate prototypes from gimple.h.
+ * gimplify.h: New File. Relocate some prototypes from gimple.h here.
+ (gimple_predicate, enum fallback, enum gimplify_status): Relocate
+ from gimple.h.
+ * gimple.h: Move some prototypes to gimplify.h.
+ (gimple_predicate, enum fallback, enum gimplify_status): Move to
+ gimplify.h.
+ (gimple_do_not_emit_location_p, gimple_set_do_not_emit_location):
+ Relocate from gimpify.c.
+ * gimple-expr.c (remove_suffix, tmp_var_id_num, create_tmp_var_name,
+ create_tmp_var_raw, create_tmp_var, create_tmp_reg, mark_addressable,
+ is_gimple_reg_rhs) Relocate from gimplify.c.
+ * gimplify.c (mark_addressable): Move to gimple-expr.c.
+ (gimple_seq_add_stmt_without_update): Move to gimple.c.
+ (remove_suffix, tmp_var_id_num, create_tmp_var_name,
+ create_tmp_var_raw, create_tmp_var, create_tmp_reg,
+ is_gimple_reg_rhs): Move to gimple-expr.c.
+ (should_carry_location_p): Move to gimple.c.
+ (gimple_do_not_emit_location_p, gimple_set_do_not_emit_location): Move
+ to gimple.h.
+ (annotate_one_with_location, annotate_all_with_location_after,
+ annotate_all_with_location): Move to gimple.c.
+ (compare_case_labels, sort_case_labels,
+ preprocess_case_label_vec_for_gimple): Move to gimple.c.
+ (rhs_predicate_for): Make static.
+ (gimplify_assign): Relocate from gimple.c.
+ * gimple.c (gimplify_assign): Move to gimplify.c.
+ (gimple_seq_add_stmt_without_update, should_carry_location_p,
+ annotate_one_with_location, annotate_all_with_location_after,
+ annotate_all_with_location, compare_case_labels, sort_case_labels,
+ preprocess_case_label_vec_for_gimple): Relocate from gimplify.c.
+ * tree.h (unshare_expr, unshare_expr_without_location,
+ mark_addressable): Move prototypes to gimplify.h.
+ * Makefile.in (GTFILES): gimple-expr.c now has the GTY tag for
+ tmp_var_id_num
+ * asan.c: Include gimplify.h rather than gimple.h.
+ * cfgloopmanip.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cilk-common.c: Likewise.
+ * dwarf2out.c: Dont include gimple.h.
+ * fold-const.c: Include gimplify.h rather than gimple.h.
+ * function.c: Likewise.
+ * gimple-fold.c: Likewise.
+ * gimple-ssa-strength-reduction.c: Likewise.
+ * graphite-clast-to-gimple.c: Likewise.
+ * graphite-sese-to-poly.c: Likewise.
+ * ipa-prop.c: Likewise.
+ * ipa-split.c: Likewise.
+ * ipa.c: Likewise.
+ * langhooks.c: Dont include gimple.h.
+ * loop-init.c: Include gimplify.h rather than gimple.h.
+ * omp-low.c: Likewise.
+ * sese.c: Likewise.
+ * stor-layout.c: Likewise.
+ * targhooks.c: Likewise.
+ * trans-mem.c: Likewise.
+ * tree-affine.c: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-cfgcleanup.c: Likewise.
+ * tree-complex.c: Likewise.
+ * tree-if-conv.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-iterator.c: Likewise.
+ * tree-loop-distribution.c: Likewise.
+ * tree-nested.c: Likewise.
+ * tree-parloops.c: Likewise.
+ * tree-predcom.c: Likewise.
+ * tree-profile.c: Likewise.
+ * tree-scalar-evolution.c: Likewise.
+ * tree-sra.c: Likewise.
+ * tree-ssa-address.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-forwprop.c: Likewise.
+ * tree-ssa-ifcombine.c: Likewise.
+ * tree-ssa-loop-im.c: Likewise.
+ * tree-ssa-loop-ivopts.c: Likewise.
+ * tree-ssa-loop-manip.c: Likewise.
+ * tree-ssa-loop-niter.c: Likewise.
+ * tree-ssa-loop-prefetch.c: Likewise.
+ * tree-ssa-loop-unswitch.c: Likewise.
+ * tree-ssa-math-opts.c: Likewise.
+ * tree-ssa-phiopt.c: Likewise.
+ * tree-ssa-phiprop.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa-propagate.c: Likewise.
+ * tree-ssa-reassoc.c: Likewise.
+ * tree-ssa-sccvn.c: Likewise.
+ * tree-ssa-strlen.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-switch-conversio: Likewise.n.c
+ * tree-tailcall.c: Likewise.
+ * tree-vect-data-refs.c: Likewise.
+ * tree-vect-generic.c: Likewise.
+ * tree-vect-loop-manip.c: Likewise.
+ * tree-vect-loop.c: Likewise.
+ * tree-vect-patterns.c: Likewise.
+ * tree-vect-stmts.c: Likewise.
+ * tsan.c: Likewise.
+ * value-prof.c: Likewise.
+ * config/aarch64/aarch64.c: Include gimplify.h instead of gimple.h.
+ * config/alpha/alpha.c: Likewise.
+ * config/darwin.c: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/mep/mep.c: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/spu/spu.c: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/tilegx/tilegx.c: Likewise.
+ * config/tilepro/tilepro.c: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ * tree.c (grow_tree_vec_stat): New function ...
+ * tree.h (grow_tree_vec_stat) (grow_tree_vec): ... and its declaration
+ and macro front-end.
+
+2013-11-12 Marek Polacek <polacek@redhat.com>
+
+ * final.c (update_alignments): Initialize label to NULL_RTX.
+
+2013-11-12 Jeff Law <law@redhat.com>
+
+ * gimple-ssa-isolate-paths.c (check_loadstore): New function.
+ (insert_trap_and_remove_trailing_statements): New argument OP which
+ is the NULL pointer. Emit the trap after the load/store through
+ the NULL pointer. Simplify the RHS of a store through a NULL pointer
+ when trivial to do so.
+ (isolate_path): Corresponding changes.
+ (gimple_ssa_isolate_erroneous_path): Likewise.
+
+2013-11-12 Teresa Johnson <tejohnson@google.com>
+ Jan Hubicka <jh@suse.cz>
+
+ * predict.c (drop_profile): New function.
+ (handle_missing_profiles): Ditto.
+ (counts_to_freqs): Don't overwrite estimated frequencies
+ when function has no profile counts.
+ * predict.h (handle_missing_profiles): Declare.
+ * tree-inline.c (freqs_to_counts): New function.
+ (copy_cfg_body): Invoke freqs_to_counts as needed.
+ * tree-profile.c (tree_profiling): Invoke handle_missing_profiles.
+
+2013-11-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/59088
+ * config/i386/x86-tune.def (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL):
+ Set for m_HASWELL.
+ (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL): Set for m_HASWELL.
+
+2013-11-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/59084
+ * config/i386/i386.c (ix86_option_override_internal): Check
+ X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL and
+ X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL for
+ MASK_AVX256_SPLIT_UNALIGNED_LOAD and
+ MASK_AVX256_SPLIT_UNALIGNED_STORE.
+
+ * config/i386/x86-tune.def (X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL):
+ Clear m_COREI7_AVX and update comments.
+ (X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL): Likewise.
+
+2013-11-12 Martin Jambor <mjambor@suse.cz>
+
+ PR rtl-optimization/10474
+ * ira.c (interesting_dest_for_shprep): New function.
+ (split_live_ranges_for_shrink_wrap): Likewise.
+ (find_moveable_pseudos): Move calculation of dominance info,
+ df_analysios and the final anlyses to...
+ (ira): ...here, call split_live_ranges_for_shrink_wrap.
+
+2013-11-12 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-ssa-loop-ivopts.c (force_expr_to_var_cost): Refactor the code.
+ Handle type conversion.
+
+2013-11-11 Martin Liska <marxin.liska@gmail.com>
+ Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (dump_cgraph_node): Profile dump added.
+ * cgraph.h (struct cgraph_node): New time profile variable added.
+ * cgraphclones.c (cgraph_clone_node): Time profile is cloned.
+ * gcov-io.h (gcov_type): New profiler type introduced.
+ * ipa-profile.c (lto_output_node): Streaming for time profile added.
+ (input_node): Time profiler is read from LTO stream.
+ * predict.c (maybe_hot_count_p): Hot prediction changed.
+ * profile.c (instrument_values): New case for time profiler added.
+ (compute_value_histograms): Read of time profile.
+ * tree-pretty-print.c (dump_function_header): Time profiler is dumped.
+ * tree-profile.c (init_ic_make_global_vars): Time profiler
+ function added.
+ (gimple_init_edge_profiler): TP function instrumentation.
+ (gimple_gen_time_profiler): New.
+ * value-prof.c (gimple_add_histogram_value): Support for time profiler
+ added.
+ (dump_histogram_value): TP type added to dumps.
+ (visit_hist): More sensitive check that takes TP into account.
+ (gimple_find_values_to_profile): TP instrumentation.
+ * value-prof.h (hist_type): New histogram type added.
+ (struct histogram_value_t): Pointer to struct function added.
+ * libgcc/Makefile.in: New GCOV merge function for TP added.
+ * libgcov.c: function_counter variable introduced.
+ (_gcov_merge_time_profile): New.
+ (_gcov_time_profiler): New.
+
+2013-11-11 Marc Glisse <marc.glisse@inria.fr>
+ Jeff Law <law@redhat.com>
+
+ * tree-ssa-alias.c (stmt_kills_ref_p_1): Use
+ ao_ref_init_from_ptr_and_size for builtins.
+
+2013-11-11 Uros Bizjak <ubizjak@gmail.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/58853
+ * config/i386/x86-tune.def
+ (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES): Rename from
+ TARGET_MISALIGNED_MOVE_STRING_PROLOGUES.
+ * config/i386/i386.h
+ (TARGET_MISALIGNED_MOVE_STRING_PRO_EPILOGUES): Rename from
+ TARGET_MISALIGNED_MOVE_STRING_PROLOGUES_EPILOGUES. Update for renamed
+ X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES.
+ * config/i386/i386.c (ix86_expand_set_or_movmem): Use
+ TARGET_MISALIGNED_MOVE_STRING_PRO_EPILOGUES to calculate
+ misaligned_prologue_used. Check that
+ desired_aling <= epilogue_size_needed.
+
+2013-11-11 Cong Hou <congh@google.com>
+
+ PR tree-optimization/59050
+ * tree-vect-data-refs.c (comp_dr_addr_with_seg_len_pair): Bug fix.
+
+2013-11-11 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ PR middle-end/59049
+ * expmed.c (emit_store_flag): Fail for const-const comparison.
+
+2013-11-11 Tristan Gingold <gingold@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.h (CONSTRUCTOR_NO_CLEARING): Define.
+ * tree-core.h (CONSTRUCTOR_NO_CLEARING): Document it.
+ * tree.def (CONSTRUCTOR): Likewise.
+ * doc/generic.texi (CONSTRUCTOR): Likewise. Update description.
+ * gimplify.c (gimplify_init_constructor): Do not clear the object when
+ the constructor is incomplete and CONSTRUCTOR_NO_CLEARING is set.
+
+2013-11-11 Basile Starynkevitch <basile@starynkevitch.net>
+
+ * toplev.c (toplev_main): Move PLUGIN_FINISH invocation before
+ diagnostic_finish.
+
+2013-11-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_new_rtx_costs): Return after handling
+ comparisons.
+
+2013-11-11 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/arc/arc.h (LOGICAL_OP_NON_SHORT_CIRCUIT): Define.
+
+2013-11-08 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadupdate.c (mark_threaded_blocks): Truncate jump
+ threading paths first, then perform PHI node checks if applicable.
+
+2013-11-10 Karlson2k <k2k@narod.ru>
+ Kai Tietz <ktietz@redhat.com>
+
+ PR plugin/52872
+ * configure.ac: Adding for exported symbols check
+ and for rdynamic-check executable-extension.
+ * configure: Regenerated.
+
+2013-11-10 Uros Bizjak <ubizjak@gmail.com>
+
+ * mode-switching.c (optimize_mode_switching): Mark block as
+ nontransparent, if last_mode at block exit is different from no_mode.
+
+2013-11-09 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * function.c (NAME__MAIN): Move to...
+ * cfgexpand.c (NAME__MAIN): ...here.
+
2013-11-09 Richard Sandiford <rdsandiford@googlemail.com>
* target.def (can_use_doloop_p): New hook.
@@ -85,8 +1551,7 @@
2013-11-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/59047
- * tree-predcom.c (ref_at_iteration): Handle bitfield accesses
- properly.
+ * tree-predcom.c (ref_at_iteration): Handle bitfield accesses properly.
2013-11-08 Ilya Enkovich <ilya.enkovich@intel.com>
@@ -119,8 +1584,7 @@
(TYPE_QUALS, TYPE_QUALS_NO_ADDR_SPACE): Add TYPE_QUAL_ATOMIC.
(TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC): New macro.
(atomicQI_type_node, atomicHI_type_node, atomicSI_type_node)
- (atomicDI_type_node, atomicTI_type_node): New macros for type
- nodes.
+ (atomicDI_type_node, atomicTI_type_node): New macros for type nodes.
* tree.c (set_type_quals): Set TYPE_ATOMIC.
(find_atomic_core_type): New function.
(build_qualified_type): Adjust alignment for qualified types.
@@ -129,23 +1593,20 @@
atomicHI_type_node, atomicSI_type_node, atomicDI_type_node and
atomicTI_type_node.
* print-tree.c (print_node): Print atomic qualifier.
- * tree-pretty-print.c (dump_generic_node): Print atomic type
- attribute.
+ * tree-pretty-print.c (dump_generic_node): Print atomic type attribute.
* target.def (atomic_assign_expand_fenv): New hook.
* doc/tm.texi.in (TARGET_ATOMIC_ASSIGN_EXPAND_FENV): New @hook.
* doc/tm.texi: Regenerate.
* targhooks.c (default_atomic_assign_expand_fenv): New function.
* targhooks.h (default_atomic_assign_expand_fenv): Declare.
- * sync-builtins.def (__atomic_feraiseexcept): New built-in
- function.
+ * sync-builtins.def (__atomic_feraiseexcept): New built-in function.
* config/i386/i386-builtin-types.def (VOID_FTYPE_PUSHORT): New
function type.
* config/i386/i386.c (enum ix86_builtins): Add
IX86_BUILTIN_FNSTENV, IX86_BUILTIN_FLDENV, IX86_BUILTIN_FNSTSW and
IX86_BUILTIN_FNCLEX.
(bdesc_special_args): Add __builtin_ia32_fnstenv,
- __builtin_ia32_fldenv, __builtin_ia32_fnstsw and
- __builtin_ia32_fnclex.
+ __builtin_ia32_fldenv, __builtin_ia32_fnstsw and __builtin_ia32_fnclex.
(ix86_expand_builtin): Handle the new built-in functions.
(ix86_atomic_assign_expand_fenv): New function.
(TARGET_ATOMIC_ASSIGN_EXPAND_FENV): New macro.
@@ -178,8 +1639,7 @@
* tree-ssa-loop-im.c
(move_computations_dom_walker::before_dom_children): Same.
* tree-ssa-loop-manip.c (rewrite_phi_with_iv): Same.
- * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
- Same.
+ * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Same.
* tree-ssa-propagate.c (substitute_and_fold): Same.
* tree-vect-loop.c (vect_finalize_reduction): Same.
* tree-vect-stmts.c (vectorizable_call): Same.
@@ -213,15 +1673,13 @@
* doc/invoke.texi (-fisolate-erroneous-paths): Document.
* gimple-ssa-isolate-paths.c (gate_isolate_erroneous_paths):
- No longer check if we have __builtin_trap, assume it's
- available.
+ No longer check if we have __builtin_trap, assume it's available.
2013-11-07 Diego Novillo <dnovillo@google.com>
* attribs.c (lookup_scoped_attribute_spec): Make static.
(get_attribute_namespace): Likewise.
- * builtins.c (more_const_call_expr_args_p): Move from
- tree.h.
+ * builtins.c (more_const_call_expr_args_p): Move from tree.h.
(validate_arglist): Move earlier in the file. Make static.
(expand_stack_restore): Move from stmt.c
(expand_stack_save): Move from stmt.c
@@ -298,7 +1756,7 @@
(in_array_bounds_p): Move to tree-eh.c.
(range_in_array_bounds_p): Move to tree-eh.c.
(truth_type_for): Move to gimple-fold.c.
- (list_equal_p): remove.
+ (list_equal_p): Remove.
* tree.h (decl_assembler_name_equal): Remove.
(decl_assembler_name_hash): Remove.
(truth_type_for): Remove.
@@ -344,13 +1802,12 @@
* doc/sourcebuild.texi (Top Level) <lto-plugin>: GNU ld can use
linker plugins, too.
- * config/arc/arc.h (LINK_COMMAND_SPEC): For
- -ftree-parallelize-loops=*, link to libgomp and its dependencies.
+ * config/arc/arc.h (LINK_COMMAND_SPEC): For -ftree-parallelize-loops=*,
+ link to libgomp and its dependencies.
* config/ia64/hpux.h (LIB_SPEC): Likewise.
* config/pa/pa-hpux11.h (LIB_SPEC): Likewise.
* config/pa/pa64-hpux.h (LIB_SPEC): Likewise.
- * gcc.c (GOMP_SELF_SPECS): Update comment about libgomp's
- dependencies.
+ * gcc.c (GOMP_SELF_SPECS): Update comment about libgomp's dependencies.
2013-11-07 Jakub Jelinek <jakub@redhat.com>
@@ -393,8 +1850,7 @@
(canonicalize_value): ... this. Also handle stripping of
TREE_OVERFLOW.
(get_value, set_lattice_value, get_value_for_expr): Adjust.
- * gimple-fold.c (canonicalize_constructor_val): Strip
- TREE_OVERFLOW.
+ * gimple-fold.c (canonicalize_constructor_val): Strip TREE_OVERFLOW.
* tree-ssa-threadedge.c (set_ssa_name_value): Likewise.
2013-11-07 Richard Biener <rguenther@suse.de>
@@ -453,8 +1909,7 @@
(finish_live_range_shrinkage): Ditto.
* sched-deps.c (create_insn_reg_set): Make void return value.
* passes.def: Add pass_live_range_shrinkage.
- * ira.c (update_equiv_regs): Don't move if
- flag_live_range_shrinkage.
+ * ira.c (update_equiv_regs): Don't move if flag_live_range_shrinkage.
* haifa-sched.c (live_range_shrinkage_p): New.
(initialize_live_range_shrinkage, finish_live_range_shrinkage):
New functions.
@@ -3378,8 +4833,7 @@
* ipa-reference.h: Include cgraph.h instead of tree.h.
* cgraph.h: Include basic-block.h instead of tree.h.
* tree-streamer.h: Do not include tree.h.
- * genattrtab.c (write_header): Generate inclusion of
- tree.h.
+ * genattrtab.c (write_header): Generate inclusion of tree.h.
* genautomata.c (main): Likewise.
* genemit.c: Likewise.
* genopinit.c: Likewise.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index bcf9fa39761..afb6d3f1a6d 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20131109
+20131116
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b0a2995e054..c11d14a00f7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1138,6 +1138,7 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
c-family/c-omp.o c-family/c-opts.o c-family/c-pch.o \
c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
c-family/c-semantics.o c-family/c-ada-spec.o \
+ c-family/c-cilkplus.o \
c-family/array-notation-common.o c-family/cilk.o c-family/c-ubsan.o
# Language-independent object files.
@@ -1240,7 +1241,9 @@ OBJS = \
gimple-ssa-strength-reduction.o \
gimple-streamer-in.o \
gimple-streamer-out.o \
+ gimple-walk.o \
gimplify.o \
+ gimplify-me.o \
godump.o \
graph.o \
graphds.o \
@@ -2258,7 +2261,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
$(srcdir)/tree-cfg.c \
$(srcdir)/tree-dfa.c \
- $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
+ $(srcdir)/tree-iterator.c $(srcdir)/gimple-expr.c \
$(srcdir)/tree-chrec.h \
$(srcdir)/tree-scalar-evolution.c \
$(srcdir)/tree-ssa-operands.h \
diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4
index 6798d6fbc6a..34de2075bf2 100644
--- a/gcc/acinclude.m4
+++ b/gcc/acinclude.m4
@@ -561,3 +561,12 @@ dnl Make sure that build_exeext is looked for
AC_DEFUN([gcc_AC_BUILD_EXEEXT], [
ac_executable_extensions="$build_exeext"])
+dnl GCC_GLIBC_VERSION_GTE_IFELSE(MAJOR, MINOR, IF-TRUE, IF-FALSE)
+dnl -------------------------------------------------------------
+dnl If the target glibc version ($glibc_version_major.$glibc_version_minor)
+dnl is at least MAJOR.MINOR, call IF-TRUE, otherwise call IF-FALSE.
+AC_DEFUN([GCC_GLIBC_VERSION_GTE_IFELSE],
+[
+AS_IF([test $glibc_version_major -gt $1 \
+ || ( test $glibc_version_major -eq $1 && test $glibc_version_minor -ge $2 )],
+[$3], [$4])])
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 44d04845b9e..4de8e32c897 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,37 @@
+2013-11-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ada/54040
+ * s-linux-x32.ads: New file.
+ * s-osprim-x32.adb: Likewise.
+ * s-linux.ads (time_t): New type.
+ * s-linux-alpha.ads (time_t): Likewise.
+ * s-linux-hppa.ads (time_t): Likewise.
+ * s-linux-mipsel.ads (time_t): Likewise.
+ * s-linux-sparc.ads (time_t): Likewise.
+ * s-osinte-linux.ads (time_t): Mark it private. Replace long
+ with System.Linux.time_t.
+ (timespec): Replace long with time_t.
+ * s-osinte-posix.adb (To_Timespec): Likewise.
+ * s-taprop-linux.adb (timeval): Replace C.long with
+ System.OS_Interface.time_t.
+ * gcc-interface/Makefile.in (LIBGNAT_TARGET_PAIRS): Replace
+ s-linux.ads with s-linux-x32.ads, s-osprim-posix.adb with
+ s-osprim-x32.adb for x32.
+
+2013-11-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc-interface/trans.c: Include gimple.h and pointer-set.h.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc-interface/trans.c: Include gimplify.h.
+
+2013-11-11 Tristan Gingold <gingold@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils2.c (gnat_build_constructor): Also set the flag
+ CONSTRUCTOR_NO_CLEARING on the constructor.
+
2013-10-30 Sharad Singhai <singhai@google.com>
* gnat_ugn.texi: Remove option description for PR middle-end/58134.
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 91778c5fcf6..885a5edce89 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -2186,11 +2186,11 @@ ifeq ($(strip $(filter-out %x32 linux%,$(target_cpu) $(target_os))),)
a-synbar.ads<a-synbar-posix.ads \
s-inmaop.adb<s-inmaop-posix.adb \
s-intman.adb<s-intman-posix.adb \
- s-linux.ads<s-linux.ads \
+ s-linux.ads<s-linux-x32.ads \
s-mudido.adb<s-mudido-affinity.adb \
s-osinte.ads<s-osinte-linux.ads \
s-osinte.adb<s-osinte-posix.adb \
- s-osprim.adb<s-osprim-posix.adb \
+ s-osprim.adb<s-osprim-x32.adb \
s-taprop.adb<s-taprop-linux.adb \
s-tasinf.ads<s-tasinf-linux.ads \
s-tasinf.adb<s-tasinf-linux.adb \
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 118f9f223dc..dcb667eb935 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -34,6 +34,8 @@
#include "libfuncs.h" /* For set_stack_check_libfunc. */
#include "tree-iterator.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "pointer-set.h"
#include "bitmap.h"
#include "cgraph.h"
#include "diagnostic.h"
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index ec986158a7a..0e97c178113 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -1874,6 +1874,7 @@ gnat_build_constructor (tree type, vec<constructor_elt, va_gc> *v)
v->qsort (compare_elmt_bitpos);
result = build_constructor (type, v);
+ CONSTRUCTOR_NO_CLEARING (result) = 1;
TREE_CONSTANT (result) = TREE_STATIC (result) = allconstant;
TREE_SIDE_EFFECTS (result) = side_effects;
TREE_READONLY (result) = TYPE_READONLY (type) || allconstant;
diff --git a/gcc/ada/s-linux-alpha.ads b/gcc/ada/s-linux-alpha.ads
index a700c9720e6..1a9f37acd7d 100644
--- a/gcc/ada/s-linux-alpha.ads
+++ b/gcc/ada/s-linux-alpha.ads
@@ -38,6 +38,12 @@
package System.Linux is
pragma Preelaborate;
+ ------------
+ -- time_t --
+ ------------
+
+ type time_t is new Long_Integer;
+
-----------
-- Errno --
-----------
diff --git a/gcc/ada/s-linux-hppa.ads b/gcc/ada/s-linux-hppa.ads
index d25dcebdb33..90461504945 100644
--- a/gcc/ada/s-linux-hppa.ads
+++ b/gcc/ada/s-linux-hppa.ads
@@ -38,6 +38,12 @@
package System.Linux is
pragma Preelaborate;
+ ------------
+ -- time_t --
+ ------------
+
+ type time_t is new Long_Integer;
+
-----------
-- Errno --
-----------
diff --git a/gcc/ada/s-linux-mipsel.ads b/gcc/ada/s-linux-mipsel.ads
index f1b119d0f11..028ea7c0b60 100644
--- a/gcc/ada/s-linux-mipsel.ads
+++ b/gcc/ada/s-linux-mipsel.ads
@@ -37,6 +37,12 @@
package System.Linux is
pragma Preelaborate;
+ ------------
+ -- time_t --
+ ------------
+
+ type time_t is new Long_Integer;
+
-----------
-- Errno --
-----------
diff --git a/gcc/ada/s-linux-sparc.ads b/gcc/ada/s-linux-sparc.ads
index 3ba20da4d5c..db3b4ea794c 100644
--- a/gcc/ada/s-linux-sparc.ads
+++ b/gcc/ada/s-linux-sparc.ads
@@ -38,6 +38,12 @@
package System.Linux is
pragma Preelaborate;
+ ------------
+ -- time_t --
+ ------------
+
+ type time_t is new Long_Integer;
+
-----------
-- Errno --
-----------
diff --git a/gcc/ada/s-linux-x32.ads b/gcc/ada/s-linux-x32.ads
new file mode 100644
index 00000000000..9dc0e830d94
--- /dev/null
+++ b/gcc/ada/s-linux-x32.ads
@@ -0,0 +1,110 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . L I N U X --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2013, Free Software Foundation, Inc. --
+-- --
+-- GNARL is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the x32 version of this package
+
+-- This package encapsulates cpu specific differences between implementations
+-- of GNU/Linux, in order to share s-osinte-linux.ads.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package
+
+package System.Linux is
+ pragma Preelaborate;
+
+ ------------
+ -- time_t --
+ ------------
+
+ type time_t is new Long_Long_Integer;
+
+ -----------
+ -- Errno --
+ -----------
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ EPERM : constant := 1;
+ ETIMEDOUT : constant := 110;
+
+ -------------
+ -- Signals --
+ -------------
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 7; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 10; -- user defined signal 1
+ SIGUSR2 : constant := 12; -- user defined signal 2
+ SIGCLD : constant := 17; -- alias for SIGCHLD
+ SIGCHLD : constant := 17; -- child status change
+ SIGPWR : constant := 30; -- power-fail restart
+ SIGWINCH : constant := 28; -- window size change
+ SIGURG : constant := 23; -- urgent condition on IO channel
+ SIGPOLL : constant := 29; -- pollable event occurred
+ SIGIO : constant := 29; -- I/O now possible (4.2 BSD)
+ SIGLOST : constant := 29; -- File lock lost
+ SIGSTOP : constant := 19; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 20; -- user stop requested from tty
+ SIGCONT : constant := 18; -- stopped process has been continued
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGUNUSED : constant := 31; -- unused signal (GNU/Linux)
+ SIGSTKFLT : constant := 16; -- coprocessor stack fault (Linux)
+ SIGLTHRRES : constant := 32; -- GNU/LinuxThreads restart signal
+ SIGLTHRCAN : constant := 33; -- GNU/LinuxThreads cancel signal
+ SIGLTHRDBG : constant := 34; -- GNU/LinuxThreads debugger signal
+
+ -- struct_sigaction offsets
+
+ sa_handler_pos : constant := 0;
+ sa_mask_pos : constant := Standard'Address_Size / 8;
+ sa_flags_pos : constant := 128 + sa_mask_pos;
+
+ SA_SIGINFO : constant := 16#04#;
+ SA_ONSTACK : constant := 16#08000000#;
+
+end System.Linux;
diff --git a/gcc/ada/s-linux.ads b/gcc/ada/s-linux.ads
index c8a7ad1744e..2339e29e04b 100644
--- a/gcc/ada/s-linux.ads
+++ b/gcc/ada/s-linux.ads
@@ -38,6 +38,12 @@
package System.Linux is
pragma Preelaborate;
+ ------------
+ -- time_t --
+ ------------
+
+ type time_t is new Long_Integer;
+
-----------
-- Errno --
-----------
diff --git a/gcc/ada/s-osinte-linux.ads b/gcc/ada/s-osinte-linux.ads
index a99c4e53f93..6eb0b88f561 100644
--- a/gcc/ada/s-osinte-linux.ads
+++ b/gcc/ada/s-osinte-linux.ads
@@ -218,6 +218,7 @@ package System.OS_Interface is
----------
type timespec is private;
+ type time_t is private;
function To_Duration (TS : timespec) return Duration;
pragma Inline (To_Duration);
@@ -596,11 +597,11 @@ private
type pid_t is new int;
- type time_t is new long;
+ type time_t is new System.Linux.time_t;
type timespec is record
tv_sec : time_t;
- tv_nsec : long;
+ tv_nsec : time_t;
end record;
pragma Convention (C, timespec);
diff --git a/gcc/ada/s-osinte-posix.adb b/gcc/ada/s-osinte-posix.adb
index 29579b25247..402ddcb6190 100644
--- a/gcc/ada/s-osinte-posix.adb
+++ b/gcc/ada/s-osinte-posix.adb
@@ -104,7 +104,7 @@ package body System.OS_Interface is
end if;
return timespec'(tv_sec => S,
- tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ tv_nsec => time_t (Long_Long_Integer (F * 10#1#E9)));
end To_Timespec;
end System.OS_Interface;
diff --git a/gcc/ada/s-osprim-x32.adb b/gcc/ada/s-osprim-x32.adb
new file mode 100644
index 00000000000..5d4964a2776
--- /dev/null
+++ b/gcc/ada/s-osprim-x32.adb
@@ -0,0 +1,173 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2013, Free Software Foundation, Inc. --
+-- --
+-- GNARL is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version is for Linux/x32
+
+package body System.OS_Primitives is
+
+ -- ??? These definitions are duplicated from System.OS_Interface
+ -- because we don't want to depend on any package. Consider removing
+ -- these declarations in System.OS_Interface and move these ones in
+ -- the spec.
+
+ type time_t is new Long_Long_Integer;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : time_t;
+ end record;
+ pragma Convention (C, timespec);
+
+ function nanosleep (rqtp, rmtp : not null access timespec) return Integer;
+ pragma Import (C, nanosleep, "nanosleep");
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ type timeval is array (1 .. 2) of time_t;
+
+ procedure timeval_to_duration
+ (T : not null access timeval;
+ sec : not null access Long_Integer;
+ usec : not null access Long_Integer);
+ pragma Import (C, timeval_to_duration, "__gnat_timeval_to_duration");
+
+ Micro : constant := 10**6;
+ sec : aliased Long_Integer;
+ usec : aliased Long_Integer;
+ TV : aliased timeval;
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ function gettimeofday
+ (Tv : access timeval;
+ Tz : System.Address := System.Null_Address) return Integer;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ begin
+ -- The return codes for gettimeofday are as follows (from man pages):
+ -- EPERM settimeofday is called by someone other than the superuser
+ -- EINVAL Timezone (or something else) is invalid
+ -- EFAULT One of tv or tz pointed outside accessible address space
+
+ -- None of these codes signal a potential clock skew, hence the return
+ -- value is never checked.
+
+ Result := gettimeofday (TV'Access, System.Null_Address);
+ timeval_to_duration (TV'Access, sec'Access, usec'Access);
+ return Duration (sec) + Duration (usec) / Micro;
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec;
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ timespec'(tv_sec => S,
+ tv_nsec => time_t (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Request : aliased timespec;
+ Remaind : aliased timespec;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Base_Time : constant Duration := Clock;
+ Check_Time : Duration := Base_Time;
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ Request := To_Timespec (Rel_Time);
+ Result := nanosleep (Request'Access, Remaind'Access);
+ Check_Time := Clock;
+
+ exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize is
+ begin
+ null;
+ end Initialize;
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-taprop-linux.adb b/gcc/ada/s-taprop-linux.adb
index 6047d312567..b8accbec021 100644
--- a/gcc/ada/s-taprop-linux.adb
+++ b/gcc/ada/s-taprop-linux.adb
@@ -627,7 +627,7 @@ package body System.Task_Primitives.Operations is
function Monotonic_Clock return Duration is
use Interfaces;
- type timeval is array (1 .. 2) of C.long;
+ type timeval is array (1 .. 2) of System.OS_Interface.time_t;
procedure timeval_to_duration
(T : not null access timeval;
diff --git a/gcc/asan.c b/gcc/asan.c
index e072ece1a12..4353db63160 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -24,6 +24,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "tree-iterator.h"
#include "cgraph.h"
#include "tree-ssanames.h"
@@ -1001,6 +1003,9 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
TREE_STATIC (decl) = 1;
TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
+ DECL_INITIAL (decl) = decl;
+ TREE_ASM_WRITTEN (decl) = 1;
+ TREE_ASM_WRITTEN (id) = 1;
emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
shadow_base = expand_binop (Pmode, lshr_optab, base,
GEN_INT (ASAN_SHADOW_SHIFT),
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 9c28f14afa4..fd1681209fb 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -1008,4 +1008,19 @@ inverse_probability (int prob1)
check_probability (prob1);
return REG_BR_PROB_BASE - prob1;
}
+
+/* Return true if BB has at least one abnormal outgoing edge. */
+
+static inline bool
+has_abnormal_or_eh_outgoing_edge_p (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
+ return true;
+
+ return false;
+}
#endif /* GCC_BASIC_BLOCK_H */
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 4ff4310e8b6..9f884b6c845 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,55 @@
+2013-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-cilkplus.c: New file.
+ * c-common.c (readonly_error): Add location argument.
+ * c-common.h (readonly_error): Same.
+ (c_finish_cilk_clauses): Protoize.
+ (c_check_cilk_loop): Same.
+ c-omp.c (c_finish_omp_for): Handle CILK_SIMD nodes.
+ Do not fail on error_mark_node.
+ Abstract increment canonicalization to here...
+ (c_omp_for_incr_canonicalize_ptr): New.
+ c-pragma.c (init_pragma): Register "simd" pragma.
+ c-pragma.h (enum pragma_kind): Add PRAGMA_CILK_SIMD.
+ (enum pragma_cilk_clause): New.
+
+2013-11-15 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * c-pretty-print.c (pp_c_character_constant): Remove unnecessary
+ wchar_type and host_integerp checks.
+
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-common.c: Likewise.
+ * c-gimplify.c: Likewise.
+ * cilk.c: Likewise.
+
+2013-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * c-common.h (enum rid): Add RID_AUTO_TYPE.
+ * c-common.c (c_common_reswords): Add __auto_type.
+ (keyword_begins_type_specifier): Handle RID_AUTO_TYPE.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-common.c: Include gimplify.h.
+ * c-gimplify.c: Likewise.
+ * cilk.c: Likewise.
+ * c-omp.c: Include gimple-expr.h instead of gimple.h.
+ * c-ubsan.c: Don't include gimple.h.
+
+2013-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * c-common.c (c_common_reswords): Add _Thread_local.
+
+2013-11-09 Joseph Myers <joseph@codesourcery.com>
+
+ * c-common.c (atomic_size_supported_p): New function.
+ (resolve_overloaded_atomic_exchange)
+ (resolve_overloaded_atomic_compare_exchange)
+ (resolve_overloaded_atomic_load, resolve_overloaded_atomic_store):
+ Use it instead of comparing size with a local list of sizes.
+
2013-11-07 Andrew MacLeod <amacleod@redhat.com>
Joseph Myers <joseph@codesourcery.com>
diff --git a/gcc/c-family/c-cilkplus.c b/gcc/c-family/c-cilkplus.c
new file mode 100644
index 00000000000..6fa979d652d
--- /dev/null
+++ b/gcc/c-family/c-cilkplus.c
@@ -0,0 +1,93 @@
+/* This file contains routines to construct and validate Cilk Plus
+ constructs within the C and C++ front ends.
+
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>.
+
+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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "c-common.h"
+
+/* Validate the body of a _Cilk_for construct or a <#pragma simd> for
+ loop.
+
+ Returns true if there were no errors, false otherwise. */
+
+bool
+c_check_cilk_loop (location_t loc, tree decl)
+{
+ if (TREE_THIS_VOLATILE (decl))
+ {
+ error_at (loc, "iteration variable cannot be volatile");
+ return false;
+ }
+ return true;
+}
+
+/* Validate and emit code for <#pragma simd> clauses. */
+
+tree
+c_finish_cilk_clauses (tree clauses)
+{
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ tree prev = clauses;
+
+ /* If a variable appears in a linear clause it cannot appear in
+ any other OMP clause. */
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
+ for (tree c2 = clauses; c2; c2 = OMP_CLAUSE_CHAIN (c2))
+ {
+ if (c == c2)
+ continue;
+ enum omp_clause_code code = OMP_CLAUSE_CODE (c2);
+
+ switch (code)
+ {
+ case OMP_CLAUSE_LINEAR:
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ case OMP_CLAUSE_REDUCTION:
+ break;
+
+ case OMP_CLAUSE_SAFELEN:
+ goto next;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (c2))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c2),
+ "variable appears in more than one clause");
+ inform (OMP_CLAUSE_LOCATION (c),
+ "other clause defined here");
+ // Remove problematic clauses.
+ OMP_CLAUSE_CHAIN (prev) = OMP_CLAUSE_CHAIN (c2);
+ }
+ next:
+ prev = c2;
+ }
+ }
+ return clauses;
+}
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d83d971c87f..5e57a20fc15 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -42,6 +42,8 @@ along with GCC; see the file COPYING3. If not see
#include "opts.h"
#include "cgraph.h"
#include "target-def.h"
+#include "gimple.h"
+#include "gimplify.h"
#include "wide-int-print.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -425,6 +427,7 @@ const struct c_common_resword c_common_reswords[] =
{ "_Static_assert", RID_STATIC_ASSERT, D_CONLY },
{ "_Noreturn", RID_NORETURN, D_CONLY },
{ "_Generic", RID_GENERIC, D_CONLY },
+ { "_Thread_local", RID_THREAD, D_CONLY },
{ "__FUNCTION__", RID_FUNCTION_NAME, 0 },
{ "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
@@ -433,6 +436,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__asm__", RID_ASM, 0 },
{ "__attribute", RID_ATTRIBUTE, 0 },
{ "__attribute__", RID_ATTRIBUTE, 0 },
+ { "__auto_type", RID_AUTO_TYPE, D_CONLY },
{ "__bases", RID_BASES, D_CXXONLY },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
{ "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY },
@@ -9793,7 +9797,7 @@ warn_for_omitted_condop (location_t location, tree cond)
how ARG was being used. */
void
-readonly_error (tree arg, enum lvalue_use use)
+readonly_error (location_t loc, tree arg, enum lvalue_use use)
{
gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
|| use == lv_asm);
@@ -9806,59 +9810,59 @@ readonly_error (tree arg, enum lvalue_use use)
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- error (READONLY_MSG (G_("assignment of member "
- "%qD in read-only object"),
- G_("increment of member "
- "%qD in read-only object"),
- G_("decrement of member "
- "%qD in read-only object"),
- G_("member %qD in read-only object "
- "used as %<asm%> output")),
- TREE_OPERAND (arg, 1));
+ error_at (loc, READONLY_MSG (G_("assignment of member "
+ "%qD in read-only object"),
+ G_("increment of member "
+ "%qD in read-only object"),
+ G_("decrement of member "
+ "%qD in read-only object"),
+ G_("member %qD in read-only object "
+ "used as %<asm%> output")),
+ TREE_OPERAND (arg, 1));
else
- error (READONLY_MSG (G_("assignment of read-only member %qD"),
- G_("increment of read-only member %qD"),
- G_("decrement of read-only member %qD"),
- G_("read-only member %qD used as %<asm%> output")),
- TREE_OPERAND (arg, 1));
+ error_at (loc, READONLY_MSG (G_("assignment of read-only member %qD"),
+ G_("increment of read-only member %qD"),
+ G_("decrement of read-only member %qD"),
+ G_("read-only member %qD used as %<asm%> output")),
+ TREE_OPERAND (arg, 1));
}
else if (TREE_CODE (arg) == VAR_DECL)
- error (READONLY_MSG (G_("assignment of read-only variable %qD"),
- G_("increment of read-only variable %qD"),
- G_("decrement of read-only variable %qD"),
- G_("read-only variable %qD used as %<asm%> output")),
- arg);
+ error_at (loc, READONLY_MSG (G_("assignment of read-only variable %qD"),
+ G_("increment of read-only variable %qD"),
+ G_("decrement of read-only variable %qD"),
+ G_("read-only variable %qD used as %<asm%> output")),
+ arg);
else if (TREE_CODE (arg) == PARM_DECL)
- error (READONLY_MSG (G_("assignment of read-only parameter %qD"),
- G_("increment of read-only parameter %qD"),
- G_("decrement of read-only parameter %qD"),
- G_("read-only parameter %qD use as %<asm%> output")),
- arg);
+ error_at (loc, READONLY_MSG (G_("assignment of read-only parameter %qD"),
+ G_("increment of read-only parameter %qD"),
+ G_("decrement of read-only parameter %qD"),
+ G_("read-only parameter %qD use as %<asm%> output")),
+ arg);
else if (TREE_CODE (arg) == RESULT_DECL)
{
gcc_assert (c_dialect_cxx ());
- error (READONLY_MSG (G_("assignment of "
- "read-only named return value %qD"),
- G_("increment of "
- "read-only named return value %qD"),
- G_("decrement of "
- "read-only named return value %qD"),
- G_("read-only named return value %qD "
- "used as %<asm%>output")),
- arg);
+ error_at (loc, READONLY_MSG (G_("assignment of "
+ "read-only named return value %qD"),
+ G_("increment of "
+ "read-only named return value %qD"),
+ G_("decrement of "
+ "read-only named return value %qD"),
+ G_("read-only named return value %qD "
+ "used as %<asm%>output")),
+ arg);
}
else if (TREE_CODE (arg) == FUNCTION_DECL)
- error (READONLY_MSG (G_("assignment of function %qD"),
- G_("increment of function %qD"),
- G_("decrement of function %qD"),
- G_("function %qD used as %<asm%> output")),
- arg);
+ error_at (loc, READONLY_MSG (G_("assignment of function %qD"),
+ G_("increment of function %qD"),
+ G_("decrement of function %qD"),
+ G_("function %qD used as %<asm%> output")),
+ arg);
else
- error (READONLY_MSG (G_("assignment of read-only location %qE"),
- G_("increment of read-only location %qE"),
- G_("decrement of read-only location %qE"),
- G_("read-only location %qE used as %<asm%> output")),
- arg);
+ error_at (loc, READONLY_MSG (G_("assignment of read-only location %qE"),
+ G_("increment of read-only location %qE"),
+ G_("decrement of read-only location %qE"),
+ G_("read-only location %qE used as %<asm%> output")),
+ arg);
}
/* Print an error message for an invalid lvalue. USE says
@@ -10384,6 +10388,27 @@ add_atomic_size_parameter (unsigned n, location_t loc, tree function,
}
+/* Return whether atomic operations for naturally aligned N-byte
+ arguments are supported, whether inline or through libatomic. */
+static bool
+atomic_size_supported_p (int n)
+{
+ switch (n)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ return true;
+
+ case 16:
+ return targetm.scalar_mode_supported_p (TImode);
+
+ default:
+ return false;
+ }
+}
+
/* This will process an __atomic_exchange function call, determine whether it
needs to be mapped to the _N variation, or turned into a library call.
LOC is the location of the builtin call.
@@ -10409,7 +10434,7 @@ resolve_overloaded_atomic_exchange (location_t loc, tree function,
}
/* If not a lock-free size, change to the library generic format. */
- if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
+ if (!atomic_size_supported_p (n))
{
*new_return = add_atomic_size_parameter (n, loc, function, params);
return true;
@@ -10474,7 +10499,7 @@ resolve_overloaded_atomic_compare_exchange (location_t loc, tree function,
}
/* If not a lock-free size, change to the library generic format. */
- if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
+ if (!atomic_size_supported_p (n))
{
/* The library generic format does not have the weak parameter, so
remove it from the param list. Since a parameter has been removed,
@@ -10550,7 +10575,7 @@ resolve_overloaded_atomic_load (location_t loc, tree function,
}
/* If not a lock-free size, change to the library generic format. */
- if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
+ if (!atomic_size_supported_p (n))
{
*new_return = add_atomic_size_parameter (n, loc, function, params);
return true;
@@ -10610,7 +10635,7 @@ resolve_overloaded_atomic_store (location_t loc, tree function,
}
/* If not a lock-free size, change to the library generic format. */
- if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
+ if (!atomic_size_supported_p (n))
{
*new_return = add_atomic_size_parameter (n, loc, function, params);
return true;
@@ -11509,6 +11534,7 @@ keyword_begins_type_specifier (enum rid keyword)
{
switch (keyword)
{
+ case RID_AUTO_TYPE:
case RID_INT:
case RID_CHAR:
case RID_FLOAT:
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 74fd59fb5ee..b931fd6d2a8 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -102,7 +102,7 @@ enum rid
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
- RID_FRACT, RID_ACCUM,
+ RID_FRACT, RID_ACCUM, RID_AUTO_TYPE,
/* C11 */
RID_ALIGNAS, RID_GENERIC,
@@ -970,7 +970,7 @@ enum lvalue_use {
lv_asm
};
-extern void readonly_error (tree, enum lvalue_use);
+extern void readonly_error (location_t, tree, enum lvalue_use);
extern void lvalue_error (location_t, enum lvalue_use);
extern void invalid_indirection_error (location_t, tree, ref_operator);
@@ -1289,6 +1289,11 @@ enum stv_conv {
extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code,
tree op0, tree op1, bool);
+/* In c-cilkplus.c */
+extern tree c_finish_cilk_clauses (tree);
+extern tree c_validate_cilk_plus_loop (tree *, int *, void *);
+extern bool c_check_cilk_loop (location_t, tree);
+
/* These #defines allow users to access different operands of the
array notation tree. */
diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
index 2a4f633ad4f..d3c304e1137 100644
--- a/gcc/c-family/c-gimplify.c
+++ b/gcc/c-family/c-gimplify.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "c-common.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-inline.h"
#include "diagnostic-core.h"
#include "langhooks.h"
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index ef2d281de51..3ccf8f91521 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "c-common.h"
#include "c-pragma.h"
-#include "gimple.h" /* For create_tmp_var_raw. */
+#include "gimple-expr.h"
#include "langhooks.h"
@@ -349,6 +349,28 @@ check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
return error_mark_node;
}
+/* If the OMP_FOR increment expression in INCR is of pointer type,
+ canonicalize it into an expression handled by gimplify_omp_for()
+ and return it. DECL is the iteration variable. */
+
+static tree
+c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
+{
+ if (POINTER_TYPE_P (TREE_TYPE (decl))
+ && TREE_OPERAND (incr, 1))
+ {
+ tree t = fold_convert_loc (loc,
+ sizetype, TREE_OPERAND (incr, 1));
+
+ if (TREE_CODE (incr) == POSTDECREMENT_EXPR
+ || TREE_CODE (incr) == PREDECREMENT_EXPR)
+ t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
+ t = fold_build_pointer_plus (decl, t);
+ incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
+ }
+ return incr;
+}
+
/* Validate and emit code for the OpenMP directive #pragma omp for.
DECLV is a vector of iteration variables, for each collapsed loop.
INITV, CONDV and INCRV are vectors containing initialization
@@ -364,6 +386,10 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
bool fail = false;
int i;
+ if (code == CILK_SIMD
+ && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
+ fail = true;
+
gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
@@ -407,8 +433,11 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
init,
NULL_TREE);
}
- gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
- gcc_assert (TREE_OPERAND (init, 0) == decl);
+ if (init != error_mark_node)
+ {
+ gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+ gcc_assert (TREE_OPERAND (init, 0) == decl);
+ }
if (cond == NULL_TREE)
{
@@ -487,7 +516,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
0))
TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
? LT_EXPR : GE_EXPR);
- else
+ else if (code != CILK_SIMD)
cond_ok = false;
}
}
@@ -523,18 +552,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
break;
incr_ok = true;
- if (POINTER_TYPE_P (TREE_TYPE (decl))
- && TREE_OPERAND (incr, 1))
- {
- tree t = fold_convert_loc (elocus,
- sizetype, TREE_OPERAND (incr, 1));
-
- if (TREE_CODE (incr) == POSTDECREMENT_EXPR
- || TREE_CODE (incr) == PREDECREMENT_EXPR)
- t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t);
- t = fold_build_pointer_plus (decl, t);
- incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
- }
+ incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
break;
case MODIFY_EXPR:
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c
index 173dbe18481..6e6ad5844e1 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -1380,6 +1380,10 @@ init_pragma (void)
omp_pragmas_simd[i].id, true, true);
}
+ if (flag_enable_cilkplus && !flag_preprocess_only)
+ cpp_register_deferred_pragma (parse_in, NULL, "simd", PRAGMA_CILK_SIMD,
+ true, false);
+
if (!flag_preprocess_only)
cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
PRAGMA_GCC_PCH_PREPROCESS, false, false);
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 705bcb472a9..5379b9e4eb8 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -52,6 +52,9 @@ typedef enum pragma_kind {
PRAGMA_OMP_THREADPRIVATE,
PRAGMA_OMP_TEAMS,
+ /* Top level clause to handle all Cilk Plus pragma simd clauses. */
+ PRAGMA_CILK_SIMD,
+
PRAGMA_GCC_PCH_PREPROCESS,
PRAGMA_IVDEP,
@@ -103,6 +106,17 @@ typedef enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_UNTIED
} pragma_omp_clause;
+/* All Cilk Plus #pragma omp clauses. */
+typedef enum pragma_cilk_clause {
+ PRAGMA_CILK_CLAUSE_NONE = 0,
+ PRAGMA_CILK_CLAUSE_VECTORLENGTH,
+ PRAGMA_CILK_CLAUSE_LINEAR,
+ PRAGMA_CILK_CLAUSE_PRIVATE,
+ PRAGMA_CILK_CLAUSE_FIRSTPRIVATE,
+ PRAGMA_CILK_CLAUSE_LASTPRIVATE,
+ PRAGMA_CILK_CLAUSE_REDUCTION
+} pragma_cilk_clause;
+
extern struct cpp_reader* parse_in;
/* It's safe to always leave visibility pragma enabled as if
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 61acb54606f..70381a0efae 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -949,14 +949,8 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i)
static void
pp_c_character_constant (c_pretty_printer *pp, tree c)
{
- tree type = TREE_TYPE (c);
- if (type == wchar_type_node)
- pp_character (pp, 'L');
pp_quote (pp);
- if (tree_fits_hwi_p (c, TYPE_SIGN (type)))
- pp_c_char (pp, tree_to_hwi (c, TYPE_SIGN (type)));
- else
- pp_scalar (pp, "\\x%x", (unsigned) tree_to_hwi (c));
+ pp_c_char (pp, (unsigned) tree_to_hwi (c));
pp_quote (pp);
}
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
index c9896381db2..dbac348bc0e 100644
--- a/gcc/c-family/c-ubsan.c
+++ b/gcc/c-family/c-ubsan.c
@@ -24,7 +24,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "alloc-pool.h"
#include "cgraph.h"
-#include "gimple.h"
#include "output.h"
#include "toplev.h"
#include "ubsan.h"
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index ea97fbdc59f..802d879749d 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "langhooks.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-iterator.h"
#include "tree-inline.h"
#include "c-family/c-common.h"
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index e38bcb8cdbd..f1b1a496185 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,57 @@
+2013-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-parser.c (c_parser_cilk_simd): New.
+ (c_parser_cilk_verify_simd): New.
+ (c_parser_pragma): Add case for PRAGMA_CILK_SIMD.
+ (c_parser_omp_for_loop): Add case for NE_EXPR.
+ Set c_break_label for CILK_SIMD.
+ (c_parser_cilk_clause_vectorlength): New.
+ (c_parser_cilk_clause_linear): New.
+ (c_parser_cilk_clause_name): New.
+ (c_parser_cilk_all_clauses): New.
+ * c-typeck.c (build_unary_op): Pass location argument to
+ readonly_error.
+ (build_modify_expr): Same.
+ (build_asm_expr): Same.
+ (c_finish_bc_stmt): Error on break/continue in loops.
+
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-typeck.c: Include only gimplify.h and gimple.h as needed.
+
+2013-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * c-tree.h (c_typespec_keyword): Add cts_auto_type.
+ * c-decl.c (declspecs_add_type, finish_declspecs): Handle
+ __auto_type.
+ * c-parser.c (c_token_starts_typename, c_token_starts_declspecs)
+ (c_parser_attribute_any_word, c_parser_objc_selector): Handle
+ RID_AUTO_TYPE.
+ (c_parser_declspecs): Take argument AUTO_TYPE_OK.
+ (c_parser_declaration_or_fndef, c_parser_struct_declaration)
+ (c_parser_declarator, c_parser_direct_declarator_inner)
+ (c_parser_parameter_declaration, c_parser_type_name): All callers
+ changed.
+ (c_parser_declaration_or_fndef): Handle declarations with type
+ determined from the initializer.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-typeck.c: Include gimplify.h.
+
+2013-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * c-tree.h (struct c_declspecs): Add thread_gnu_p field.
+ * c-parser.c (c_parser_declspecs): Mention _Thread_local in
+ comment.
+ * c-decl.c (shadow_tag_warned, grokdeclarator): Mention __thread
+ or _Thread_local as appropriate in diagnostics.
+ (build_null_declspecs): Initialize ret->thread_gnu_p.
+ (declspecs_add_scspec): Handle either __thread or _Thread_local
+ for RID_THREAD. Diagnose _Thread_local for pre-C11 standards if
+ pedantic. Do not disallow _Thread_local extern and _Thread_local
+ static.
+
2013-11-07 Joseph Myers <joseph@codesourcery.com>
Andrew MacLeod <amacleod@redhat.com>
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 4afe0f401a9..57ca8de328d 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -3805,7 +3805,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
if (!warned && !in_system_header && declspecs->thread_p)
{
- warning (0, "useless %<__thread%> in empty declaration");
+ warning (0, "useless %qs in empty declaration",
+ declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
warned = 2;
}
@@ -5164,7 +5165,8 @@ grokdeclarator (const struct c_declarator *declarator,
if (storage_class == csc_typedef)
error_at (loc, "function definition declared %<typedef%>");
if (threadp)
- error_at (loc, "function definition declared %<__thread%>");
+ error_at (loc, "function definition declared %qs",
+ declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
threadp = false;
if (storage_class == csc_auto
|| storage_class == csc_register
@@ -5233,8 +5235,8 @@ grokdeclarator (const struct c_declarator *declarator,
else if (threadp && storage_class == csc_none)
{
error_at (loc, "function-scope %qE implicitly auto and declared "
- "%<__thread%>",
- name);
+ "%qs", name,
+ declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
threadp = false;
}
}
@@ -8981,6 +8983,7 @@ build_null_declspecs (void)
ret->inline_p = false;
ret->noreturn_p = false;
ret->thread_p = false;
+ ret->thread_gnu_p = false;
ret->const_p = false;
ret->volatile_p = false;
ret->atomic_p = false;
@@ -9113,6 +9116,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<long%> and %<short%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_auto_type)
+ error_at (loc,
+ ("both %<long%> and %<__auto_type%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<long%> and %<void%> in "
@@ -9157,6 +9164,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<long%> and %<short%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_auto_type)
+ error_at (loc,
+ ("both %<short%> and %<__auto_type%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<short%> and %<void%> in "
@@ -9205,6 +9216,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<signed%> and %<unsigned%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_auto_type)
+ error_at (loc,
+ ("both %<signed%> and %<__auto_type%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<signed%> and %<void%> in "
@@ -9245,6 +9260,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<signed%> and %<unsigned%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_auto_type)
+ error_at (loc,
+ ("both %<unsigned%> and %<__auto_type%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<unsigned%> and %<void%> in "
@@ -9284,7 +9303,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
if (!flag_isoc99 && !in_system_header_at (loc))
pedwarn (loc, OPT_Wpedantic,
"ISO C90 does not support complex types");
- if (specs->typespec_word == cts_void)
+ if (specs->typespec_word == cts_auto_type)
+ error_at (loc,
+ ("both %<complex%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<complex%> and %<void%> in "
"declaration specifiers"));
@@ -9332,6 +9355,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
("both %<_Sat%> and %<__int128%> in "
"declaration specifiers"));
}
+ else if (specs->typespec_word == cts_auto_type)
+ error_at (loc,
+ ("both %<_Sat%> and %<__auto_type%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<_Sat%> and %<void%> in "
@@ -9390,7 +9417,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
else
{
/* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
- "__int128", "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */
+ "__int128", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
+ "__auto_type". */
if (specs->typespec_word != cts_none)
{
error_at (loc,
@@ -9399,6 +9427,37 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
}
switch (i)
{
+ case RID_AUTO_TYPE:
+ if (specs->long_p)
+ error_at (loc,
+ ("both %<long%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else if (specs->short_p)
+ error_at (loc,
+ ("both %<short%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else if (specs->signed_p)
+ error_at (loc,
+ ("both %<signed%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else if (specs->unsigned_p)
+ error_at (loc,
+ ("both %<unsigned%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else if (specs->complex_p)
+ error_at (loc,
+ ("both %<complex%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else if (specs->saturating_p)
+ error_at (loc,
+ ("both %<_Sat%> and %<__auto_type%> in "
+ "declaration specifiers"));
+ else
+ {
+ specs->typespec_word = cts_auto_type;
+ specs->locations[cdw_typespec] = loc;
+ }
+ return specs;
case RID_INT128:
if (int128_integer_type_node == NULL_TREE)
{
@@ -9774,14 +9833,29 @@ declspecs_add_scspec (source_location loc,
case RID_THREAD:
dupe = specs->thread_p;
if (specs->storage_class == csc_auto)
- error ("%<__thread%> used with %<auto%>");
+ error ("%qE used with %<auto%>", scspec);
else if (specs->storage_class == csc_register)
- error ("%<__thread%> used with %<register%>");
+ error ("%qE used with %<register%>", scspec);
else if (specs->storage_class == csc_typedef)
- error ("%<__thread%> used with %<typedef%>");
+ error ("%qE used with %<typedef%>", scspec);
else
{
specs->thread_p = true;
+ specs->thread_gnu_p = (strcmp (IDENTIFIER_POINTER (scspec),
+ "__thread") == 0);
+ /* A diagnostic is not required for the use of this
+ identifier in the implementation namespace; only diagnose
+ it for the C11 spelling because of existing code using
+ the other spelling. */
+ if (!flag_isoc11 && !specs->thread_gnu_p)
+ {
+ if (flag_isoc99)
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C99 does not support %qE", scspec);
+ else
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C90 does not support %qE", scspec);
+ }
specs->locations[cdw_thread] = loc;
}
break;
@@ -9791,7 +9865,7 @@ declspecs_add_scspec (source_location loc,
case RID_EXTERN:
n = csc_extern;
/* Diagnose "__thread extern". */
- if (specs->thread_p)
+ if (specs->thread_p && specs->thread_gnu_p)
error ("%<__thread%> before %<extern%>");
break;
case RID_REGISTER:
@@ -9800,7 +9874,7 @@ declspecs_add_scspec (source_location loc,
case RID_STATIC:
n = csc_static;
/* Diagnose "__thread static". */
- if (specs->thread_p)
+ if (specs->thread_p && specs->thread_gnu_p)
error ("%<__thread%> before %<static%>");
break;
case RID_TYPEDEF:
@@ -9812,7 +9886,12 @@ declspecs_add_scspec (source_location loc,
if (n != csc_none && n == specs->storage_class)
dupe = true;
if (dupe)
- error ("duplicate %qE", scspec);
+ {
+ if (i == RID_THREAD)
+ error ("duplicate %<_Thread_local%> or %<__thread%>");
+ else
+ error ("duplicate %qE", scspec);
+ }
if (n != csc_none)
{
if (specs->storage_class != csc_none && n != specs->storage_class)
@@ -9825,7 +9904,9 @@ declspecs_add_scspec (source_location loc,
specs->locations[cdw_storage_class] = loc;
if (n != csc_extern && n != csc_static && specs->thread_p)
{
- error ("%<__thread%> used with %qE", scspec);
+ error ("%qs used with %qE",
+ specs->thread_gnu_p ? "__thread" : "_Thread_local",
+ scspec);
specs->thread_p = false;
}
}
@@ -9932,6 +10013,12 @@ finish_declspecs (struct c_declspecs *specs)
/* Now compute the actual type. */
switch (specs->typespec_word)
{
+ case cts_auto_type:
+ gcc_assert (!specs->long_p && !specs->short_p
+ && !specs->signed_p && !specs->unsigned_p
+ && !specs->complex_p);
+ /* Type to be filled in later. */
+ break;
case cts_void:
gcc_assert (!specs->long_p && !specs->short_p
&& !specs->signed_p && !specs->unsigned_p
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 69030acabf4..ee4c9f7d2d4 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -501,6 +501,7 @@ c_token_starts_typename (c_token *token)
case RID_FRACT:
case RID_ACCUM:
case RID_SAT:
+ case RID_AUTO_TYPE:
return true;
default:
return false;
@@ -659,6 +660,7 @@ c_token_starts_declspecs (c_token *token)
case RID_SAT:
case RID_ALIGNAS:
case RID_ATOMIC:
+ case RID_AUTO_TYPE:
return true;
default:
return false;
@@ -1128,7 +1130,7 @@ static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
static void c_parser_static_assert_declaration_no_semi (c_parser *);
static void c_parser_static_assert_declaration (c_parser *);
static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
- bool, bool, enum c_lookahead_kind);
+ bool, bool, bool, enum c_lookahead_kind);
static struct c_typespec c_parser_enum_specifier (c_parser *);
static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
static tree c_parser_struct_declaration (c_parser *);
@@ -1235,6 +1237,9 @@ static void c_parser_objc_at_dynamic_declaration (c_parser *);
static bool c_parser_objc_diagnose_bad_element_prefix
(c_parser *, struct c_declspecs *);
+/* Cilk Plus supporting routines. */
+static void c_parser_cilk_simd (c_parser *);
+static bool c_parser_cilk_verify_simd (c_parser *, enum pragma_context);
static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
/* Parse a translation unit (C90 6.7, C99 6.9).
@@ -1499,7 +1504,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
c_parser_declspecs (parser, specs, true, true, start_attr_ok,
- true, cla_nonabstract_decl);
+ true, true, cla_nonabstract_decl);
if (parser->error)
{
c_parser_skip_to_end_of_block_or_statement (parser);
@@ -1512,9 +1517,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
return;
}
finish_declspecs (specs);
+ bool auto_type_p = specs->typespec_word == cts_auto_type;
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- if (empty_ok)
+ if (auto_type_p)
+ error_at (here, "%<__auto_type%> in empty declaration");
+ else if (empty_ok)
shadow_tag (specs);
else
{
@@ -1537,7 +1545,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
shadow_tag_warned (specs, 1);
return;
}
- else if (c_dialect_objc ())
+ else if (c_dialect_objc () && !auto_type_p)
{
/* Prefix attributes are an error on method decls. */
switch (c_parser_peek_token (parser)->type)
@@ -1640,6 +1648,14 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
+ if (auto_type_p && declarator->kind != cdk_id)
+ {
+ error_at (here,
+ "%<__auto_type%> requires a plain identifier"
+ " as declarator");
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
if (c_parser_next_token_is (parser, CPP_EQ)
|| c_parser_next_token_is (parser, CPP_COMMA)
|| c_parser_next_token_is (parser, CPP_SEMICOLON)
@@ -1667,19 +1683,72 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
struct c_expr init;
location_t init_loc;
c_parser_consume_token (parser);
- /* The declaration of the variable is in effect while
- its initializer is parsed. */
- d = start_decl (declarator, specs, true,
- chainon (postfix_attrs, all_prefix_attrs));
- if (!d)
- d = error_mark_node;
- if (omp_declare_simd_clauses.exists ())
- c_finish_omp_declare_simd (parser, d, NULL_TREE,
- omp_declare_simd_clauses);
- start_init (d, asm_name, global_bindings_p ());
- init_loc = c_parser_peek_token (parser)->location;
- init = c_parser_initializer (parser);
- finish_init ();
+ if (auto_type_p)
+ {
+ start_init (NULL_TREE, asm_name, global_bindings_p ());
+ init_loc = c_parser_peek_token (parser)->location;
+ init = c_parser_expr_no_commas (parser, NULL);
+ if (TREE_CODE (init.value) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
+ error_at (here,
+ "%<__auto_type%> used with a bit-field"
+ " initializer");
+ init = convert_lvalue_to_rvalue (init_loc, init, true, true);
+ tree init_type = TREE_TYPE (init.value);
+ /* As with typeof, remove _Atomic and const
+ qualifiers from atomic types. */
+ if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
+ init_type
+ = c_build_qualified_type (init_type,
+ (TYPE_QUALS (init_type)
+ & ~(TYPE_QUAL_ATOMIC
+ | TYPE_QUAL_CONST)));
+ bool vm_type = variably_modified_type_p (init_type,
+ NULL_TREE);
+ if (vm_type)
+ init.value = c_save_expr (init.value);
+ finish_init ();
+ specs->typespec_kind = ctsk_typeof;
+ specs->locations[cdw_typedef] = init_loc;
+ specs->typedef_p = true;
+ specs->type = init_type;
+ if (vm_type)
+ {
+ bool maybe_const = true;
+ tree type_expr = c_fully_fold (init.value, false,
+ &maybe_const);
+ specs->expr_const_operands &= maybe_const;
+ if (specs->expr)
+ specs->expr = build2 (COMPOUND_EXPR,
+ TREE_TYPE (type_expr),
+ specs->expr, type_expr);
+ else
+ specs->expr = type_expr;
+ }
+ d = start_decl (declarator, specs, true,
+ chainon (postfix_attrs, all_prefix_attrs));
+ if (!d)
+ d = error_mark_node;
+ if (omp_declare_simd_clauses.exists ())
+ c_finish_omp_declare_simd (parser, d, NULL_TREE,
+ omp_declare_simd_clauses);
+ }
+ else
+ {
+ /* The declaration of the variable is in effect while
+ its initializer is parsed. */
+ d = start_decl (declarator, specs, true,
+ chainon (postfix_attrs, all_prefix_attrs));
+ if (!d)
+ d = error_mark_node;
+ if (omp_declare_simd_clauses.exists ())
+ c_finish_omp_declare_simd (parser, d, NULL_TREE,
+ omp_declare_simd_clauses);
+ start_init (d, asm_name, global_bindings_p ());
+ init_loc = c_parser_peek_token (parser)->location;
+ init = c_parser_initializer (parser);
+ finish_init ();
+ }
if (d != error_mark_node)
{
maybe_warn_string_init (TREE_TYPE (d), init);
@@ -1689,6 +1758,14 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
else
{
+ if (auto_type_p)
+ {
+ error_at (here,
+ "%<__auto_type%> requires an initialized "
+ "data declaration");
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
tree d = start_decl (declarator, specs, false,
chainon (postfix_attrs,
all_prefix_attrs));
@@ -1728,6 +1805,14 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
if (c_parser_next_token_is (parser, CPP_COMMA))
{
+ if (auto_type_p)
+ {
+ error_at (here,
+ "%<__auto_type%> may only be used with"
+ " a single declarator");
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
c_parser_consume_token (parser);
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
all_prefix_attrs = chainon (c_parser_attributes (parser),
@@ -1757,6 +1842,13 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
return;
}
}
+ else if (auto_type_p)
+ {
+ error_at (here,
+ "%<__auto_type%> requires an initialized data declaration");
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
else if (!fndef_ok)
{
c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
@@ -1949,7 +2041,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
Storage class specifiers are accepted iff SCSPEC_OK; type
specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
accepted iff ALIGNSPEC_OK; attributes are accepted at the start
- iff START_ATTR_OK.
+ iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.
declaration-specifiers:
storage-class-specifier declaration-specifiers[opt]
@@ -1969,6 +2061,9 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
static
auto
register
+ _Thread_local
+
+ (_Thread_local is new in C11.)
C99 6.7.4:
function-specifier:
@@ -2027,6 +2122,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
type-specifier:
typeof-specifier
+ __auto_type
__int128
_Decimal32
_Decimal64
@@ -2052,7 +2148,8 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
static void
c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
bool scspec_ok, bool typespec_ok, bool start_attr_ok,
- bool alignspec_ok, enum c_lookahead_kind la)
+ bool alignspec_ok, bool auto_type_ok,
+ enum c_lookahead_kind la)
{
bool attrs_ok = start_attr_ok;
bool seen_type = specs->typespec_kind != ctsk_none;
@@ -2174,6 +2271,10 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
break;
+ case RID_AUTO_TYPE:
+ if (!auto_type_ok)
+ goto out;
+ /* Fall through. */
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
@@ -2719,7 +2820,7 @@ c_parser_struct_declaration (c_parser *parser)
of N1731.
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
c_parser_declspecs (parser, specs, false, true, true,
- true, cla_nonabstract_decl);
+ true, false, cla_nonabstract_decl);
if (parser->error)
return NULL_TREE;
if (!specs->declspecs_seen_p)
@@ -3042,7 +3143,7 @@ c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
struct c_declarator *inner;
c_parser_consume_token (parser);
c_parser_declspecs (parser, quals_attrs, false, false, true,
- false, cla_prefer_id);
+ false, false, cla_prefer_id);
inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
if (inner == NULL)
return NULL;
@@ -3198,13 +3299,13 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
dimen.original_type = NULL_TREE;
c_parser_consume_token (parser);
c_parser_declspecs (parser, quals_attrs, false, false, true,
- false, cla_prefer_id);
+ false, false, cla_prefer_id);
static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
if (static_seen)
c_parser_consume_token (parser);
if (static_seen && !quals_attrs->declspecs_seen_p)
c_parser_declspecs (parser, quals_attrs, false, false, true,
- false, cla_prefer_id);
+ false, false, cla_prefer_id);
if (!quals_attrs->declspecs_seen_p)
quals_attrs = NULL;
/* If "static" is present, there must be an array dimension.
@@ -3507,7 +3608,7 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
declspecs_add_attrs (input_location, specs, attrs);
attrs = NULL_TREE;
}
- c_parser_declspecs (parser, specs, true, true, true, true,
+ c_parser_declspecs (parser, specs, true, true, true, true, false,
cla_nonabstract_decl);
finish_declspecs (specs);
pending_xref_error ();
@@ -3640,6 +3741,7 @@ c_parser_attribute_any_word (c_parser *parser)
case RID_TRANSACTION_ATOMIC:
case RID_TRANSACTION_CANCEL:
case RID_ATOMIC:
+ case RID_AUTO_TYPE:
ok = true;
break;
default:
@@ -3818,7 +3920,7 @@ c_parser_type_name (c_parser *parser)
struct c_declarator *declarator;
struct c_type_name *ret;
bool dummy = false;
- c_parser_declspecs (parser, specs, false, true, true, false,
+ c_parser_declspecs (parser, specs, false, true, true, false, false,
cla_prefer_type);
if (!specs->declspecs_seen_p)
{
@@ -8699,6 +8801,7 @@ c_parser_objc_selector (c_parser *parser)
case RID_VOID:
case RID_BOOL:
case RID_ATOMIC:
+ case RID_AUTO_TYPE:
c_parser_consume_token (parser);
return value;
default:
@@ -9271,6 +9374,13 @@ c_parser_pragma (c_parser *parser, enum pragma_context context)
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
+ case PRAGMA_CILK_SIMD:
+ if (!c_parser_cilk_verify_simd (parser, context))
+ return false;
+ c_parser_consume_pragma (parser);
+ c_parser_cilk_simd (parser);
+ return false;
+
default:
if (id < PRAGMA_FIRST_EXTERNAL)
{
@@ -11443,6 +11553,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
case LT_EXPR:
case LE_EXPR:
break;
+ case NE_EXPR:
+ if (code == CILK_SIMD)
+ break;
+ /* FALLTHRU. */
default:
/* Can't be cond = error_mark_node, because we want to preserve
the location until c_finish_omp_for. */
@@ -11516,7 +11630,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
}
save_break = c_break_label;
- c_break_label = size_one_node;
+ if (code == CILK_SIMD)
+ c_break_label = build_int_cst (size_type_node, 2);
+ else
+ c_break_label = size_one_node;
save_cont = c_cont_label;
c_cont_label = NULL_TREE;
body = push_stmt_list ();
@@ -13211,7 +13328,252 @@ c_parser_omp_threadprivate (c_parser *parser)
c_parser_skip_to_pragma_eol (parser);
}
+
+/* Cilk Plus <#pragma simd> parsing routines. */
+
+/* Helper function for c_parser_pragma. Perform some sanity checking
+ for <#pragma simd> constructs. Returns FALSE if there was a
+ problem. */
+
+static bool
+c_parser_cilk_verify_simd (c_parser *parser,
+ enum pragma_context context)
+{
+ if (!flag_enable_cilkplus)
+ {
+ warning (0, "pragma simd ignored because -fcilkplus is not enabled");
+ c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+ return false;
+ }
+ if (context == pragma_external)
+ {
+ c_parser_error (parser,"pragma simd must be inside a function");
+ c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+ return false;
+ }
+ return true;
+}
+
+/* Cilk Plus:
+ vectorlength ( constant-expression ) */
+
+static tree
+c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses)
+{
+ /* The vectorlength clause behaves exactly like OpenMP's safelen
+ clause. Represent it in OpenMP terms. */
+ check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength");
+
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return clauses;
+
+ location_t loc = c_parser_peek_token (parser)->location;
+ tree expr = c_parser_expr_no_commas (parser, NULL).value;
+ expr = c_fully_fold (expr, false, NULL);
+
+ if (!TREE_TYPE (expr)
+ || !TREE_CONSTANT (expr)
+ || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
+ error_at (loc, "vectorlength must be an integer constant");
+ else if (exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
+ error_at (loc, "vectorlength must be a power of 2");
+ else
+ {
+ tree u = build_omp_clause (loc, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (u) = expr;
+ OMP_CLAUSE_CHAIN (u) = clauses;
+ clauses = u;
+ }
+
+ c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+ return clauses;
+}
+
+/* Cilk Plus:
+ linear ( simd-linear-variable-list )
+
+ simd-linear-variable-list:
+ simd-linear-variable
+ simd-linear-variable-list , simd-linear-variable
+
+ simd-linear-variable:
+ id-expression
+ id-expression : simd-linear-step
+
+ simd-linear-step:
+ conditional-expression */
+
+static tree
+c_parser_cilk_clause_linear (c_parser *parser, tree clauses)
+{
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return clauses;
+
+ location_t loc = c_parser_peek_token (parser)->location;
+
+ if (c_parser_next_token_is_not (parser, CPP_NAME)
+ || c_parser_peek_token (parser)->id_kind != C_ID_ID)
+ c_parser_error (parser, "expected identifier");
+
+ while (c_parser_next_token_is (parser, CPP_NAME)
+ && c_parser_peek_token (parser)->id_kind == C_ID_ID)
+ {
+ tree var = lookup_name (c_parser_peek_token (parser)->value);
+
+ if (var == NULL)
+ {
+ undeclared_variable (c_parser_peek_token (parser)->location,
+ c_parser_peek_token (parser)->value);
+ c_parser_consume_token (parser);
+ }
+ else if (var == error_mark_node)
+ c_parser_consume_token (parser);
+ else
+ {
+ tree step = integer_one_node;
+
+ /* Parse the linear step if present. */
+ if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
+ {
+ c_parser_consume_token (parser);
+ c_parser_consume_token (parser);
+
+ tree expr = c_parser_expr_no_commas (parser, NULL).value;
+ expr = c_fully_fold (expr, false, NULL);
+
+ if (TREE_TYPE (expr)
+ && INTEGRAL_TYPE_P (TREE_TYPE (expr))
+ && (TREE_CONSTANT (expr)
+ || DECL_P (expr)))
+ step = expr;
+ else
+ c_parser_error (parser,
+ "step size must be an integer constant "
+ "expression or an integer variable");
+ }
+ else
+ c_parser_consume_token (parser);
+
+ /* Use OMP_CLAUSE_LINEAR, which has the same semantics. */
+ tree u = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_DECL (u) = var;
+ OMP_CLAUSE_LINEAR_STEP (u) = step;
+ OMP_CLAUSE_CHAIN (u) = clauses;
+ clauses = u;
+ }
+
+ if (c_parser_next_token_is_not (parser, CPP_COMMA))
+ break;
+
+ c_parser_consume_token (parser);
+ }
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+ return clauses;
+}
+
+/* Returns the name of the next clause. If the clause is not
+ recognized SIMD_OMP_CLAUSE_NONE is returned and the next token is
+ not consumed. Otherwise, the appropriate pragma_simd_clause is
+ returned and the token is consumed. */
+
+static pragma_cilk_clause
+c_parser_cilk_clause_name (c_parser *parser)
+{
+ pragma_cilk_clause result;
+ c_token *token = c_parser_peek_token (parser);
+
+ if (!token->value || token->type != CPP_NAME)
+ return PRAGMA_CILK_CLAUSE_NONE;
+
+ const char *p = IDENTIFIER_POINTER (token->value);
+
+ if (!strcmp (p, "vectorlength"))
+ result = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
+ else if (!strcmp (p, "linear"))
+ result = PRAGMA_CILK_CLAUSE_LINEAR;
+ else if (!strcmp (p, "private"))
+ result = PRAGMA_CILK_CLAUSE_PRIVATE;
+ else if (!strcmp (p, "firstprivate"))
+ result = PRAGMA_CILK_CLAUSE_FIRSTPRIVATE;
+ else if (!strcmp (p, "lastprivate"))
+ result = PRAGMA_CILK_CLAUSE_LASTPRIVATE;
+ else if (!strcmp (p, "reduction"))
+ result = PRAGMA_CILK_CLAUSE_REDUCTION;
+ else
+ return PRAGMA_CILK_CLAUSE_NONE;
+
+ c_parser_consume_token (parser);
+ return result;
+}
+
+/* Parse all #<pragma simd> clauses. Return the list of clauses
+ found. */
+
+static tree
+c_parser_cilk_all_clauses (c_parser *parser)
+{
+ tree clauses = NULL;
+
+ while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+ {
+ pragma_cilk_clause c_kind;
+
+ c_kind = c_parser_cilk_clause_name (parser);
+
+ switch (c_kind)
+ {
+ case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
+ clauses = c_parser_cilk_clause_vectorlength (parser, clauses);
+ break;
+ case PRAGMA_CILK_CLAUSE_LINEAR:
+ clauses = c_parser_cilk_clause_linear (parser, clauses);
+ break;
+ case PRAGMA_CILK_CLAUSE_PRIVATE:
+ /* Use the OpenMP counterpart. */
+ clauses = c_parser_omp_clause_private (parser, clauses);
+ break;
+ case PRAGMA_CILK_CLAUSE_FIRSTPRIVATE:
+ /* Use the OpenMP counterpart. */
+ clauses = c_parser_omp_clause_firstprivate (parser, clauses);
+ break;
+ case PRAGMA_CILK_CLAUSE_LASTPRIVATE:
+ /* Use the OpenMP counterpart. */
+ clauses = c_parser_omp_clause_lastprivate (parser, clauses);
+ break;
+ case PRAGMA_CILK_CLAUSE_REDUCTION:
+ /* Use the OpenMP counterpart. */
+ clauses = c_parser_omp_clause_reduction (parser, clauses);
+ break;
+ default:
+ c_parser_error (parser, "expected %<#pragma simd%> clause");
+ goto saw_error;
+ }
+ }
+
+ saw_error:
+ c_parser_skip_to_pragma_eol (parser);
+ return c_finish_cilk_clauses (clauses);
+}
+
+/* Main entry point for parsing Cilk Plus <#pragma simd> for
+ loops. */
+static void
+c_parser_cilk_simd (c_parser *parser ATTRIBUTE_UNUSED)
+{
+ char p_name[100];
+ strcpy (p_name, "#pragma omp");
+ tree clauses = c_parser_cilk_all_clauses (parser);
+ tree block = c_begin_compound_stmt (true);
+ location_t loc = c_parser_peek_token (parser)->location;
+ c_parser_omp_for_loop (loc, parser, CILK_SIMD, clauses, NULL);
+ block = c_end_compound_stmt (loc, block, true);
+ add_stmt (block);
+}
+
/* Parse a transaction attribute (GCC Extension).
transaction-attribute:
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 8dffa9c1674..c4dfc3baf36 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -214,7 +214,8 @@ enum c_typespec_keyword {
cts_dfloat64,
cts_dfloat128,
cts_fract,
- cts_accum
+ cts_accum,
+ cts_auto_type
};
/* This enum lists all the possible declarator specifiers, storage
@@ -320,8 +321,10 @@ struct c_declspecs {
BOOL_BITFIELD inline_p : 1;
/* Whether "_Noreturn" was speciied. */
BOOL_BITFIELD noreturn_p : 1;
- /* Whether "__thread" was specified. */
+ /* Whether "__thread" or "_Thread_local" was specified. */
BOOL_BITFIELD thread_p : 1;
+ /* Whether "__thread" rather than "_Thread_local" was specified. */
+ BOOL_BITFIELD thread_gnu_p : 1;
/* Whether "const" was specified. */
BOOL_BITFIELD const_p : 1;
/* Whether "volatile" was specified. */
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 36b66898168..09f52650909 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-inline.h"
#include "omp-low.h"
#include "c-family/c-objc.h"
@@ -4055,7 +4056,7 @@ build_unary_op (location_t location,
/* Report a read-only lvalue. */
if (TYPE_READONLY (argtype))
{
- readonly_error (arg,
+ readonly_error (location, arg,
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
? lv_increment : lv_decrement));
@@ -5264,7 +5265,7 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
|| TREE_CODE (lhstype) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (lhstype)))
{
- readonly_error (lhs, lv_assign);
+ readonly_error (location, lhs, lv_assign);
return error_mark_node;
}
else if (TREE_READONLY (lhs))
@@ -8949,7 +8950,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
|| ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (output)) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
- readonly_error (output, lv_asm);
+ readonly_error (loc, output, lv_asm);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
oconstraints[i] = constraint;
@@ -9576,6 +9577,13 @@ c_finish_bc_stmt (location_t loc, tree *label_p, bool is_break)
error_at (loc, "break statement used with OpenMP for loop");
return NULL_TREE;
+ case 2:
+ if (is_break)
+ error ("break statement within %<#pragma simd%> loop body");
+ else
+ error ("continue statement within %<#pragma simd%> loop body");
+ return NULL_TREE;
+
default:
gcc_unreachable ();
}
diff --git a/gcc/calls.c b/gcc/calls.c
index c04ed32801f..4dcdb27c1c1 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -981,6 +981,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
for (i = 0; i < num_actuals; i++)
if (args[i].reg != 0 && ! args[i].pass_on_stack
+ && GET_CODE (args[i].reg) != PARALLEL
&& args[i].mode == BLKmode
&& MEM_P (args[i].value)
&& (MEM_ALIGN (args[i].value)
@@ -1325,6 +1326,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
#else
args[i].reg != 0,
#endif
+ reg_parm_stack_space,
args[i].pass_on_stack ? 0 : args[i].partial,
fndecl, args_size, &args[i].locate);
#ifdef BLOCK_REG_PADDING
@@ -3735,7 +3737,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
#else
argvec[count].reg != 0,
#endif
- 0, NULL_TREE, &args_size, &argvec[count].locate);
+ reg_parm_stack_space, 0,
+ NULL_TREE, &args_size, &argvec[count].locate);
if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0)
@@ -3822,7 +3825,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
#else
argvec[count].reg != 0,
#endif
- argvec[count].partial,
+ reg_parm_stack_space, argvec[count].partial,
NULL_TREE, &args_size, &argvec[count].locate);
args_size.constant += argvec[count].locate.size.constant;
gcc_assert (!argvec[count].locate.size.var);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index ff085bb3761..0bd4ef79bae 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -61,6 +63,14 @@ along with GCC; see the file COPYING3. If not see
#include "recog.h"
#include "output.h"
+/* Some systems use __main in a way incompatible with its use in gcc, in these
+ cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
+ give the same symbol without quotes for an alternative entry point. You
+ must define both, or neither. */
+#ifndef NAME__MAIN
+#define NAME__MAIN "__main"
+#endif
+
/* This variable holds information helping the rewriting of SSA trees
into RTL. */
struct ssaexpand SA;
@@ -1120,6 +1130,13 @@ expand_one_error_var (tree var)
static bool
defer_stack_allocation (tree var, bool toplevel)
{
+ /* Whether the variable is small enough for immediate allocation not to be
+ a problem with regard to the frame size. */
+ bool smallish
+ = (tree_to_uhwi (DECL_SIZE_UNIT (var))
+ < ((unsigned HOST_WIDE_INT)
+ PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING)));
+
/* If stack protection is enabled, *all* stack variables must be deferred,
so that we can re-order the strings to the top of the frame.
Similarly for Address Sanitizer. */
@@ -1131,8 +1148,15 @@ defer_stack_allocation (tree var, bool toplevel)
if (DECL_ALIGN (var) > MAX_SUPPORTED_STACK_ALIGNMENT)
return true;
- /* Variables in the outermost scope automatically conflict with
- every other variable. The only reason to want to defer them
+ /* When optimization is enabled, DECL_IGNORED_P variables originally scoped
+ might be detached from their block and appear at toplevel when we reach
+ here. We want to coalesce them with variables from other blocks when
+ the immediate contribution to the frame size would be noticeable. */
+ if (toplevel && optimize > 0 && DECL_IGNORED_P (var) && !smallish)
+ return true;
+
+ /* Variables declared in the outermost scope automatically conflict
+ with every other variable. The only reason to want to defer them
at all is that, after sorting, we can more efficiently pack
small variables in the stack frame. Continue to defer at -O2. */
if (toplevel && optimize < 2)
@@ -1144,10 +1168,7 @@ defer_stack_allocation (tree var, bool toplevel)
other hand, we don't want the function's stack frame size to
get completely out of hand. So we avoid adding scalars and
"small" aggregates to the list at all. */
- if (optimize == 0
- && (tree_to_uhwi (DECL_SIZE_UNIT (var))
- < ((unsigned HOST_WIDE_INT)
- PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING))))
+ if (optimize == 0 && smallish)
return false;
return true;
@@ -1603,9 +1624,15 @@ expand_used_vars (void)
replace_ssa_name_symbol (var, (tree) *slot);
}
+ /* Always allocate space for partitions based on VAR_DECLs. But for
+ those based on PARM_DECLs or RESULT_DECLs and which matter for the
+ debug info, there is no need to do so if optimization is disabled
+ because all the SSA_NAMEs based on these DECLs have been coalesced
+ into a single partition, which is thus assigned the canonical RTL
+ location of the DECLs. */
if (TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL)
expand_one_var (var, true, true);
- else
+ else if (DECL_IGNORED_P (SSA_NAME_VAR (var)) || optimize)
{
/* This is a PARM_DECL or RESULT_DECL. For those partitions that
contain the default def (representing the parm or result itself)
@@ -1661,9 +1688,11 @@ expand_used_vars (void)
else if (TREE_STATIC (var) || DECL_EXTERNAL (var))
expand_now = true;
- /* If the variable is not associated with any block, then it
- was created by the optimizers, and could be live anywhere
- in the function. */
+ /* Expand variables not associated with any block now. Those created by
+ the optimizers could be live anywhere in the function. Those that
+ could possibly have been scoped originally and detached from their
+ block will have their allocation deferred so we coalesce them with
+ others when optimization is enabled. */
else if (TREE_USED (var))
expand_now = true;
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 72441ceefe0..be0157edf67 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "pointer-set.h"
#include "ggc.h"
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index be876db354f..0fc6552746b 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "tree-ssa-loop-manip.h"
#include "dumpfile.h"
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index d6733a2af31..c7ee7eee636 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -610,7 +610,7 @@ forwarder_block_p (const_basic_block bb)
}
/* Return nonzero if we can reach target from src by falling through. */
-/* FIXME: Make this a cfg hook. */
+/* FIXME: Make this a cfg hook, the result is only valid in cfgrtl mode. */
bool
can_fallthru (basic_block src, basic_block target)
@@ -623,17 +623,21 @@ can_fallthru (basic_block src, basic_block target)
if (target == EXIT_BLOCK_PTR)
return true;
if (src->next_bb != target)
- return 0;
+ return false;
+
+ /* ??? Later we may add code to move jump tables offline. */
+ if (tablejump_p (insn, NULL, NULL))
+ return false;
+
FOR_EACH_EDGE (e, ei, src->succs)
if (e->dest == EXIT_BLOCK_PTR
&& e->flags & EDGE_FALLTHRU)
- return 0;
+ return false;
insn2 = BB_HEAD (target);
- if (insn2 && !active_insn_p (insn2))
+ if (!active_insn_p (insn2))
insn2 = next_active_insn (insn2);
- /* ??? Later we may add code to move jump tables offline. */
return next_active_insn (insn) == insn2;
}
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index dccd6db3c56..746ceca071e 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "intl.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "timevar.h"
#include "dumpfile.h"
#include "gimple-ssa.h"
@@ -540,19 +541,34 @@ cgraph_create_node (tree decl)
return node;
}
-/* Try to find a call graph node for declaration DECL and if it does not exist,
- create it. */
+/* Try to find a call graph node for declaration DECL and if it does not exist
+ or if it corresponds to an inline clone, create a new one. */
struct cgraph_node *
cgraph_get_create_node (tree decl)
{
- struct cgraph_node *node;
+ struct cgraph_node *first_clone = cgraph_get_node (decl);
- node = cgraph_get_node (decl);
- if (node)
- return node;
+ if (first_clone && !first_clone->global.inlined_to)
+ return first_clone;
- return cgraph_create_node (decl);
+ struct cgraph_node *node = cgraph_create_node (decl);
+ if (first_clone)
+ {
+ first_clone->clone_of = node;
+ node->clones = first_clone;
+ symtab_prevail_in_asm_name_hash (node);
+ symtab_insert_node_to_hashtable (node);
+ if (dump_file)
+ fprintf (dump_file, "Introduced new external node "
+ "(%s/%i) and turned into root of the clone tree.\n",
+ xstrdup (cgraph_node_name (node)), node->order);
+ }
+ else if (dump_file)
+ fprintf (dump_file, "Introduced new external node "
+ "(%s/%i).\n", xstrdup (cgraph_node_name (node)),
+ node->order);
+ return node;
}
/* Mark ALIAS as an alias to DECL. DECL_NODE is cgraph node representing
@@ -1889,6 +1905,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
if (node->profile_id)
fprintf (f, " Profile id: %i\n",
node->profile_id);
+ fprintf (f, " First run: %i\n", node->tp_first_run);
fprintf (f, " Function flags:");
if (node->count)
fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
@@ -2888,51 +2905,6 @@ verify_cgraph (void)
verify_cgraph_node (node);
}
-/* Create external decl node for DECL.
- The difference i nbetween cgraph_get_create_node and
- cgraph_get_create_real_symbol_node is that cgraph_get_create_node
- may return inline clone, while cgraph_get_create_real_symbol_node
- will create a new node in this case.
- FIXME: This function should be removed once clones are put out of decl
- hash. */
-
-struct cgraph_node *
-cgraph_get_create_real_symbol_node (tree decl)
-{
- struct cgraph_node *first_clone = cgraph_get_node (decl);
- struct cgraph_node *node;
- /* create symbol table node. even if inline clone exists, we can not take
- it as a target of non-inlined call. */
- node = cgraph_get_node (decl);
- if (node && !node->global.inlined_to)
- return node;
-
- node = cgraph_create_node (decl);
-
- /* ok, we previously inlined the function, then removed the offline copy and
- now we want it back for external call. this can happen when devirtualizing
- while inlining function called once that happens after extern inlined and
- virtuals are already removed. in this case introduce the external node
- and make it available for call. */
- if (first_clone)
- {
- first_clone->clone_of = node;
- node->clones = first_clone;
- symtab_prevail_in_asm_name_hash (node);
- symtab_insert_node_to_hashtable (node);
- if (dump_file)
- fprintf (dump_file, "Introduced new external node "
- "(%s/%i) and turned into root of the clone tree.\n",
- xstrdup (cgraph_node_name (node)), node->order);
- }
- else if (dump_file)
- fprintf (dump_file, "Introduced new external node "
- "(%s/%i).\n", xstrdup (cgraph_node_name (node)),
- node->order);
- return node;
-}
-
-
/* Given NODE, walk the alias chain to return the function NODE is alias of.
Walk through thunk, too.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 4f93713b889..1ac6dfb9e0d 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -298,6 +298,8 @@ public:
int uid;
/* ID assigned by the profiling. */
unsigned int profile_id;
+ /* Time profiler: first run of function. */
+ int tp_first_run;
/* Set when decl is an abstract function pointed to by the
ABSTRACT_DECL_ORIGIN of a reachable function. */
@@ -633,7 +635,6 @@ struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
struct cgraph_node * cgraph_create_node (tree);
struct cgraph_node * cgraph_create_empty_node (void);
struct cgraph_node * cgraph_get_create_node (tree);
-struct cgraph_node * cgraph_get_create_real_symbol_node (tree);
struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree);
struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT,
HOST_WIDE_INT, tree, tree);
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 87e06e37cbe..7834b065d52 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -24,6 +24,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "langhooks.h"
#include "pointer-set.h"
#include "intl.h"
@@ -71,7 +73,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data)
decl = get_base_var (*tp);
if (TREE_CODE (decl) == FUNCTION_DECL)
{
- struct cgraph_node *node = cgraph_get_create_real_symbol_node (decl);
+ struct cgraph_node *node = cgraph_get_create_node (decl);
if (!ctx->only_vars)
cgraph_mark_address_taken_node (node);
ipa_record_reference (ctx->varpool_node,
@@ -139,9 +141,9 @@ record_eh_tables (struct cgraph_node *node, struct function *fun)
if (DECL_FUNCTION_PERSONALITY (node->decl))
{
- struct cgraph_node *per_node;
+ tree per_decl = DECL_FUNCTION_PERSONALITY (node->decl);
+ struct cgraph_node *per_node = cgraph_get_create_node (per_decl);
- per_node = cgraph_get_create_real_symbol_node (DECL_FUNCTION_PERSONALITY (node->decl));
ipa_record_reference (node, per_node, IPA_REF_ADDR, NULL);
cgraph_mark_address_taken_node (per_node);
}
@@ -221,7 +223,7 @@ mark_address (gimple stmt, tree addr, void *data)
addr = get_base_address (addr);
if (TREE_CODE (addr) == FUNCTION_DECL)
{
- struct cgraph_node *node = cgraph_get_create_real_symbol_node (addr);
+ struct cgraph_node *node = cgraph_get_create_node (addr);
cgraph_mark_address_taken_node (node);
ipa_record_reference ((symtab_node *)data,
node,
@@ -250,7 +252,7 @@ mark_load (gimple stmt, tree t, void *data)
{
/* ??? This can happen on platforms with descriptors when these are
directly manipulated in the code. Pretend that it's an address. */
- struct cgraph_node *node = cgraph_get_create_real_symbol_node (t);
+ struct cgraph_node *node = cgraph_get_create_node (t);
cgraph_mark_address_taken_node (node);
ipa_record_reference ((symtab_node *)data,
node,
@@ -338,7 +340,7 @@ build_cgraph_edges (void)
{
tree fn = gimple_omp_parallel_child_fn (stmt);
ipa_record_reference (node,
- cgraph_get_create_real_symbol_node (fn),
+ cgraph_get_create_node (fn),
IPA_REF_ADDR, stmt);
}
if (gimple_code (stmt) == GIMPLE_OMP_TASK)
@@ -346,12 +348,12 @@ build_cgraph_edges (void)
tree fn = gimple_omp_task_child_fn (stmt);
if (fn)
ipa_record_reference (node,
- cgraph_get_create_real_symbol_node (fn),
+ cgraph_get_create_node (fn),
IPA_REF_ADDR, stmt);
fn = gimple_omp_task_copy_fn (stmt);
if (fn)
ipa_record_reference (node,
- cgraph_get_create_real_symbol_node (fn),
+ cgraph_get_create_node (fn),
IPA_REF_ADDR, stmt);
}
}
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 9bb5656fb07..f91fcfc6fd4 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -208,6 +208,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
new_node->frequency = n->frequency;
new_node->clone = n->clone;
new_node->clone.tree_map = NULL;
+ new_node->tp_first_run = n->tp_first_run;
if (n->count)
{
if (new_node->count > n->count)
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 4978d2aea1a..4ccaf8574d0 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -165,6 +165,9 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "rtl.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
diff --git a/gcc/cilk-common.c b/gcc/cilk-common.c
index 9be864d5a7e..98b85988764 100644
--- a/gcc/cilk-common.c
+++ b/gcc/cilk-common.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "recog.h"
#include "tree-iterator.h"
#include "gimple.h"
+#include "gimplify.h"
#include "cilk.h"
/* This structure holds all the important fields of the internal structures,
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 6c62a64d25d..fafa8b87e07 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3805,7 +3805,7 @@ case "${target}" in
;;
powerpc*-*-* | rs6000-*-*)
- supported_defaults="cpu cpu_32 cpu_64 float tune tune_32 tune_64"
+ supported_defaults="abi cpu cpu_32 cpu_64 float tune tune_32 tune_64"
for which in cpu cpu_32 cpu_64 tune tune_32 tune_64; do
eval "val=\$with_$which"
@@ -3842,6 +3842,16 @@ case "${target}" in
;;
esac
done
+
+ case "$with_abi" in
+ "" | elfv1 | elfv2 )
+ #OK
+ ;;
+ *)
+ echo "Unknown ABI used in --with-abi=$with_abi"
+ exit 1
+ ;;
+ esac
;;
s390*-*-*)
diff --git a/gcc/config/aarch64/aarch64-arches.def b/gcc/config/aarch64/aarch64-arches.def
index b66e33ec932..683c34c1ec4 100644
--- a/gcc/config/aarch64/aarch64-arches.def
+++ b/gcc/config/aarch64/aarch64-arches.def
@@ -26,4 +26,4 @@
this architecture. ARCH is the architecture revision. FLAGS are
the flags implied by the architecture. */
-AARCH64_ARCH("armv8-a", generic, 8, AARCH64_FL_FOR_ARCH8)
+AARCH64_ARCH("armv8-a", cortexa53, 8, AARCH64_FL_FOR_ARCH8)
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 0df5b3b0d77..2f1a8d03cb1 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -31,6 +31,7 @@
#include "diagnostic-core.h"
#include "optabs.h"
#include "gimple.h"
+#include "gimple-iterator.h"
enum aarch64_simd_builtin_type_mode
{
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index c840aa016e8..51c1ff803b0 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -35,6 +35,4 @@
therefore serves as a template for adding more CPUs in the future. */
AARCH64_CORE("cortex-a53", cortexa53, 8, AARCH64_FL_FPSIMD, generic)
-AARCH64_CORE("cortex-a57", cortexa57, 8, AARCH64_FL_FPSIMD, generic)
-AARCH64_CORE("example-1", large, 8, AARCH64_FL_FPSIMD, generic)
-AARCH64_CORE("example-2", small, 8, AARCH64_FL_FPSIMD, generic)
+AARCH64_CORE("cortex-a57", cortexa15, 8, AARCH64_FL_FPSIMD, generic)
diff --git a/gcc/config/aarch64/aarch64-generic.md b/gcc/config/aarch64/aarch64-generic.md
deleted file mode 100644
index 12faac84348..00000000000
--- a/gcc/config/aarch64/aarch64-generic.md
+++ /dev/null
@@ -1,40 +0,0 @@
-;; Machine description for AArch64 architecture.
-;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
-;; Contributed by ARM Ltd.
-;;
-;; 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/>.
-
-;; Generic scheduler
-
-(define_automaton "aarch64")
-
-(define_cpu_unit "core" "aarch64")
-
-(define_attr "is_load" "yes,no"
- (if_then_else (eq_attr "v8type" "fpsimd_load,fpsimd_load2,load1,load2")
- (const_string "yes")
- (const_string "no")))
-
-(define_insn_reservation "load" 2
- (and (eq_attr "generic_sched" "yes")
- (eq_attr "is_load" "yes"))
- "core")
-
-(define_insn_reservation "nonload" 1
- (and (eq_attr "generic_sched" "yes")
- (eq_attr "is_load" "no"))
- "core")
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index f19045d0792..489fd1cd7b5 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -108,25 +108,6 @@ enum aarch64_symbol_type
cost models and vectors for address cost calculations, register
move costs and memory move costs. */
-/* Extra costs for specific insns. Only records the cost above a
- single insn. */
-
-struct cpu_rtx_cost_table
-{
- const int memory_load;
- const int memory_store;
- const int register_shift;
- const int int_divide;
- const int float_divide;
- const int double_divide;
- const int int_multiply;
- const int int_multiply_extend;
- const int int_multiply_add;
- const int int_multiply_extend_add;
- const int float_multiply;
- const int double_multiply;
-};
-
/* Additional cost for addresses. */
struct cpu_addrcost_table
{
@@ -170,7 +151,7 @@ struct cpu_vector_cost
struct tune_params
{
- const struct cpu_rtx_cost_table *const insn_extra_cost;
+ const struct cpu_cost_table *const insn_extra_cost;
const struct cpu_addrcost_table *const addr_cost;
const struct cpu_regmove_cost *const regmove_cost;
const struct cpu_vector_cost *const vec_costs;
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index a747ee8d7ba..b9ebdf54431 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -18,226 +18,6 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
-
-; Main data types used by the insntructions
-
-(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,SF,HI,QI"
- (const_string "unknown"))
-
-
-; Classification of AdvSIMD instructions for scheduling purposes.
-; Do not set this attribute and the "v8type" attribute together in
-; any instruction pattern.
-
-; simd_abd integer absolute difference and accumulate.
-; simd_abdl integer absolute difference and accumulate (long).
-; simd_adal integer add and accumulate (long).
-; simd_add integer addition/subtraction.
-; simd_addl integer addition/subtraction (long).
-; simd_addlv across lanes integer sum (long).
-; simd_addn integer addition/subtraction (narrow).
-; simd_addn2 integer addition/subtraction (narrow, high).
-; simd_addv across lanes integer sum.
-; simd_cls count leading sign/zero bits.
-; simd_cmp compare / create mask.
-; simd_cnt population count.
-; simd_dup duplicate element.
-; simd_dupgp duplicate general purpose register.
-; simd_ext bitwise extract from pair.
-; simd_fabd floating point absolute difference.
-; simd_fadd floating point add/sub.
-; simd_fcmp floating point compare.
-; simd_fcvti floating point convert to integer.
-; simd_fcvtl floating-point convert upsize.
-; simd_fcvtn floating-point convert downsize (narrow).
-; simd_fcvtn2 floating-point convert downsize (narrow, high).
-; simd_fdiv floating point division.
-; simd_fminmax floating point min/max.
-; simd_fminmaxv across lanes floating point min/max.
-; simd_fmla floating point multiply-add.
-; simd_fmla_elt floating point multiply-add (by element).
-; simd_fmul floating point multiply.
-; simd_fmul_elt floating point multiply (by element).
-; simd_fnegabs floating point neg/abs.
-; simd_frecpe floating point reciprocal estimate.
-; simd_frecps floating point reciprocal step.
-; simd_frecpx floating point reciprocal exponent.
-; simd_frint floating point round to integer.
-; simd_fsqrt floating point square root.
-; simd_icvtf integer convert to floating point.
-; simd_ins insert element.
-; simd_insgp insert general purpose register.
-; simd_load1 load multiple structures to one register (LD1).
-; simd_load1r load single structure to all lanes of one register (LD1R).
-; simd_load1s load single structure to one lane of one register (LD1 [index]).
-; simd_load2 load multiple structures to two registers (LD1, LD2).
-; simd_load2r load single structure to all lanes of two registers (LD1R, LD2R).
-; simd_load2s load single structure to one lane of two registers (LD2 [index]).
-; simd_load3 load multiple structures to three registers (LD1, LD3).
-; simd_load3r load single structure to all lanes of three registers (LD3R).
-; simd_load3s load single structure to one lane of three registers (LD3 [index]).
-; simd_load4 load multiple structures to four registers (LD1, LD2, LD4).
-; simd_load4r load single structure to all lanes of four registers (LD4R).
-; simd_load4s load single structure to one lane of four registers (LD4 [index]).
-; simd_logic logical operation.
-; simd_logic_imm logcial operation (immediate).
-; simd_minmax integer min/max.
-; simd_minmaxv across lanes integer min/max,
-; simd_mla integer multiply-accumulate.
-; simd_mla_elt integer multiply-accumulate (by element).
-; simd_mlal integer multiply-accumulate (long).
-; simd_mlal_elt integer multiply-accumulate (by element, long).
-; simd_move move register.
-; simd_move_imm move immediate.
-; simd_movgp move element to general purpose register.
-; simd_mul integer multiply.
-; simd_mul_elt integer multiply (by element).
-; simd_mull integer multiply (long).
-; simd_mull_elt integer multiply (by element, long).
-; simd_negabs integer negate/absolute.
-; simd_rbit bitwise reverse.
-; simd_rcpe integer reciprocal estimate.
-; simd_rcps integer reciprocal square root.
-; simd_rev element reverse.
-; simd_sat_add integer saturating addition/subtraction.
-; simd_sat_mlal integer saturating multiply-accumulate (long).
-; simd_sat_mlal_elt integer saturating multiply-accumulate (by element, long).
-; simd_sat_mul integer saturating multiply.
-; simd_sat_mul_elt integer saturating multiply (by element).
-; simd_sat_mull integer saturating multiply (long).
-; simd_sat_mull_elt integer saturating multiply (by element, long).
-; simd_sat_negabs integer saturating negate/absolute.
-; simd_sat_shift integer saturating shift.
-; simd_sat_shift_imm integer saturating shift (immediate).
-; simd_sat_shiftn_imm integer saturating shift (narrow, immediate).
-; simd_sat_shiftn2_imm integer saturating shift (narrow, high, immediate).
-; simd_shift shift register/vector.
-; simd_shift_acc shift accumulate.
-; simd_shift_imm shift immediate.
-; simd_shift_imm_acc shift immediate and accumualte.
-; simd_shiftl shift register/vector (long).
-; simd_shiftl_imm shift register/vector (long, immediate).
-; simd_shiftn_imm shift register/vector (narrow, immediate).
-; simd_shiftn2_imm shift register/vector (narrow, high, immediate).
-; simd_store1 store multiple structures from one register (ST1).
-; simd_store1s store single structure from one lane of one register (ST1 [index]).
-; simd_store2 store multiple structures from two registers (ST1, ST2).
-; simd_store2s store single structure from one lane of two registers (ST2 [index]).
-; simd_store3 store multiple structures from three registers (ST1, ST3).
-; simd_store3s store single structure from one lane of three register (ST3 [index]).
-; simd_store4 store multiple structures from four registers (ST1, ST2, ST4).
-; simd_store4s store single structure from one lane for four registers (ST4 [index]).
-; simd_tbl table lookup.
-; simd_trn transpose.
-; simd_uzp unzip.
-; simd_zip zip.
-
-(define_attr "simd_type"
- "simd_abd,\
- simd_abdl,\
- simd_adal,\
- simd_add,\
- simd_addl,\
- simd_addlv,\
- simd_addn,\
- simd_addn2,\
- simd_addv,\
- simd_cls,\
- simd_cmp,\
- simd_cnt,\
- simd_dup,\
- simd_dupgp,\
- simd_ext,\
- simd_fabd,\
- simd_fadd,\
- simd_fcmp,\
- simd_fcvti,\
- simd_fcvtl,\
- simd_fcvtn,\
- simd_fcvtn2,\
- simd_fdiv,\
- simd_fminmax,\
- simd_fminmaxv,\
- simd_fmla,\
- simd_fmla_elt,\
- simd_fmul,\
- simd_fmul_elt,\
- simd_fnegabs,\
- simd_frecpe,\
- simd_frecps,\
- simd_frecpx,\
- simd_frint,\
- simd_fsqrt,\
- simd_icvtf,\
- simd_ins,\
- simd_insgp,\
- simd_load1,\
- simd_load1r,\
- simd_load1s,\
- simd_load2,\
- simd_load2r,\
- simd_load2s,\
- simd_load3,\
- simd_load3r,\
- simd_load3s,\
- simd_load4,\
- simd_load4r,\
- simd_load4s,\
- simd_logic,\
- simd_logic_imm,\
- simd_minmax,\
- simd_minmaxv,\
- simd_mla,\
- simd_mla_elt,\
- simd_mlal,\
- simd_mlal_elt,\
- simd_movgp,\
- simd_move,\
- simd_move_imm,\
- simd_mul,\
- simd_mul_elt,\
- simd_mull,\
- simd_mull_elt,\
- simd_negabs,\
- simd_rbit,\
- simd_rcpe,\
- simd_rcps,\
- simd_rev,\
- simd_sat_add,\
- simd_sat_mlal,\
- simd_sat_mlal_elt,\
- simd_sat_mul,\
- simd_sat_mul_elt,\
- simd_sat_mull,\
- simd_sat_mull_elt,\
- simd_sat_negabs,\
- simd_sat_shift,\
- simd_sat_shift_imm,\
- simd_sat_shiftn_imm,\
- simd_sat_shiftn2_imm,\
- simd_shift,\
- simd_shift_acc,\
- simd_shift_imm,\
- simd_shift_imm_acc,\
- simd_shiftl,\
- simd_shiftl_imm,\
- simd_shiftn_imm,\
- simd_shiftn2_imm,\
- simd_store1,\
- simd_store1s,\
- simd_store2,\
- simd_store2s,\
- simd_store3,\
- simd_store3s,\
- simd_store4,\
- simd_store4s,\
- simd_tbl,\
- simd_trn,\
- simd_uzp,\
- simd_zip,\
- none"
- (const_string "none"))
-
(define_expand "mov<mode>"
[(set (match_operand:VALL 0 "aarch64_simd_nonimmediate_operand" "")
(match_operand:VALL 1 "aarch64_simd_general_operand" ""))]
@@ -268,9 +48,7 @@
"@
dup\\t%0.<Vtype>, %<vw>1
dup\\t%0.<Vtype>, %1.<Vetype>[0]"
- [(set_attr "simd_type" "simd_dupgp, simd_dup")
- (set_attr "type" "neon_from_gp<q>, neon_dup<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_from_gp<q>, neon_dup<q>")]
)
(define_insn "aarch64_simd_dup<mode>"
@@ -278,9 +56,7 @@
(vec_duplicate:VDQF (match_operand:<VEL> 1 "register_operand" "w")))]
"TARGET_SIMD"
"dup\\t%0.<Vtype>, %1.<Vetype>[0]"
- [(set_attr "simd_type" "simd_dup")
- (set_attr "type" "neon_dup<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_dup<q>")]
)
(define_insn "aarch64_dup_lane<mode>"
@@ -292,9 +68,7 @@
)))]
"TARGET_SIMD"
"dup\\t%0.<Vtype>, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_dup")
- (set_attr "type" "neon_dup<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_dup<q>")]
)
(define_insn "aarch64_dup_lane_<vswap_width_name><mode>"
@@ -306,9 +80,7 @@
)))]
"TARGET_SIMD"
"dup\\t%0.<Vtype>, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_dup")
- (set_attr "type" "neon_dup<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_dup<q>")]
)
(define_insn "*aarch64_simd_mov<mode>"
@@ -334,11 +106,9 @@
default: gcc_unreachable ();
}
}
- [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm")
- (set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
+ [(set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
neon_logic<q>, neon_to_gp<q>, neon_from_gp<q>,\
- mov_reg, neon_move<q>")
- (set_attr "simd_mode" "<MODE>")]
+ mov_reg, neon_move<q>")]
)
(define_insn "*aarch64_simd_mov<mode>"
@@ -368,11 +138,9 @@
gcc_unreachable ();
}
}
- [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm")
- (set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
+ [(set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
neon_logic<q>, multiple, multiple, multiple,\
neon_move<q>")
- (set_attr "simd_mode" "<MODE>")
(set_attr "length" "4,4,4,8,8,8,4")]
)
@@ -451,9 +219,7 @@
(match_operand:VQ 2 "vect_par_cnst_lo_half" "")))]
"TARGET_SIMD && reload_completed"
"umov\t%0, %1.d[0]"
- [(set_attr "simd_type" "simd_movgp")
- (set_attr "type" "neon_to_gp<q>")
- (set_attr "simd_mode" "<MODE>")
+ [(set_attr "type" "neon_to_gp<q>")
(set_attr "length" "4")
])
@@ -464,9 +230,7 @@
(match_operand:VQ 2 "vect_par_cnst_hi_half" "")))]
"TARGET_SIMD && reload_completed"
"umov\t%0, %1.d[1]"
- [(set_attr "simd_type" "simd_movgp")
- (set_attr "type" "neon_to_gp<q>")
- (set_attr "simd_mode" "<MODE>")
+ [(set_attr "type" "neon_to_gp<q>")
(set_attr "length" "4")
])
@@ -476,9 +240,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"orn\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "type" "neon_logic<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_logic<q>")]
)
(define_insn "bic<mode>3"
@@ -487,9 +249,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"bic\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "type" "neon_logic<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_logic<q>")]
)
(define_insn "add<mode>3"
@@ -498,9 +258,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"add\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "type" "neon_add<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_add<q>")]
)
(define_insn "sub<mode>3"
@@ -509,9 +267,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"sub\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "type" "neon_sub<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sub<q>")]
)
(define_insn "mul<mode>3"
@@ -520,9 +276,7 @@
(match_operand:VDQM 2 "register_operand" "w")))]
"TARGET_SIMD"
"mul\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mul")
- (set_attr "type" "neon_mul_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mul_<Vetype><q>")]
)
(define_insn "*aarch64_mul3_elt<mode>"
@@ -535,9 +289,7 @@
(match_operand:VMUL 3 "register_operand" "w")))]
"TARGET_SIMD"
"<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_<f>mul_elt")
- (set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_mul3_elt_<vswap_width_name><mode>"
@@ -550,9 +302,7 @@
(match_operand:VMUL_CHANGE_NLANES 3 "register_operand" "w")))]
"TARGET_SIMD"
"<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_<f>mul_elt")
- (set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_mul3_elt_to_128df"
@@ -563,9 +313,7 @@
(match_operand:V2DF 1 "register_operand" "w")))]
"TARGET_SIMD"
"fmul\\t%0.2d, %1.2d, %2.d[0]"
- [(set_attr "simd_type" "simd_fmul_elt")
- (set_attr "type" "neon_fp_mul_d_scalar_q")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_mul_d_scalar_q")]
)
(define_insn "*aarch64_mul3_elt_to_64v2df"
@@ -577,9 +325,7 @@
(match_operand:DF 3 "register_operand" "w")))]
"TARGET_SIMD"
"fmul\\t%0.2d, %3.2d, %1.d[%2]"
- [(set_attr "simd_type" "simd_fmul_elt")
- (set_attr "type" "neon_fp_mul_d_scalar_q")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_mul_d_scalar_q")]
)
(define_insn "neg<mode>2"
@@ -587,9 +333,7 @@
(neg:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
"TARGET_SIMD"
"neg\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_negabs")
- (set_attr "type" "neon_neg<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_neg<q>")]
)
(define_insn "abs<mode>2"
@@ -597,9 +341,7 @@
(abs:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
"TARGET_SIMD"
"abs\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_negabs")
- (set_attr "type" "neon_abs<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_abs<q>")]
)
(define_insn "abd<mode>_3"
@@ -609,9 +351,7 @@
(match_operand:VDQ_BHSI 2 "register_operand" "w"))))]
"TARGET_SIMD"
"sabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_abd")
- (set_attr "type" "neon_abd<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_abd<q>")]
)
(define_insn "aba<mode>_3"
@@ -622,9 +362,7 @@
(match_operand:VDQ_BHSI 3 "register_operand" "0")))]
"TARGET_SIMD"
"saba\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_abd")
- (set_attr "type" "neon_arith_acc<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_arith_acc<q>")]
)
(define_insn "fabd<mode>_3"
@@ -634,9 +372,7 @@
(match_operand:VDQF 2 "register_operand" "w"))))]
"TARGET_SIMD"
"fabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fabd")
- (set_attr "type" "neon_fp_abd_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_abd_<Vetype><q>")]
)
(define_insn "*fabd_scalar<mode>3"
@@ -646,9 +382,7 @@
(match_operand:GPF 2 "register_operand" "w"))))]
"TARGET_SIMD"
"fabd\t%<s>0, %<s>1, %<s>2"
- [(set_attr "simd_type" "simd_fabd")
- (set_attr "type" "neon_fp_abd_<Vetype><q>")
- (set_attr "mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_abd_<Vetype><q>")]
)
(define_insn "and<mode>3"
@@ -657,9 +391,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "type" "neon_logic<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_logic<q>")]
)
(define_insn "ior<mode>3"
@@ -668,9 +400,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "type" "neon_logic<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_logic<q>")]
)
(define_insn "xor<mode>3"
@@ -679,9 +409,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "type" "neon_logic<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_logic<q>")]
)
(define_insn "one_cmpl<mode>2"
@@ -689,23 +417,21 @@
(not:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
"TARGET_SIMD"
"not\t%0.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "type" "neon_logic<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_logic<q>")]
)
(define_insn "aarch64_simd_vec_set<mode>"
- [(set (match_operand:VQ_S 0 "register_operand" "=w")
+ [(set (match_operand:VQ_S 0 "register_operand" "=w,w")
(vec_merge:VQ_S
(vec_duplicate:VQ_S
- (match_operand:<VEL> 1 "register_operand" "r"))
- (match_operand:VQ_S 3 "register_operand" "0")
- (match_operand:SI 2 "immediate_operand" "i")))]
+ (match_operand:<VEL> 1 "register_operand" "r,w"))
+ (match_operand:VQ_S 3 "register_operand" "0,0")
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_SIMD"
- "ins\t%0.<Vetype>[%p2], %w1";
- [(set_attr "simd_type" "simd_insgp")
- (set_attr "type" "neon_from_gp<q>")
- (set_attr "simd_mode" "<MODE>")]
+ "@
+ ins\t%0.<Vetype>[%p2], %w1
+ ins\\t%0.<Vetype>[%p2], %1.<Vetype>[0]"
+ [(set_attr "type" "neon_from_gp<q>, neon_ins<q>")]
)
(define_insn "aarch64_simd_lshr<mode>"
@@ -714,9 +440,7 @@
(match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
"TARGET_SIMD"
"ushr\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_shift_imm<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm<q>")]
)
(define_insn "aarch64_simd_ashr<mode>"
@@ -725,9 +449,7 @@
(match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
"TARGET_SIMD"
"sshr\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_shift_imm<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm<q>")]
)
(define_insn "aarch64_simd_imm_shl<mode>"
@@ -736,9 +458,7 @@
(match_operand:VDQ 2 "aarch64_simd_lshift_imm" "Dl")))]
"TARGET_SIMD"
"shl\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_shift_imm<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm<q>")]
)
(define_insn "aarch64_simd_reg_sshl<mode>"
@@ -747,9 +467,7 @@
(match_operand:VDQ 2 "register_operand" "w")))]
"TARGET_SIMD"
"sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shift")
- (set_attr "type" "neon_shift_reg<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_reg<q>")]
)
(define_insn "aarch64_simd_reg_shl<mode>_unsigned"
@@ -759,9 +477,7 @@
UNSPEC_ASHIFT_UNSIGNED))]
"TARGET_SIMD"
"ushl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shift")
- (set_attr "type" "neon_shift_reg<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_reg<q>")]
)
(define_insn "aarch64_simd_reg_shl<mode>_signed"
@@ -771,9 +487,7 @@
UNSPEC_ASHIFT_SIGNED))]
"TARGET_SIMD"
"sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shift")
- (set_attr "type" "neon_shift_reg<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_reg<q>")]
)
(define_expand "ashl<mode>3"
@@ -958,9 +672,9 @@
})
(define_expand "vec_set<mode>"
- [(match_operand:VQ_S 0 "register_operand" "+w")
- (match_operand:<VEL> 1 "register_operand" "r")
- (match_operand:SI 2 "immediate_operand" "")]
+ [(match_operand:VQ_S 0 "register_operand")
+ (match_operand:<VEL> 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
@@ -971,23 +685,23 @@
)
(define_insn "aarch64_simd_vec_setv2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
+ [(set (match_operand:V2DI 0 "register_operand" "=w,w")
(vec_merge:V2DI
(vec_duplicate:V2DI
- (match_operand:DI 1 "register_operand" "r"))
- (match_operand:V2DI 3 "register_operand" "0")
- (match_operand:SI 2 "immediate_operand" "i")))]
+ (match_operand:DI 1 "register_operand" "r,w"))
+ (match_operand:V2DI 3 "register_operand" "0,0")
+ (match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_SIMD"
- "ins\t%0.d[%p2], %1";
- [(set_attr "simd_type" "simd_insgp")
- (set_attr "type" "neon_from_gp")
- (set_attr "simd_mode" "V2DI")]
+ "@
+ ins\t%0.d[%p2], %1
+ ins\\t%0.d[%p2], %1.d[0]"
+ [(set_attr "type" "neon_from_gp, neon_ins_q")]
)
(define_expand "vec_setv2di"
- [(match_operand:V2DI 0 "register_operand" "+w")
- (match_operand:DI 1 "register_operand" "r")
- (match_operand:SI 2 "immediate_operand" "")]
+ [(match_operand:V2DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
@@ -1006,9 +720,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_SIMD"
"ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
- [(set_attr "simd_type" "simd_ins")
- (set_attr "type" "neon_ins<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_ins<q>")]
)
(define_expand "vec_set<mode>"
@@ -1032,9 +744,7 @@
(match_operand:VQ_S 1 "register_operand" "0")))]
"TARGET_SIMD"
"mla\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "type" "neon_mla_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype><q>")]
)
(define_insn "*aarch64_mla_elt<mode>"
@@ -1049,9 +759,7 @@
(match_operand:VDQHS 4 "register_operand" "0")))]
"TARGET_SIMD"
"mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "type" "neon_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_mla_elt_<vswap_width_name><mode>"
@@ -1066,9 +774,7 @@
(match_operand:VDQHS 4 "register_operand" "0")))]
"TARGET_SIMD"
"mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "type" "neon_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
)
(define_insn "aarch64_mls<mode>"
@@ -1078,9 +784,7 @@
(match_operand:VQ_S 3 "register_operand" "w"))))]
"TARGET_SIMD"
"mls\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "type" "neon_mla_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype><q>")]
)
(define_insn "*aarch64_mls_elt<mode>"
@@ -1095,9 +799,7 @@
(match_operand:VDQHS 3 "register_operand" "w"))))]
"TARGET_SIMD"
"mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "type" "neon_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_mls_elt_<vswap_width_name><mode>"
@@ -1112,9 +814,7 @@
(match_operand:VDQHS 3 "register_operand" "w"))))]
"TARGET_SIMD"
"mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "type" "neon_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
)
;; Max/Min operations.
@@ -1124,9 +824,7 @@
(match_operand:VQ_S 2 "register_operand" "w")))]
"TARGET_SIMD"
"<su><maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_minmax")
- (set_attr "type" "neon_minmax<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_minmax<q>")]
)
;; Move into low-half clearing high half to 0.
@@ -1141,10 +839,7 @@
dup\\t%d0, %1.d[0]
fmov\\t%d0, %1
dup\\t%d0, %1"
- [(set_attr "v8type" "*,fmov,*")
- (set_attr "type" "neon_dup<q>,fmov,neon_dup<q>")
- (set_attr "simd_type" "simd_dup,*,simd_dup")
- (set_attr "simd_mode" "<MODE>")
+ [(set_attr "type" "neon_dup<q>,fmov,neon_dup<q>")
(set_attr "simd" "yes,*,yes")
(set_attr "fp" "*,yes,*")
(set_attr "length" "4")]
@@ -1163,9 +858,7 @@
"@
ins\\t%0.d[1], %1.d[0]
ins\\t%0.d[1], %1"
- [(set_attr "simd_type" "simd_ins,simd_ins")
- (set_attr "type" "neon_ins")
- (set_attr "simd_mode" "<MODE>")
+ [(set_attr "type" "neon_ins")
(set_attr "length" "4")]
)
@@ -1188,9 +881,7 @@
(truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w")))]
"TARGET_SIMD"
"xtn\\t%0.<Vntype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_shiftn_imm")
- (set_attr "type" "neon_shift_imm_narrow_q")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm_narrow_q")]
)
(define_expand "vec_pack_trunc_<mode>"
@@ -1216,9 +907,7 @@
(truncate:<VNARROWQ> (match_operand:VQN 2 "register_operand" "w"))))]
"TARGET_SIMD"
"xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shiftn2_imm")
- (set_attr "type" "multiple")
- (set_attr "simd_mode" "<MODE>")
+ [(set_attr "type" "multiple")
(set_attr "length" "8")]
)
@@ -1232,9 +921,7 @@
)))]
"TARGET_SIMD"
"<su>shll %0.<Vwtype>, %1.<Vhalftype>, 0"
- [(set_attr "simd_type" "simd_shiftl_imm")
- (set_attr "type" "neon_shift_imm_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm_long")]
)
(define_insn "aarch64_simd_vec_unpack<su>_hi_<mode>"
@@ -1245,9 +932,7 @@
)))]
"TARGET_SIMD"
"<su>shll2 %0.<Vwtype>, %1.<Vtype>, 0"
- [(set_attr "simd_type" "simd_shiftl_imm")
- (set_attr "type" "neon_shift_imm_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm_long")]
)
(define_expand "vec_unpack<su>_hi_<mode>"
@@ -1289,9 +974,7 @@
(match_operand:<VWIDE> 1 "register_operand" "0")))]
"TARGET_SIMD"
"<su>mlal\t%0.<Vwtype>, %2.<Vhalftype>, %4.<Vhalftype>"
- [(set_attr "simd_type" "simd_mlal")
- (set_attr "type" "neon_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_long")]
)
(define_insn "*aarch64_<su>mlal_hi<mode>"
@@ -1307,9 +990,7 @@
(match_operand:<VWIDE> 1 "register_operand" "0")))]
"TARGET_SIMD"
"<su>mlal2\t%0.<Vwtype>, %2.<Vtype>, %4.<Vtype>"
- [(set_attr "simd_type" "simd_mlal")
- (set_attr "type" "neon_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_long")]
)
(define_insn "*aarch64_<su>mlsl_lo<mode>"
@@ -1325,9 +1006,7 @@
(match_dup 3))))))]
"TARGET_SIMD"
"<su>mlsl\t%0.<Vwtype>, %2.<Vhalftype>, %4.<Vhalftype>"
- [(set_attr "simd_type" "simd_mlal")
- (set_attr "type" "neon_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_long")]
)
(define_insn "*aarch64_<su>mlsl_hi<mode>"
@@ -1343,9 +1022,7 @@
(match_dup 3))))))]
"TARGET_SIMD"
"<su>mlsl2\t%0.<Vwtype>, %2.<Vtype>, %4.<Vtype>"
- [(set_attr "simd_type" "simd_mlal")
- (set_attr "type" "neon_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_long")]
)
(define_insn "*aarch64_<su>mlal<mode>"
@@ -1359,9 +1036,7 @@
(match_operand:<VWIDE> 3 "register_operand" "0")))]
"TARGET_SIMD"
"<su>mlal\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mlal")
- (set_attr "type" "neon_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_long")]
)
(define_insn "*aarch64_<su>mlsl<mode>"
@@ -1375,9 +1050,7 @@
(match_operand:VDW 3 "register_operand" "w")))))]
"TARGET_SIMD"
"<su>mlsl\t%0.<Vwtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_mlal")
- (set_attr "type" "neon_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mla_<Vetype>_long")]
)
(define_insn "aarch64_simd_vec_<su>mult_lo_<mode>"
@@ -1390,9 +1063,7 @@
(match_dup 3)))))]
"TARGET_SIMD"
"<su>mull\\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
- [(set_attr "simd_type" "simd_mull")
- (set_attr "type" "neon_mul_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mul_<Vetype>_long")]
)
(define_expand "vec_widen_<su>mult_lo_<mode>"
@@ -1419,9 +1090,7 @@
(match_dup 3)))))]
"TARGET_SIMD"
"<su>mull2\\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mull")
- (set_attr "type" "neon_mul_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mul_<Vetype>_long")]
)
(define_expand "vec_widen_<su>mult_hi_<mode>"
@@ -1470,9 +1139,7 @@
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
"fadd\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "type" "neon_fp_addsub_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_addsub_<Vetype><q>")]
)
(define_insn "sub<mode>3"
@@ -1481,9 +1148,7 @@
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
"fsub\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "type" "neon_fp_addsub_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_addsub_<Vetype><q>")]
)
(define_insn "mul<mode>3"
@@ -1492,9 +1157,7 @@
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
"fmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fmul")
- (set_attr "type" "neon_fp_mul_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mul_<Vetype><q>")]
)
(define_insn "div<mode>3"
@@ -1503,9 +1166,7 @@
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
"fdiv\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fdiv")
- (set_attr "type" "neon_fp_div_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_div_<Vetype><q>")]
)
(define_insn "neg<mode>2"
@@ -1513,9 +1174,7 @@
(neg:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
"TARGET_SIMD"
"fneg\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fnegabs")
- (set_attr "type" "neon_fp_neg_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_neg_<Vetype><q>")]
)
(define_insn "abs<mode>2"
@@ -1523,9 +1182,7 @@
(abs:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
"TARGET_SIMD"
"fabs\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fnegabs")
- (set_attr "type" "neon_fp_abs_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_abs_<Vetype><q>")]
)
(define_insn "fma<mode>4"
@@ -1535,9 +1192,7 @@
(match_operand:VDQF 3 "register_operand" "0")))]
"TARGET_SIMD"
"fmla\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fmla")
- (set_attr "type" "neon_fp_mla_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype><q>")]
)
(define_insn "*aarch64_fma4_elt<mode>"
@@ -1551,9 +1206,7 @@
(match_operand:VDQF 4 "register_operand" "0")))]
"TARGET_SIMD"
"fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_fma4_elt_<vswap_width_name><mode>"
@@ -1567,9 +1220,7 @@
(match_operand:VDQSF 4 "register_operand" "0")))]
"TARGET_SIMD"
"fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_fma4_elt_to_128df"
@@ -1581,9 +1232,7 @@
(match_operand:V2DF 3 "register_operand" "0")))]
"TARGET_SIMD"
"fmla\\t%0.2d, %2.2d, %1.2d[0]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_d_scalar_q")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_mla_d_scalar_q")]
)
(define_insn "*aarch64_fma4_elt_to_64v2df"
@@ -1596,9 +1245,7 @@
(match_operand:DF 4 "register_operand" "0")))]
"TARGET_SIMD"
"fmla\\t%0.2d, %3.2d, %1.2d[%2]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_d_scalar_q")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_mla_d_scalar_q")]
)
(define_insn "fnma<mode>4"
@@ -1610,9 +1257,7 @@
(match_operand:VDQF 3 "register_operand" "0")))]
"TARGET_SIMD"
"fmls\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fmla")
- (set_attr "type" "neon_fp_mla_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype><q>")]
)
(define_insn "*aarch64_fnma4_elt<mode>"
@@ -1627,9 +1272,7 @@
(match_operand:VDQF 4 "register_operand" "0")))]
"TARGET_SIMD"
"fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_fnma4_elt_<vswap_width_name><mode>"
@@ -1644,9 +1287,7 @@
(match_operand:VDQSF 4 "register_operand" "0")))]
"TARGET_SIMD"
"fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_fnma4_elt_to_128df"
@@ -1659,9 +1300,7 @@
(match_operand:V2DF 3 "register_operand" "0")))]
"TARGET_SIMD"
"fmls\\t%0.2d, %2.2d, %1.2d[0]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_d_scalar_q")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_mla_d_scalar_q")]
)
(define_insn "*aarch64_fnma4_elt_to_64v2df"
@@ -1675,9 +1314,7 @@
(match_operand:DF 4 "register_operand" "0")))]
"TARGET_SIMD"
"fmls\\t%0.2d, %3.2d, %1.2d[%2]"
- [(set_attr "simd_type" "simd_fmla_elt")
- (set_attr "type" "neon_fp_mla_d_scalar_q")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_mla_d_scalar_q")]
)
;; Vector versions of the floating-point frint patterns.
@@ -1688,9 +1325,7 @@
FRINT))]
"TARGET_SIMD"
"frint<frint_suffix>\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_frint")
- (set_attr "type" "neon_fp_round_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_round_<Vetype><q>")]
)
;; Vector versions of the fcvt standard patterns.
@@ -1702,9 +1337,7 @@
FCVT)))]
"TARGET_SIMD"
"fcvt<frint_suffix><su>\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fcvti")
- (set_attr "type" "neon_fp_to_int_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_to_int_<Vetype><q>")]
)
(define_expand "<optab><VDQF:mode><fcvt_target>2"
@@ -1736,9 +1369,7 @@
(match_operand:<FCVT_TARGET> 1 "register_operand" "w")))]
"TARGET_SIMD"
"<su_optab>cvtf\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_icvtf")
- (set_attr "type" "neon_int_to_fp_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_int_to_fp_<Vetype><q>")]
)
;; Conversions between vectors of floats and doubles.
@@ -1756,9 +1387,7 @@
)))]
"TARGET_SIMD"
"fcvtl\\t%0.2d, %1.2s"
- [(set_attr "simd_type" "simd_fcvtl")
- (set_attr "type" "neon_fp_cvt_widen_s")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_cvt_widen_s")]
)
(define_insn "aarch64_float_extend_lo_v2df"
@@ -1767,9 +1396,7 @@
(match_operand:V2SF 1 "register_operand" "w")))]
"TARGET_SIMD"
"fcvtl\\t%0.2d, %1.2s"
- [(set_attr "simd_type" "simd_fcvtl")
- (set_attr "type" "neon_fp_cvt_widen_s")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_cvt_widen_s")]
)
(define_insn "vec_unpacks_hi_v4sf"
@@ -1781,9 +1408,7 @@
)))]
"TARGET_SIMD"
"fcvtl2\\t%0.2d, %1.4s"
- [(set_attr "simd_type" "simd_fcvtl")
- (set_attr "type" "neon_fp_cvt_widen_s")
- (set_attr "simd_mode" "V2DF")]
+ [(set_attr "type" "neon_fp_cvt_widen_s")]
)
;; Float narrowing operations.
@@ -1794,9 +1419,7 @@
(match_operand:V2DF 1 "register_operand" "w")))]
"TARGET_SIMD"
"fcvtn\\t%0.2s, %1.2d"
- [(set_attr "simd_type" "simd_fcvtl")
- (set_attr "type" "neon_fp_cvt_narrow_d_q")
- (set_attr "simd_mode" "V2SF")]
+ [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
)
(define_insn "aarch64_float_truncate_hi_v4sf"
@@ -1807,9 +1430,7 @@
(match_operand:V2DF 2 "register_operand" "w"))))]
"TARGET_SIMD"
"fcvtn2\\t%0.4s, %2.2d"
- [(set_attr "simd_type" "simd_fcvtl")
- (set_attr "type" "neon_fp_cvt_narrow_d_q")
- (set_attr "simd_mode" "V4SF")]
+ [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
)
(define_expand "vec_pack_trunc_v2df"
@@ -1855,9 +1476,7 @@
(match_operand:VDQF 3 "register_operand" "w"))))]
"TARGET_SIMD"
"fmls\\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_fmla")
- (set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
;; FP Max/Min
@@ -1880,9 +1499,7 @@
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
"f<maxmin>nm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "type" "neon_fp_minmax_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_minmax_<Vetype><q>")]
)
(define_insn "<maxmin_uns><mode>3"
@@ -1892,9 +1509,7 @@
FMAXMIN_UNS))]
"TARGET_SIMD"
"<maxmin_uns_op>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "type" "neon_fp_minmax_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_minmax_<Vetype><q>")]
)
;; 'across lanes' add.
@@ -1905,9 +1520,7 @@
SUADDV))]
"TARGET_SIMD"
"addv\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_addv")
- (set_attr "type" "neon_reduc_add<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_reduc_add<q>")]
)
(define_insn "reduc_<sur>plus_v2di"
@@ -1916,9 +1529,7 @@
SUADDV))]
"TARGET_SIMD"
"addp\\t%d0, %1.2d"
- [(set_attr "simd_type" "simd_addv")
- (set_attr "type" "neon_reduc_add_q")
- (set_attr "simd_mode" "V2DI")]
+ [(set_attr "type" "neon_reduc_add_q")]
)
(define_insn "reduc_<sur>plus_v2si"
@@ -1927,9 +1538,7 @@
SUADDV))]
"TARGET_SIMD"
"addp\\t%0.2s, %1.2s, %1.2s"
- [(set_attr "simd_type" "simd_addv")
- (set_attr "type" "neon_reduc_add")
- (set_attr "simd_mode" "V2SI")]
+ [(set_attr "type" "neon_reduc_add")]
)
(define_insn "reduc_<sur>plus_<mode>"
@@ -1938,9 +1547,7 @@
SUADDV))]
"TARGET_SIMD"
"faddp\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "type" "neon_fp_reduc_add_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
)
(define_insn "aarch64_addpv4sf"
@@ -1949,9 +1556,7 @@
UNSPEC_FADDV))]
"TARGET_SIMD"
"faddp\\t%0.4s, %1.4s, %1.4s"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "type" "neon_fp_reduc_add_s_q")
- (set_attr "simd_mode" "V4SF")]
+ [(set_attr "type" "neon_fp_reduc_add_s_q")]
)
(define_expand "reduc_<sur>plus_v4sf"
@@ -1971,9 +1576,7 @@
(clz:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))]
"TARGET_SIMD"
"clz\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_cls")
- (set_attr "type" "neon_cls<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_cls<q>")]
)
;; 'across lanes' max and min ops.
@@ -1984,9 +1587,7 @@
MAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_minmaxv")
- (set_attr "type" "neon_reduc_minmax<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_reduc_minmax<q>")]
)
(define_insn "reduc_<maxmin_uns>_v2di"
@@ -1995,9 +1596,7 @@
MAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op>p\\t%d0, %1.2d"
- [(set_attr "simd_type" "simd_minmaxv")
- (set_attr "type" "neon_reduc_minmax_q")
- (set_attr "simd_mode" "V2DI")]
+ [(set_attr "type" "neon_reduc_minmax_q")]
)
(define_insn "reduc_<maxmin_uns>_v2si"
@@ -2006,9 +1605,7 @@
MAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op>p\\t%0.2s, %1.2s, %1.2s"
- [(set_attr "simd_type" "simd_minmaxv")
- (set_attr "type" "neon_reduc_minmax")
- (set_attr "simd_mode" "V2SI")]
+ [(set_attr "type" "neon_reduc_minmax")]
)
(define_insn "reduc_<maxmin_uns>_<mode>"
@@ -2017,9 +1614,7 @@
FMAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op>p\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fminmaxv")
- (set_attr "type" "neon_fp_reduc_minmax_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_reduc_minmax_<Vetype><q>")]
)
(define_insn "reduc_<maxmin_uns>_v4sf"
@@ -2028,9 +1623,7 @@
FMAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op>v\\t%s0, %1.4s"
- [(set_attr "simd_type" "simd_fminmaxv")
- (set_attr "type" "neon_fp_reduc_minmax_s_q")
- (set_attr "simd_mode" "V4SF")]
+ [(set_attr "type" "neon_fp_reduc_minmax_s_q")]
)
;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
@@ -2065,8 +1658,7 @@
bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_mode" "<MODE>")
- (set_attr "type" "neon_bsl<q>")]
+ [(set_attr "type" "neon_bsl<q>")]
)
(define_expand "aarch64_simd_bsl<mode>"
@@ -2431,9 +2023,7 @@
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
"smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]"
- [(set_attr "simd_type" "simd_movgp")
- (set_attr "type" "neon_to_gp<q>")
- (set_attr "simd_mode" "<VDQQH:MODE>")]
+ [(set_attr "type" "neon_to_gp<q>")]
)
(define_insn "*aarch64_get_lane_zero_extendsi<mode>"
@@ -2444,9 +2034,7 @@
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
"umov\\t%w0, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_movgp")
- (set_attr "type" "neon_to_gp<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_to_gp<q>")]
)
;; Lane extraction of a value, neither sign nor zero extension
@@ -2460,9 +2048,7 @@
"@
umov\\t%<vwcore>0, %1.<Vetype>[%2]
dup\\t%<Vetype>0, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_movgp, simd_dup")
- (set_attr "type" "neon_to_gp<q>, neon_dup<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_to_gp<q>, neon_dup<q>")]
)
(define_expand "aarch64_get_lanedi"
@@ -2585,9 +2171,7 @@
(match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")))]
"TARGET_SIMD"
"mov\\t%0.8b, %1.8b"
- [(set_attr "simd_type" "simd_move")
- (set_attr "type" "neon_move<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_move<q>")]
)
(define_insn_and_split "aarch64_combine<mode>"
@@ -2630,9 +2214,7 @@
(match_dup 3)))))]
"TARGET_SIMD"
"<ANY_EXTEND:su><ADDSUB:optab>l2\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "type" "neon_<ADDSUB:optab>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<ADDSUB:optab>_long")]
)
(define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_lo_internal"
@@ -2645,9 +2227,7 @@
(match_dup 3)))))]
"TARGET_SIMD"
"<ANY_EXTEND:su><ADDSUB:optab>l\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "type" "neon_<ADDSUB:optab>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<ADDSUB:optab>_long")]
)
@@ -2707,9 +2287,7 @@
(match_operand:VDW 2 "register_operand" "w"))))]
"TARGET_SIMD"
"<ANY_EXTEND:su><ADDSUB:optab>l %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "type" "neon_<ADDSUB:optab>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<ADDSUB:optab>_long")]
)
;; <su><addsub>w<q>.
@@ -2721,9 +2299,7 @@
(match_operand:VDW 2 "register_operand" "w"))))]
"TARGET_SIMD"
"<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "type" "neon_<ADDSUB:optab>_widen")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
)
(define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w2<mode>_internal"
@@ -2735,9 +2311,7 @@
(match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))]
"TARGET_SIMD"
"<ANY_EXTEND:su><ADDSUB:optab>w2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "type" "neon_<ADDSUB:optab>_widen")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
)
(define_expand "aarch64_saddw2<mode>"
@@ -2798,9 +2372,7 @@
HADDSUB))]
"TARGET_SIMD"
"<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "type" "neon_<addsub>_halve<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<addsub>_halve<q>")]
)
;; <r><addsub>hn<q>.
@@ -2812,9 +2384,7 @@
ADDSUBHN))]
"TARGET_SIMD"
"<sur><addsub>hn\\t%0.<Vntype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addn")
- (set_attr "type" "neon_<addsub>_halve_narrow_q")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
)
(define_insn "aarch64_<sur><addsub>hn2<mode>"
@@ -2825,9 +2395,7 @@
ADDSUBHN2))]
"TARGET_SIMD"
"<sur><addsub>hn2\\t%0.<V2ntype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_addn2")
- (set_attr "type" "neon_<addsub>_halve_narrow_q")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
)
;; pmul.
@@ -2839,9 +2407,7 @@
UNSPEC_PMUL))]
"TARGET_SIMD"
"pmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mul")
- (set_attr "type" "neon_mul_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_mul_<Vetype><q>")]
)
;; <su>q<addsub>
@@ -2852,9 +2418,7 @@
(match_operand:VSDQ_I 2 "register_operand" "w")))]
"TARGET_SIMD"
"<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "type" "neon_<optab><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<optab><q>")]
)
;; suqadd and usqadd
@@ -2866,9 +2430,7 @@
USSUQADD))]
"TARGET_SIMD"
"<sur>qadd\\t%<v>0<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_add")
- (set_attr "type" "neon_qadd<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_qadd<q>")]
)
;; sqmovun
@@ -2879,9 +2441,7 @@
UNSPEC_SQXTUN))]
"TARGET_SIMD"
"sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
- [(set_attr "simd_type" "simd_sat_shiftn_imm")
- (set_attr "type" "neon_sat_shift_imm_narrow_q")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
)
;; sqmovn and uqmovn
@@ -2892,9 +2452,7 @@
SUQMOVN))]
"TARGET_SIMD"
"<sur>qxtn\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
- [(set_attr "simd_type" "simd_sat_shiftn_imm")
- (set_attr "type" "neon_sat_shift_imm_narrow_q")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
)
;; <su>q<absneg>
@@ -2905,9 +2463,7 @@
(match_operand:VSDQ_I_BHSI 1 "register_operand" "w")))]
"TARGET_SIMD"
"s<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
- [(set_attr "simd_type" "simd_sat_negabs")
- (set_attr "type" "neon_<optab><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_<optab><q>")]
)
;; sq<r>dmulh.
@@ -2920,9 +2476,7 @@
VQDMULH))]
"TARGET_SIMD"
"sq<r>dmulh\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype><q>")]
)
;; sq<r>dmulh_lane
@@ -2939,9 +2493,7 @@
"*
aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
)
(define_insn "aarch64_sq<r>dmulh_laneq<mode>"
@@ -2956,9 +2508,7 @@
"*
aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
)
(define_insn "aarch64_sq<r>dmulh_lane<mode>"
@@ -2973,9 +2523,7 @@
"*
aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
)
;; vqdml[sa]l
@@ -2993,9 +2541,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_long")]
)
;; vqdml[sa]l_lane
@@ -3017,9 +2563,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
)
(define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
@@ -3038,9 +2582,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmlal_lane<mode>"
@@ -3119,9 +2661,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
)
;; sqdml[as]l2
@@ -3143,9 +2683,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmlal2<mode>"
@@ -3195,9 +2733,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmlal2_lane<mode>"
@@ -3280,9 +2816,7 @@
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmlal2_n<mode>"
@@ -3326,9 +2860,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_long")]
)
;; vqdmull_lane
@@ -3348,9 +2880,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
)
(define_insn "aarch64_sqdmull_lane<mode>_internal"
@@ -3367,9 +2897,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmull_lane<mode>"
@@ -3413,9 +2941,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
)
;; vqdmull2
@@ -3438,9 +2964,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmull2<mode>"
@@ -3474,9 +2998,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmull2_lane<mode>"
@@ -3526,9 +3048,7 @@
(const_int 1)))]
"TARGET_SIMD"
"sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
)
(define_expand "aarch64_sqdmull2_n<mode>"
@@ -3553,9 +3073,7 @@
VSHL))]
"TARGET_SIMD"
"<sur>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
- [(set_attr "simd_type" "simd_shift")
- (set_attr "type" "neon_shift_reg<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_reg<q>")]
)
@@ -3569,9 +3087,7 @@
VQSHL))]
"TARGET_SIMD"
"<sur>q<r>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
- [(set_attr "simd_type" "simd_sat_shift")
- (set_attr "type" "neon_sat_shift_reg<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_shift_reg<q>")]
)
;; vshll_n
@@ -3592,9 +3108,7 @@
else {
return \"<sur>shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
}"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_shift_imm_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm_long")]
)
;; vshll_high_n
@@ -3615,9 +3129,7 @@
else {
return \"<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
}"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_shift_imm_long")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm_long")]
)
;; vrshr_n
@@ -3632,9 +3144,7 @@
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
return \"<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_sat_shift_imm<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_shift_imm<q>")]
)
;; v(r)sra_n
@@ -3650,9 +3160,7 @@
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
aarch64_simd_const_bounds (operands[3], 1, bit_width + 1);
return \"<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
- [(set_attr "simd_type" "simd_shift_imm_acc")
- (set_attr "type" "neon_shift_acc<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_acc<q>")]
)
;; vs<lr>i_n
@@ -3669,9 +3177,7 @@
aarch64_simd_const_bounds (operands[3], 1 - <VSLRI:offsetlr>,
bit_width - <VSLRI:offsetlr> + 1);
return \"s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "type" "neon_shift_imm<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_shift_imm<q>")]
)
;; vqshl(u)
@@ -3686,9 +3192,7 @@
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
aarch64_simd_const_bounds (operands[2], 0, bit_width);
return \"<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
- [(set_attr "simd_type" "simd_sat_shift_imm")
- (set_attr "type" "neon_sat_shift_imm<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_shift_imm<q>")]
)
@@ -3704,9 +3208,7 @@
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
return \"<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2\";"
- [(set_attr "simd_type" "simd_sat_shiftn_imm")
- (set_attr "type" "neon_sat_shift_imm_narrow_q")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
)
@@ -3725,9 +3227,7 @@
"@
cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
cm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "type" "neon_compare<q>, neon_compare_zero<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_compare<q>, neon_compare_zero<q>")]
)
(define_insn_and_split "aarch64_cm<optab>di"
@@ -3756,9 +3256,7 @@
emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
DONE;
}
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "type" "neon_compare, neon_compare_zero, multiple")
- (set_attr "simd_mode" "DI")]
+ [(set_attr "type" "neon_compare, neon_compare_zero, multiple")]
)
;; cm(hs|hi)
@@ -3772,9 +3270,7 @@
)))]
"TARGET_SIMD"
"cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "type" "neon_compare<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_compare<q>")]
)
(define_insn_and_split "aarch64_cm<optab>di"
@@ -3802,9 +3298,7 @@
emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
DONE;
}
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "type" "neon_compare, neon_compare_zero")
- (set_attr "simd_mode" "DI")]
+ [(set_attr "type" "neon_compare, neon_compare_zero")]
)
;; cmtst
@@ -3819,9 +3313,7 @@
(vec_duplicate:<V_cmp_result> (const_int 0)))))]
"TARGET_SIMD"
"cmtst\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "type" "neon_tst<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_tst<q>")]
)
(define_insn_and_split "aarch64_cmtstdi"
@@ -3851,9 +3343,7 @@
emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
DONE;
}
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "type" "neon_tst")
- (set_attr "simd_mode" "DI")]
+ [(set_attr "type" "neon_tst")]
)
;; fcm(eq|ge|gt|le|lt)
@@ -3869,9 +3359,7 @@
"@
fcm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
fcm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
- [(set_attr "simd_type" "simd_fcmp")
- (set_attr "type" "neon_fp_compare_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_compare_<Vetype><q>")]
)
;; fac(ge|gt)
@@ -3887,9 +3375,7 @@
)))]
"TARGET_SIMD"
"fac<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
- [(set_attr "simd_type" "simd_fcmp")
- (set_attr "type" "neon_fp_compare_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_compare_<Vetype><q>")]
)
;; addp
@@ -3902,9 +3388,7 @@
UNSPEC_ADDP))]
"TARGET_SIMD"
"addp\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "type" "neon_reduc_add<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_reduc_add<q>")]
)
(define_insn "aarch64_addpdi"
@@ -3914,9 +3398,7 @@
UNSPEC_ADDP))]
"TARGET_SIMD"
"addp\t%d0, %1.2d"
- [(set_attr "simd_type" "simd_add")
- (set_attr "type" "neon_reduc_add")
- (set_attr "simd_mode" "DI")]
+ [(set_attr "type" "neon_reduc_add")]
)
;; sqrt
@@ -3926,9 +3408,7 @@
(sqrt:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
"TARGET_SIMD"
"fsqrt\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fsqrt")
- (set_attr "type" "neon_fp_sqrt_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_sqrt_<Vetype><q>")]
)
;; Patterns for vector struct loads and stores.
@@ -3940,9 +3420,8 @@
UNSPEC_LD2))]
"TARGET_SIMD"
"ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load2")
- (set_attr "type" "neon_load2_2reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load2_2reg<q>")]
+)
(define_insn "vec_store_lanesoi<mode>"
[(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -3951,9 +3430,8 @@
UNSPEC_ST2))]
"TARGET_SIMD"
"st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store2")
- (set_attr "type" "neon_store2_2reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store2_2reg<q>")]
+)
(define_insn "vec_load_lanesci<mode>"
[(set (match_operand:CI 0 "register_operand" "=w")
@@ -3962,9 +3440,8 @@
UNSPEC_LD3))]
"TARGET_SIMD"
"ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load3")
- (set_attr "type" "neon_load3_3reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load3_3reg<q>")]
+)
(define_insn "vec_store_lanesci<mode>"
[(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -3973,9 +3450,8 @@
UNSPEC_ST3))]
"TARGET_SIMD"
"st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store3")
- (set_attr "type" "neon_store3_3reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store3_3reg<q>")]
+)
(define_insn "vec_load_lanesxi<mode>"
[(set (match_operand:XI 0 "register_operand" "=w")
@@ -3984,9 +3460,8 @@
UNSPEC_LD4))]
"TARGET_SIMD"
"ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load4")
- (set_attr "type" "neon_load4_4reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load4_4reg<q>")]
+)
(define_insn "vec_store_lanesxi<mode>"
[(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -3995,9 +3470,8 @@
UNSPEC_ST4))]
"TARGET_SIMD"
"st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store4")
- (set_attr "type" "neon_store4_4reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store4_4reg<q>")]
+)
;; Reload patterns for AdvSIMD register list operands.
@@ -4029,11 +3503,10 @@
default: gcc_unreachable ();
}
}
- [(set_attr "simd_type" "simd_move,simd_store<nregs>,simd_load<nregs>")
- (set_attr "type" "neon_move,neon_store<nregs>_<nregs>reg_q,\
+ [(set_attr "type" "neon_move,neon_store<nregs>_<nregs>reg_q,\
neon_load<nregs>_<nregs>reg_q")
- (set (attr "length") (symbol_ref "aarch64_simd_attr_length_move (insn)"))
- (set_attr "simd_mode" "<MODE>")])
+ (set (attr "length") (symbol_ref "aarch64_simd_attr_length_move (insn)"))]
+)
(define_split
[(set (match_operand:OI 0 "register_operand" "")
@@ -4115,9 +3588,8 @@
(vec_duplicate:VD (const_int 0)))) 0))]
"TARGET_SIMD"
"ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load2")
- (set_attr "type" "neon_load2_2reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load2_2reg<q>")]
+)
(define_insn "aarch64_ld2<mode>_dreg"
[(set (match_operand:OI 0 "register_operand" "=w")
@@ -4133,9 +3605,8 @@
(const_int 0))) 0))]
"TARGET_SIMD"
"ld1\\t{%S0.1d - %T0.1d}, %1"
- [(set_attr "simd_type" "simd_load2")
- (set_attr "type" "neon_load1_2reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load1_2reg<q>")]
+)
(define_insn "aarch64_ld3<mode>_dreg"
[(set (match_operand:CI 0 "register_operand" "=w")
@@ -4156,9 +3627,8 @@
(vec_duplicate:VD (const_int 0)))) 0))]
"TARGET_SIMD"
"ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load3")
- (set_attr "type" "neon_load3_3reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load3_3reg<q>")]
+)
(define_insn "aarch64_ld3<mode>_dreg"
[(set (match_operand:CI 0 "register_operand" "=w")
@@ -4179,9 +3649,8 @@
(const_int 0))) 0))]
"TARGET_SIMD"
"ld1\\t{%S0.1d - %U0.1d}, %1"
- [(set_attr "simd_type" "simd_load3")
- (set_attr "type" "neon_load1_3reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load1_3reg<q>")]
+)
(define_insn "aarch64_ld4<mode>_dreg"
[(set (match_operand:XI 0 "register_operand" "=w")
@@ -4207,9 +3676,8 @@
(vec_duplicate:VD (const_int 0))))) 0))]
"TARGET_SIMD"
"ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load4")
- (set_attr "type" "neon_load4_4reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load4_4reg<q>")]
+)
(define_insn "aarch64_ld4<mode>_dreg"
[(set (match_operand:XI 0 "register_operand" "=w")
@@ -4235,9 +3703,8 @@
(const_int 0)))) 0))]
"TARGET_SIMD"
"ld1\\t{%S0.1d - %V0.1d}, %1"
- [(set_attr "simd_type" "simd_load4")
- (set_attr "type" "neon_load1_4reg<q>")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load1_4reg<q>")]
+)
(define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
[(match_operand:VSTRUCT 0 "register_operand" "=w")
@@ -4351,9 +3818,7 @@
UNSPEC_TBL))]
"TARGET_SIMD"
"tbl\\t%0.<Vtype>, {%1.16b}, %2.<Vtype>"
- [(set_attr "simd_type" "simd_tbl")
- (set_attr "type" "neon_tbl1<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_tbl1<q>")]
)
;; Two source registers.
@@ -4365,9 +3830,7 @@
UNSPEC_TBL))]
"TARGET_SIMD"
"tbl\\t%0.16b, {%S1.16b - %T1.16b}, %2.16b"
- [(set_attr "simd_type" "simd_tbl")
- (set_attr "type" "neon_tbl2_q")
- (set_attr "simd_mode" "V16QI")]
+ [(set_attr "type" "neon_tbl2_q")]
)
(define_insn_and_split "aarch64_combinev16qi"
@@ -4393,9 +3856,7 @@
PERMUTE))]
"TARGET_SIMD"
"<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_<PERMUTE:perm_insn>")
- (set_attr "type" "neon_permute<q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_permute<q>")]
)
(define_insn "aarch64_st2<mode>_dreg"
@@ -4405,9 +3866,8 @@
UNSPEC_ST2))]
"TARGET_SIMD"
"st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store2")
- (set_attr "type" "neon_store2_2reg")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store2_2reg")]
+)
(define_insn "aarch64_st2<mode>_dreg"
[(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -4416,9 +3876,8 @@
UNSPEC_ST2))]
"TARGET_SIMD"
"st1\\t{%S1.1d - %T1.1d}, %0"
- [(set_attr "simd_type" "simd_store2")
- (set_attr "type" "neon_store1_2reg")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store1_2reg")]
+)
(define_insn "aarch64_st3<mode>_dreg"
[(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -4427,9 +3886,8 @@
UNSPEC_ST3))]
"TARGET_SIMD"
"st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store3")
- (set_attr "type" "neon_store3_3reg")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store3_3reg")]
+)
(define_insn "aarch64_st3<mode>_dreg"
[(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -4438,9 +3896,8 @@
UNSPEC_ST3))]
"TARGET_SIMD"
"st1\\t{%S1.1d - %U1.1d}, %0"
- [(set_attr "simd_type" "simd_store3")
- (set_attr "type" "neon_store1_3reg")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store1_3reg")]
+)
(define_insn "aarch64_st4<mode>_dreg"
[(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -4449,9 +3906,8 @@
UNSPEC_ST4))]
"TARGET_SIMD"
"st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store4")
- (set_attr "type" "neon_store4_4reg")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store4_4reg")]
+)
(define_insn "aarch64_st4<mode>_dreg"
[(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
@@ -4460,9 +3916,8 @@
UNSPEC_ST4))]
"TARGET_SIMD"
"st1\\t{%S1.1d - %V1.1d}, %0"
- [(set_attr "simd_type" "simd_store4")
- (set_attr "type" "neon_store1_4reg")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_store1_4reg")]
+)
(define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
[(match_operand:DI 0 "register_operand" "r")
@@ -4540,9 +3995,8 @@
(match_operand:<VEL> 1 "aarch64_simd_struct_operand" "Utv")))]
"TARGET_SIMD"
"ld1r\\t{%0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load1r")
- (set_attr "type" "neon_load1_all_lanes")
- (set_attr "simd_mode" "<MODE>")])
+ [(set_attr "type" "neon_load1_all_lanes")]
+)
(define_insn "aarch64_frecpe<mode>"
[(set (match_operand:VDQF 0 "register_operand" "=w")
@@ -4550,9 +4004,7 @@
UNSPEC_FRECPE))]
"TARGET_SIMD"
"frecpe\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_frecpe")
- (set_attr "type" "neon_fp_recpe_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_recpe_<Vetype><q>")]
)
(define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
@@ -4561,9 +4013,7 @@
FRECP))]
"TARGET_SIMD"
"frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
- [(set_attr "simd_type" "simd_frecp<FRECP:frecp_suffix>")
- (set_attr "type" "neon_fp_recp<FRECP:frecp_suffix>_<GPF:Vetype><GPF:q>")
- (set_attr "mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_recp<FRECP:frecp_suffix>_<GPF:Vetype><GPF:q>")]
)
(define_insn "aarch64_frecps<mode>"
@@ -4573,8 +4023,21 @@
UNSPEC_FRECPS))]
"TARGET_SIMD"
"frecps\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_frecps")
- (set_attr "type" "neon_fp_recps_<Vetype><q>")
- (set_attr "simd_mode" "<MODE>")]
+ [(set_attr "type" "neon_fp_recps_<Vetype><q>")]
+)
+
+;; Standard pattern name vec_extract<mode>.
+
+(define_insn "vec_extract<mode>"
+ [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
+ (vec_select:<VEL>
+ (match_operand:VALL 1 "register_operand" "w, w, w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i,i,i")])))]
+ "TARGET_SIMD"
+ "@
+ umov\\t%<vw>0, %1.<Vetype>[%2]
+ dup\\t%<Vetype>0, %1.<Vetype>[%2]
+ st1\\t{%1.<Vetype>}[%2], %0"
+ [(set_attr "type" "neon_to_gp<q>, neon_dup<q>, neon_store1_one_lane<q>")]
)
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index 02699e35c3f..84081d1ba57 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa53,cortexa57,large,small"
+ "cortexa53,cortexa15"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index ab8c9097537..f9eb975a559 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -43,10 +43,12 @@
#include "langhooks.h"
#include "diagnostic-core.h"
#include "gimple.h"
+#include "gimplify.h"
#include "optabs.h"
#include "dwarf2.h"
#include "cfgloop.h"
#include "tree-vectorizer.h"
+#include "config/arm/aarch-cost-tables.h"
/* Defined for convenience. */
#define POINTER_BYTES (POINTER_SIZE / BITS_PER_UNIT)
@@ -127,7 +129,7 @@ static bool aarch64_vectorize_vec_perm_const_ok (enum machine_mode vmode,
const unsigned char *sel);
/* The processor for which instructions should be scheduled. */
-enum aarch64_processor aarch64_tune = generic;
+enum aarch64_processor aarch64_tune = cortexa53;
/* The current tuning set. */
const struct tune_params *aarch64_tune_params;
@@ -149,21 +151,6 @@ unsigned long aarch64_tune_flags = 0;
#if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007
__extension__
#endif
-static const struct cpu_rtx_cost_table generic_rtx_cost_table =
-{
- NAMED_PARAM (memory_load, COSTS_N_INSNS (1)),
- NAMED_PARAM (memory_store, COSTS_N_INSNS (0)),
- NAMED_PARAM (register_shift, COSTS_N_INSNS (1)),
- NAMED_PARAM (int_divide, COSTS_N_INSNS (6)),
- NAMED_PARAM (float_divide, COSTS_N_INSNS (2)),
- NAMED_PARAM (double_divide, COSTS_N_INSNS (6)),
- NAMED_PARAM (int_multiply, COSTS_N_INSNS (1)),
- NAMED_PARAM (int_multiply_extend, COSTS_N_INSNS (1)),
- NAMED_PARAM (int_multiply_add, COSTS_N_INSNS (1)),
- NAMED_PARAM (int_multiply_extend_add, COSTS_N_INSNS (1)),
- NAMED_PARAM (float_multiply, COSTS_N_INSNS (0)),
- NAMED_PARAM (double_multiply, COSTS_N_INSNS (1))
-};
#if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007
__extension__
@@ -216,7 +203,7 @@ __extension__
#endif
static const struct tune_params generic_tunings =
{
- &generic_rtx_cost_table,
+ &generic_extra_costs,
&generic_addrcost_table,
&generic_regmove_cost,
&generic_vector_cost,
@@ -240,7 +227,7 @@ static const struct processor all_cores[] =
{NAME, IDENT, #ARCH, FLAGS | AARCH64_FL_FOR_ARCH##ARCH, &COSTS##_tunings},
#include "aarch64-cores.def"
#undef AARCH64_CORE
- {"generic", generic, "8", AARCH64_FL_FPSIMD | AARCH64_FL_FOR_ARCH8, &generic_tunings},
+ {"generic", cortexa53, "8", AARCH64_FL_FPSIMD | AARCH64_FL_FOR_ARCH8, &generic_tunings},
{NULL, aarch64_none, NULL, 0, NULL}
};
@@ -251,7 +238,6 @@ static const struct processor all_architectures[] =
{NAME, CORE, #ARCH, FLAGS, NULL},
#include "aarch64-arches.def"
#undef AARCH64_ARCH
- {"generic", generic, "8", AARCH64_FL_FOR_ARCH8, NULL},
{NULL, aarch64_none, NULL, 0, NULL}
};
@@ -2010,7 +1996,7 @@ aarch64_save_or_restore_callee_save_registers (HOST_WIDE_INT offset,
Establish the stack frame by decreasing the stack pointer with a
properly calculated size and, if necessary, create a frame record
filled with the values of LR and previous frame pointer. The
- current FP is also set up is it is in use. */
+ current FP is also set up if it is in use. */
void
aarch64_expand_prologue (void)
@@ -4143,7 +4129,7 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
return offset - crtl->outgoing_args_size;
if (from == FRAME_POINTER_REGNUM)
- return cfun->machine->frame.saved_regs_size;
+ return cfun->machine->frame.saved_regs_size + get_frame_size ();
}
if (to == STACK_POINTER_REGNUM)
@@ -4152,6 +4138,7 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
{
HOST_WIDE_INT elim = crtl->outgoing_args_size
+ cfun->machine->frame.saved_regs_size
+ + get_frame_size ()
- cfun->machine->frame.fp_lr_offset;
elim = AARCH64_ROUND_UP (elim, STACK_BOUNDARY / BITS_PER_UNIT);
return elim;
@@ -4490,7 +4477,7 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
int param ATTRIBUTE_UNUSED, int *cost, bool speed)
{
rtx op0, op1;
- const struct cpu_rtx_cost_table *extra_cost
+ const struct cpu_cost_table *extra_cost
= aarch64_tune_params->insn_extra_cost;
switch (code)
@@ -4503,7 +4490,7 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
{
case MEM:
if (speed)
- *cost += extra_cost->memory_store;
+ *cost += extra_cost->ldst.store;
if (op1 != const0_rtx)
*cost += rtx_cost (op1, SET, 1, speed);
@@ -4540,7 +4527,7 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
case MEM:
if (speed)
- *cost += extra_cost->memory_load;
+ *cost += extra_cost->ldst.load;
return true;
@@ -4626,7 +4613,8 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
speed)
+ rtx_cost (op1, PLUS, 1, speed));
if (speed)
- *cost += extra_cost->int_multiply_extend_add;
+ *cost +=
+ extra_cost->mult[GET_MODE (x) == DImode].extend_add;
return true;
}
*cost += (rtx_cost (XEXP (op0, 0), MULT, 0, speed)
@@ -4634,7 +4622,7 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
+ rtx_cost (op1, PLUS, 1, speed));
if (speed)
- *cost += extra_cost->int_multiply_add;
+ *cost += extra_cost->mult[GET_MODE (x) == DImode].add;
}
*cost += (rtx_cost (new_op0, PLUS, 0, speed)
@@ -4700,7 +4688,7 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
/* Shifting by a register often takes an extra cycle. */
if (speed && !CONST_INT_P (XEXP (x, 1)))
- *cost += extra_cost->register_shift;
+ *cost += extra_cost->alu.arith_shift_reg;
*cost += rtx_cost (XEXP (x, 0), ASHIFT, 0, speed);
return true;
@@ -4743,19 +4731,19 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
*cost += (rtx_cost (XEXP (op0, 0), MULT, 0, speed)
+ rtx_cost (XEXP (op1, 0), MULT, 1, speed));
if (speed)
- *cost += extra_cost->int_multiply_extend;
+ *cost += extra_cost->mult[GET_MODE (x) == DImode].extend;
return true;
}
if (speed)
- *cost += extra_cost->int_multiply;
+ *cost += extra_cost->mult[GET_MODE (x) == DImode].simple;
}
else if (speed)
{
if (GET_MODE (x) == DFmode)
- *cost += extra_cost->double_multiply;
+ *cost += extra_cost->fp[1].mult;
else if (GET_MODE (x) == SFmode)
- *cost += extra_cost->float_multiply;
+ *cost += extra_cost->fp[0].mult;
}
return false; /* All arguments need to be in registers. */
@@ -4766,14 +4754,14 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
if (speed)
{
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
- *cost += (extra_cost->int_multiply_add
- + extra_cost->int_divide);
+ *cost += (extra_cost->mult[GET_MODE (x) == DImode].add
+ + extra_cost->mult[GET_MODE (x) == DImode].idiv);
else if (GET_MODE (x) == DFmode)
- *cost += (extra_cost->double_multiply
- + extra_cost->double_divide);
+ *cost += (extra_cost->fp[1].mult
+ + extra_cost->fp[1].div);
else if (GET_MODE (x) == SFmode)
- *cost += (extra_cost->float_multiply
- + extra_cost->float_divide);
+ *cost += (extra_cost->fp[0].mult
+ + extra_cost->fp[0].div);
}
return false; /* All arguments need to be in registers. */
@@ -4783,11 +4771,11 @@ aarch64_rtx_costs (rtx x, int code, int outer ATTRIBUTE_UNUSED,
if (speed)
{
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
- *cost += extra_cost->int_divide;
+ *cost += extra_cost->mult[GET_MODE (x) == DImode].idiv;
else if (GET_MODE (x) == DFmode)
- *cost += extra_cost->double_divide;
+ *cost += extra_cost->fp[1].div;
else if (GET_MODE (x) == SFmode)
- *cost += extra_cost->float_divide;
+ *cost += extra_cost->fp[0].div;
}
return false; /* All arguments need to be in registers. */
@@ -5183,7 +5171,7 @@ aarch64_override_options (void)
/* If the user did not specify a processor, choose the default
one for them. This will be the CPU set during configuration using
- --with-cpu, otherwise it is "generic". */
+ --with-cpu, otherwise it is "coretex-a53". */
if (!selected_cpu)
{
selected_cpu = &all_cores[TARGET_CPU_DEFAULT & 0x3f];
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 7a80e96385f..8b55a7bb7b5 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -443,7 +443,7 @@ enum reg_class
#define INDEX_REG_CLASS CORE_REGS
#define BASE_REG_CLASS POINTER_REGS
-/* Register pairs used to eliminate unneeded registers that point intoi
+/* Register pairs used to eliminate unneeded registers that point into
the stack frame. */
#define ELIMINABLE_REGS \
{ \
@@ -468,10 +468,10 @@ enum target_cpus
TARGET_CPU_generic
};
-/* If there is no CPU defined at configure, use "generic" as default. */
+/* If there is no CPU defined at configure, use "cortex-a53" as default. */
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT \
- (TARGET_CPU_generic | (AARCH64_CPU_DEFAULT_FLAGS << 6))
+ (TARGET_CPU_cortexa53 | (AARCH64_CPU_DEFAULT_FLAGS << 6))
#endif
/* The processor for which instructions should be scheduled. */
@@ -484,7 +484,7 @@ extern enum aarch64_processor aarch64_tune;
/* Stack layout; function entry, exit and calling. */
#define STACK_GROWS_DOWNWARD 1
-#define FRAME_GROWS_DOWNWARD 0
+#define FRAME_GROWS_DOWNWARD 1
#define STARTING_FRAME_OFFSET 0
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 758be47420e..47f3eb3f653 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -312,15 +312,13 @@
(define_attr "generic_sched" "yes,no"
(const (if_then_else
- (eq_attr "tune" "large,small,cortexa53")
+ (eq_attr "tune" "cortexa53,cortexa15")
(const_string "no")
(const_string "yes"))))
;; Scheduling
-(include "aarch64-generic.md")
-(include "large.md")
-(include "small.md")
(include "../arm/cortex-a53.md")
+(include "../arm/cortex-a15.md")
;; -------------------------------------------------------------------
;; Jumps and other miscellaneous insns
@@ -795,11 +793,10 @@
}
}
[(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
- (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,*,*,*")
- (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
+ (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
+ neon_from_gp<q>,neon_from_gp<q>, neon_dup")
(set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
- (set_attr "mode" "<MODE>")
- (set_attr "simd_mode" "<MODE>")]
+ (set_attr "mode" "<MODE>")]
)
(define_expand "mov<mode>"
@@ -914,13 +911,13 @@
str\\t%q1, %0"
[(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
load2,store2,store2,fpsimd_load,fpsimd_store")
- (set_attr "type" "multiple,f_mcr,f_mrc,*, \
+ (set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
load2,store2,store2,f_loadd,f_stored")
- (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
(set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
(set_attr "length" "8,8,8,4,4,4,4,4,4")
- (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
- (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
+ (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
+ (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
+)
;; Split a TImode register-register or register-immediate move into
;; its component DImode pieces, taking care to handle overlapping
@@ -2121,11 +2118,9 @@
neg\\t%<w>0, %<w>1
neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
[(set_attr "v8type" "alu")
- (set_attr "type" "alu_reg")
- (set_attr "simd_type" "*,simd_negabs")
+ (set_attr "type" "alu_reg, neon_neg<q>")
(set_attr "simd" "*,yes")
- (set_attr "mode" "<MODE>")
- (set_attr "simd_mode" "<MODE>")]
+ (set_attr "mode" "<MODE>")]
)
;; zero_extend version of above
@@ -3205,10 +3200,8 @@
ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
lsl\t%<w>0, %<w>1, %<w>2"
[(set_attr "simd" "yes,yes,no")
- (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
- (set_attr "simd_mode" "<MODE>,<MODE>,*")
(set_attr "v8type" "*,*,shift")
- (set_attr "type" "*,*,shift_reg")
+ (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")
(set_attr "mode" "*,*,<MODE>")]
)
@@ -3224,10 +3217,8 @@
#
lsr\t%<w>0, %<w>1, %<w>2"
[(set_attr "simd" "yes,yes,no")
- (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
- (set_attr "simd_mode" "<MODE>,<MODE>,*")
(set_attr "v8type" "*,*,shift")
- (set_attr "type" "*,*,shift_reg")
+ (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")
(set_attr "mode" "*,*,<MODE>")]
)
@@ -3269,10 +3260,8 @@
#
asr\t%<w>0, %<w>1, %<w>2"
[(set_attr "simd" "yes,yes,no")
- (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
- (set_attr "simd_mode" "<MODE>,<MODE>,*")
(set_attr "v8type" "*,*,shift")
- (set_attr "type" "*,*,shift_reg")
+ (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")
(set_attr "mode" "*,*,<MODE>")]
)
@@ -3310,8 +3299,7 @@
"TARGET_SIMD"
"ushl\t%d0, %d1, %d2"
[(set_attr "simd" "yes")
- (set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "DI")]
+ (set_attr "type" "neon_shift_reg")]
)
(define_insn "*aarch64_ushl_2s"
@@ -3322,8 +3310,7 @@
"TARGET_SIMD"
"ushl\t%0.2s, %1.2s, %2.2s"
[(set_attr "simd" "yes")
- (set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "DI")]
+ (set_attr "type" "neon_shift_reg")]
)
(define_insn "*aarch64_sisd_sshl"
@@ -3334,8 +3321,7 @@
"TARGET_SIMD"
"sshl\t%d0, %d1, %d2"
[(set_attr "simd" "yes")
- (set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "DI")]
+ (set_attr "type" "neon_shift_reg")]
)
(define_insn "*aarch64_sshl_2s"
@@ -3346,8 +3332,7 @@
"TARGET_SIMD"
"sshl\t%0.2s, %1.2s, %2.2s"
[(set_attr "simd" "yes")
- (set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "DI")]
+ (set_attr "type" "neon_shift_reg")]
)
(define_insn "*aarch64_sisd_neg_qi"
@@ -3357,8 +3342,7 @@
"TARGET_SIMD"
"neg\t%d0, %d1"
[(set_attr "simd" "yes")
- (set_attr "simd_type" "simd_negabs")
- (set_attr "simd_mode" "QI")]
+ (set_attr "type" "neon_neg")]
)
;; Rotate right
diff --git a/gcc/config/aarch64/large.md b/gcc/config/aarch64/large.md
deleted file mode 100644
index 4316cc7dfaf..00000000000
--- a/gcc/config/aarch64/large.md
+++ /dev/null
@@ -1,312 +0,0 @@
-;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
-;;
-;; Contributed by ARM Ltd.
-;;
-;; 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/>.
-
-;; In the absence of any ARMv8-A implementations, two examples derived
-;; from ARM's most recent ARMv7-A cores (Cortex-A7 and Cortex-A15) are
-;; included by way of example. This is a temporary measure.
-
-;; Example pipeline description for an example 'large' core
-;; implementing AArch64
-
-;;-------------------------------------------------------
-;; General Description
-;;-------------------------------------------------------
-
-(define_automaton "large_cpu")
-
-;; The core is modelled as a triple issue pipeline that has
-;; the following dispatch units.
-;; 1. Two pipelines for simple integer operations: int1, int2
-;; 2. Two pipelines for SIMD and FP data-processing operations: fpsimd1, fpsimd2
-;; 3. One pipeline for branch operations: br
-;; 4. One pipeline for integer multiply and divide operations: multdiv
-;; 5. Two pipelines for load and store operations: ls1, ls2
-;;
-;; We can issue into three pipelines per-cycle.
-;;
-;; We assume that where we have unit pairs xxx1 is always filled before xxx2.
-
-;;-------------------------------------------------------
-;; CPU Units and Reservations
-;;-------------------------------------------------------
-
-;; The three issue units
-(define_cpu_unit "large_cpu_unit_i1, large_cpu_unit_i2, large_cpu_unit_i3" "large_cpu")
-
-(define_reservation "large_cpu_resv_i1"
- "(large_cpu_unit_i1 | large_cpu_unit_i2 | large_cpu_unit_i3)")
-
-(define_reservation "large_cpu_resv_i2"
- "((large_cpu_unit_i1 + large_cpu_unit_i2) | (large_cpu_unit_i2 + large_cpu_unit_i3))")
-
-(define_reservation "large_cpu_resv_i3"
- "(large_cpu_unit_i1 + large_cpu_unit_i2 + large_cpu_unit_i3)")
-
-(final_presence_set "large_cpu_unit_i2" "large_cpu_unit_i1")
-(final_presence_set "large_cpu_unit_i3" "large_cpu_unit_i2")
-
-;; The main dispatch units
-(define_cpu_unit "large_cpu_unit_int1, large_cpu_unit_int2" "large_cpu")
-(define_cpu_unit "large_cpu_unit_fpsimd1, large_cpu_unit_fpsimd2" "large_cpu")
-(define_cpu_unit "large_cpu_unit_ls1, large_cpu_unit_ls2" "large_cpu")
-(define_cpu_unit "large_cpu_unit_br" "large_cpu")
-(define_cpu_unit "large_cpu_unit_multdiv" "large_cpu")
-
-(define_reservation "large_cpu_resv_ls" "(large_cpu_unit_ls1 | large_cpu_unit_ls2)")
-
-;; The extended load-store pipeline
-(define_cpu_unit "large_cpu_unit_load, large_cpu_unit_store" "large_cpu")
-
-;; The extended ALU pipeline
-(define_cpu_unit "large_cpu_unit_int1_alu, large_cpu_unit_int2_alu" "large_cpu")
-(define_cpu_unit "large_cpu_unit_int1_shf, large_cpu_unit_int2_shf" "large_cpu")
-(define_cpu_unit "large_cpu_unit_int1_sat, large_cpu_unit_int2_sat" "large_cpu")
-
-
-;;-------------------------------------------------------
-;; Simple ALU Instructions
-;;-------------------------------------------------------
-
-;; Simple ALU operations without shift
-(define_insn_reservation "large_cpu_alu" 2
- (and (eq_attr "tune" "large") (eq_attr "v8type" "adc,alu,alu_ext"))
- "large_cpu_resv_i1, \
- (large_cpu_unit_int1, large_cpu_unit_int1_alu) |\
- (large_cpu_unit_int2, large_cpu_unit_int2_alu)")
-
-(define_insn_reservation "large_cpu_logic" 2
- (and (eq_attr "tune" "large") (eq_attr "v8type" "logic,logic_imm"))
- "large_cpu_resv_i1, \
- (large_cpu_unit_int1, large_cpu_unit_int1_alu) |\
- (large_cpu_unit_int2, large_cpu_unit_int2_alu)")
-
-(define_insn_reservation "large_cpu_shift" 2
- (and (eq_attr "tune" "large") (eq_attr "v8type" "shift,shift_imm"))
- "large_cpu_resv_i1, \
- (large_cpu_unit_int1, large_cpu_unit_int1_shf) |\
- (large_cpu_unit_int2, large_cpu_unit_int2_shf)")
-
-;; Simple ALU operations with immediate shift
-(define_insn_reservation "large_cpu_alu_shift" 3
- (and (eq_attr "tune" "large") (eq_attr "v8type" "alu_shift"))
- "large_cpu_resv_i1, \
- (large_cpu_unit_int1,
- large_cpu_unit_int1 + large_cpu_unit_int1_shf, large_cpu_unit_int1_alu) | \
- (large_cpu_unit_int2,
- large_cpu_unit_int2 + large_cpu_unit_int2_shf, large_cpu_unit_int2_alu)")
-
-(define_insn_reservation "large_cpu_logic_shift" 3
- (and (eq_attr "tune" "large") (eq_attr "v8type" "logic_shift"))
- "large_cpu_resv_i1, \
- (large_cpu_unit_int1, large_cpu_unit_int1_alu) |\
- (large_cpu_unit_int2, large_cpu_unit_int2_alu)")
-
-
-;;-------------------------------------------------------
-;; Multiplication/Division
-;;-------------------------------------------------------
-
-;; Simple multiplication
-(define_insn_reservation "large_cpu_mult_single" 3
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "mult,madd") (eq_attr "mode" "SI")))
- "large_cpu_resv_i1, large_cpu_unit_multdiv")
-
-(define_insn_reservation "large_cpu_mult_double" 4
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "mult,madd") (eq_attr "mode" "DI")))
- "large_cpu_resv_i1, large_cpu_unit_multdiv")
-
-;; 64-bit multiplication
-(define_insn_reservation "large_cpu_mull" 4
- (and (eq_attr "tune" "large") (eq_attr "v8type" "mull,mulh,maddl"))
- "large_cpu_resv_i1, large_cpu_unit_multdiv * 2")
-
-;; Division
-(define_insn_reservation "large_cpu_udiv_single" 9
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "udiv") (eq_attr "mode" "SI")))
- "large_cpu_resv_i1, large_cpu_unit_multdiv")
-
-(define_insn_reservation "large_cpu_udiv_double" 18
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "udiv") (eq_attr "mode" "DI")))
- "large_cpu_resv_i1, large_cpu_unit_multdiv")
-
-(define_insn_reservation "large_cpu_sdiv_single" 10
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "sdiv") (eq_attr "mode" "SI")))
- "large_cpu_resv_i1, large_cpu_unit_multdiv")
-
-(define_insn_reservation "large_cpu_sdiv_double" 20
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "sdiv") (eq_attr "mode" "DI")))
- "large_cpu_resv_i1, large_cpu_unit_multdiv")
-
-
-;;-------------------------------------------------------
-;; Branches
-;;-------------------------------------------------------
-
-;; Branches take one issue slot.
-;; No latency as there is no result
-(define_insn_reservation "large_cpu_branch" 0
- (and (eq_attr "tune" "large") (eq_attr "v8type" "branch"))
- "large_cpu_resv_i1, large_cpu_unit_br")
-
-
-;; Calls 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 "large_cpu_call" 1
- (and (eq_attr "tune" "large") (eq_attr "v8type" "call"))
- "large_cpu_resv_i3 | large_cpu_resv_i2, \
- large_cpu_unit_int1 + large_cpu_unit_int2 + large_cpu_unit_br + \
- large_cpu_unit_multdiv + large_cpu_unit_fpsimd1 + large_cpu_unit_fpsimd2 + \
- large_cpu_unit_ls1 + large_cpu_unit_ls2,\
- large_cpu_unit_int1_alu + large_cpu_unit_int1_shf + large_cpu_unit_int1_sat + \
- large_cpu_unit_int2_alu + large_cpu_unit_int2_shf + \
- large_cpu_unit_int2_sat + large_cpu_unit_load + large_cpu_unit_store")
-
-
-;;-------------------------------------------------------
-;; Load/Store Instructions
-;;-------------------------------------------------------
-
-;; Loads of up to two words.
-(define_insn_reservation "large_cpu_load1" 4
- (and (eq_attr "tune" "large") (eq_attr "v8type" "load_acq,load1,load2"))
- "large_cpu_resv_i1, large_cpu_resv_ls, large_cpu_unit_load, nothing")
-
-;; Stores of up to two words.
-(define_insn_reservation "large_cpu_store1" 0
- (and (eq_attr "tune" "large") (eq_attr "v8type" "store_rel,store1,store2"))
- "large_cpu_resv_i1, large_cpu_resv_ls, large_cpu_unit_store")
-
-
-;;-------------------------------------------------------
-;; Floating-point arithmetic.
-;;-------------------------------------------------------
-
-(define_insn_reservation "large_cpu_fpalu" 4
- (and (eq_attr "tune" "large")
- (eq_attr "v8type" "ffarith,fadd,fccmp,fcvt,fcmp"))
- "large_cpu_resv_i1 + large_cpu_unit_fpsimd1")
-
-(define_insn_reservation "large_cpu_fconst" 3
- (and (eq_attr "tune" "large")
- (eq_attr "v8type" "fconst"))
- "large_cpu_resv_i1 + large_cpu_unit_fpsimd1")
-
-(define_insn_reservation "large_cpu_fpmuls" 4
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fmul,fmadd") (eq_attr "mode" "SF")))
- "large_cpu_resv_i1 + large_cpu_unit_fpsimd1")
-
-(define_insn_reservation "large_cpu_fpmuld" 7
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fmul,fmadd") (eq_attr "mode" "DF")))
- "large_cpu_resv_i1 + large_cpu_unit_fpsimd1, large_cpu_unit_fpsimd1 * 2,\
- large_cpu_resv_i1 + large_cpu_unit_fpsimd1")
-
-
-;;-------------------------------------------------------
-;; Floating-point Division
-;;-------------------------------------------------------
-
-;; Single-precision divide takes 14 cycles to complete, and this
-;; includes the time taken for the special instruction used to collect the
-;; result to travel down the multiply pipeline.
-
-(define_insn_reservation "large_cpu_fdivs" 14
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")))
- "large_cpu_resv_i1, large_cpu_unit_fpsimd1 * 13")
-
-(define_insn_reservation "large_cpu_fdivd" 29
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")))
- "large_cpu_resv_i1, large_cpu_unit_fpsimd1 * 28")
-
-
-
-;;-------------------------------------------------------
-;; Floating-point Transfers
-;;-------------------------------------------------------
-
-(define_insn_reservation "large_cpu_i2f" 4
- (and (eq_attr "tune" "large")
- (eq_attr "v8type" "fmovi2f"))
- "large_cpu_resv_i1")
-
-(define_insn_reservation "large_cpu_f2i" 2
- (and (eq_attr "tune" "large")
- (eq_attr "v8type" "fmovf2i"))
- "large_cpu_resv_i1")
-
-
-;;-------------------------------------------------------
-;; Floating-point Load/Store
-;;-------------------------------------------------------
-
-(define_insn_reservation "large_cpu_floads" 4
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fpsimd_load,fpsimd_load2") (eq_attr "mode" "SF")))
- "large_cpu_resv_i1")
-
-(define_insn_reservation "large_cpu_floadd" 5
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fpsimd_load,fpsimd_load2") (eq_attr "mode" "DF")))
- "large_cpu_resv_i1 + large_cpu_unit_br, large_cpu_resv_i1")
-
-(define_insn_reservation "large_cpu_fstores" 0
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fpsimd_store,fpsimd_store2") (eq_attr "mode" "SF")))
- "large_cpu_resv_i1")
-
-(define_insn_reservation "large_cpu_fstored" 0
- (and (eq_attr "tune" "large")
- (and (eq_attr "v8type" "fpsimd_store,fpsimd_store2") (eq_attr "mode" "DF")))
- "large_cpu_resv_i1 + large_cpu_unit_br, large_cpu_resv_i1")
-
-
-;;-------------------------------------------------------
-;; Bypasses
-;;-------------------------------------------------------
-
-(define_bypass 1 "large_cpu_alu, large_cpu_logic, large_cpu_shift"
- "large_cpu_alu, large_cpu_alu_shift, large_cpu_logic, large_cpu_logic_shift, large_cpu_shift")
-
-(define_bypass 2 "large_cpu_alu_shift, large_cpu_logic_shift"
- "large_cpu_alu, large_cpu_alu_shift, large_cpu_logic, large_cpu_logic_shift, large_cpu_shift")
-
-(define_bypass 1 "large_cpu_alu, large_cpu_logic, large_cpu_shift" "large_cpu_load1")
-
-(define_bypass 2 "large_cpu_alu_shift, large_cpu_logic_shift" "large_cpu_load1")
-
-(define_bypass 2 "large_cpu_floads"
- "large_cpu_fpalu, large_cpu_fpmuld,\
- large_cpu_fdivs, large_cpu_fdivd,\
- large_cpu_f2i")
-
-(define_bypass 3 "large_cpu_floadd"
- "large_cpu_fpalu, large_cpu_fpmuld,\
- large_cpu_fdivs, large_cpu_fdivd,\
- large_cpu_f2i")
diff --git a/gcc/config/aarch64/small.md b/gcc/config/aarch64/small.md
deleted file mode 100644
index a19083ccff2..00000000000
--- a/gcc/config/aarch64/small.md
+++ /dev/null
@@ -1,287 +0,0 @@
-;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
-;;
-;; Contributed by ARM Ltd.
-;;
-;; 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/>.
-
-;; In the absence of any ARMv8-A implementations, two examples derived
-;; from ARM's most recent ARMv7-A cores (Cortex-A7 and Cortex-A15) are
-;; included by way of example. This is a temporary measure.
-
-;; Example pipeline description for an example 'small' core
-;; implementing AArch64
-
-;;-------------------------------------------------------
-;; General Description
-;;-------------------------------------------------------
-
-(define_automaton "small_cpu")
-
-;; The core is modelled as a single issue pipeline with the following
-;; dispatch units.
-;; 1. One pipeline for simple intructions.
-;; 2. One pipeline for branch intructions.
-;;
-;; There are five pipeline stages.
-;; The decode/issue stages operate the same for all instructions.
-;; Instructions always advance one stage per cycle in order.
-;; Only branch instructions may dual-issue with other instructions, except
-;; when those instructions take multiple cycles to issue.
-
-
-;;-------------------------------------------------------
-;; CPU Units and Reservations
-;;-------------------------------------------------------
-
-(define_cpu_unit "small_cpu_unit_i" "small_cpu")
-(define_cpu_unit "small_cpu_unit_br" "small_cpu")
-
-;; Pseudo-unit for blocking the multiply pipeline when a double-precision
-;; multiply is in progress.
-(define_cpu_unit "small_cpu_unit_fpmul_pipe" "small_cpu")
-
-;; The floating-point add pipeline, used to model the usage
-;; of the add pipeline by fp alu instructions.
-(define_cpu_unit "small_cpu_unit_fpadd_pipe" "small_cpu")
-
-;; Floating-point division pipeline (long latency, out-of-order completion).
-(define_cpu_unit "small_cpu_unit_fpdiv" "small_cpu")
-
-
-;;-------------------------------------------------------
-;; Simple ALU Instructions
-;;-------------------------------------------------------
-
-;; Simple ALU operations without shift
-(define_insn_reservation "small_cpu_alu" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "adc,alu,alu_ext"))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_logic" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "logic,logic_imm"))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_shift" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "shift,shift_imm"))
- "small_cpu_unit_i")
-
-;; Simple ALU operations with immediate shift
-(define_insn_reservation "small_cpu_alu_shift" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "alu_shift"))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_logic_shift" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "logic_shift"))
- "small_cpu_unit_i")
-
-
-;;-------------------------------------------------------
-;; Multiplication/Division
-;;-------------------------------------------------------
-
-;; Simple multiplication
-(define_insn_reservation "small_cpu_mult_single" 2
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "mult,madd") (eq_attr "mode" "SI")))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_mult_double" 3
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "mult,madd") (eq_attr "mode" "DI")))
- "small_cpu_unit_i")
-
-;; 64-bit multiplication
-(define_insn_reservation "small_cpu_mull" 3
- (and (eq_attr "tune" "small") (eq_attr "v8type" "mull,mulh,maddl"))
- "small_cpu_unit_i * 2")
-
-;; Division
-(define_insn_reservation "small_cpu_udiv_single" 5
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "udiv") (eq_attr "mode" "SI")))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_udiv_double" 10
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "udiv") (eq_attr "mode" "DI")))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_sdiv_single" 6
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "sdiv") (eq_attr "mode" "SI")))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_sdiv_double" 12
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "sdiv") (eq_attr "mode" "DI")))
- "small_cpu_unit_i")
-
-
-;;-------------------------------------------------------
-;; Load/Store Instructions
-;;-------------------------------------------------------
-
-(define_insn_reservation "small_cpu_load1" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "load_acq,load1"))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_store1" 0
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "store_rel,store1"))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_load2" 3
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "load2"))
- "small_cpu_unit_i + small_cpu_unit_br, small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_store2" 0
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "store2"))
- "small_cpu_unit_i + small_cpu_unit_br, small_cpu_unit_i")
-
-
-;;-------------------------------------------------------
-;; Branches
-;;-------------------------------------------------------
-
-;; Direct branches are the only instructions that can dual-issue.
-;; The latency here represents when the branch actually takes place.
-
-(define_insn_reservation "small_cpu_unit_br" 3
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "branch,call"))
- "small_cpu_unit_br")
-
-
-;;-------------------------------------------------------
-;; Floating-point arithmetic.
-;;-------------------------------------------------------
-
-(define_insn_reservation "small_cpu_fpalu" 4
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "ffarith,fadd,fccmp,fcvt,fcmp"))
- "small_cpu_unit_i + small_cpu_unit_fpadd_pipe")
-
-(define_insn_reservation "small_cpu_fconst" 3
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "fconst"))
- "small_cpu_unit_i + small_cpu_unit_fpadd_pipe")
-
-(define_insn_reservation "small_cpu_fpmuls" 4
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")))
- "small_cpu_unit_i + small_cpu_unit_fpmul_pipe")
-
-(define_insn_reservation "small_cpu_fpmuld" 7
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")))
- "small_cpu_unit_i + small_cpu_unit_fpmul_pipe, small_cpu_unit_fpmul_pipe * 2,\
- small_cpu_unit_i + small_cpu_unit_fpmul_pipe")
-
-
-;;-------------------------------------------------------
-;; Floating-point Division
-;;-------------------------------------------------------
-
-;; Single-precision divide takes 14 cycles to complete, and this
-;; includes the time taken for the special instruction used to collect the
-;; result to travel down the multiply pipeline.
-
-(define_insn_reservation "small_cpu_fdivs" 14
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")))
- "small_cpu_unit_i, small_cpu_unit_fpdiv * 13")
-
-(define_insn_reservation "small_cpu_fdivd" 29
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")))
- "small_cpu_unit_i, small_cpu_unit_fpdiv * 28")
-
-
-;;-------------------------------------------------------
-;; Floating-point Transfers
-;;-------------------------------------------------------
-
-(define_insn_reservation "small_cpu_i2f" 4
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "fmovi2f"))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_f2i" 2
- (and (eq_attr "tune" "small")
- (eq_attr "v8type" "fmovf2i"))
- "small_cpu_unit_i")
-
-
-;;-------------------------------------------------------
-;; Floating-point Load/Store
-;;-------------------------------------------------------
-
-(define_insn_reservation "small_cpu_floads" 4
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_floadd" 5
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")))
- "small_cpu_unit_i + small_cpu_unit_br, small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_fstores" 0
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")))
- "small_cpu_unit_i")
-
-(define_insn_reservation "small_cpu_fstored" 0
- (and (eq_attr "tune" "small")
- (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")))
- "small_cpu_unit_i + small_cpu_unit_br, small_cpu_unit_i")
-
-
-;;-------------------------------------------------------
-;; Bypasses
-;;-------------------------------------------------------
-
-;; Forwarding path for unshifted operands.
-
-(define_bypass 1 "small_cpu_alu, small_cpu_alu_shift"
- "small_cpu_alu, small_cpu_alu_shift, small_cpu_logic, small_cpu_logic_shift, small_cpu_shift")
-
-(define_bypass 1 "small_cpu_logic, small_cpu_logic_shift"
- "small_cpu_alu, small_cpu_alu_shift, small_cpu_logic, small_cpu_logic_shift, small_cpu_shift")
-
-(define_bypass 1 "small_cpu_shift"
- "small_cpu_alu, small_cpu_alu_shift, small_cpu_logic, small_cpu_logic_shift, small_cpu_shift")
-
-;; Load-to-use for floating-point values has a penalty of one cycle.
-
-(define_bypass 2 "small_cpu_floads"
- "small_cpu_fpalu, small_cpu_fpmuld,\
- small_cpu_fdivs, small_cpu_fdivd,\
- small_cpu_f2i")
-
-(define_bypass 3 "small_cpu_floadd"
- "small_cpu_fpalu, small_cpu_fpmuld,\
- small_cpu_fdivs, small_cpu_fdivd,\
- small_cpu_f2i")
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 8158a4e81ad..e710b0c3717 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "splay-tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-stdarg.h"
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 87908d41afc..cc49c553c55 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -1087,6 +1087,22 @@ arc_select_cc_mode (OP, X, Y)
expensive than reg->reg moves. */
#define BRANCH_COST(speed_p, predictable_p) 2
+/* Scc sets the destination to 1 and then conditionally zeroes it.
+ Best case, ORed SCCs can be made into clear - condset - condset.
+ But it could also end up as five insns. So say it costs four on
+ average.
+ These extra instructions - and the second comparison - will also be
+ an extra cost if the first comparison would have been decisive.
+ So get an average saving, with a probability of the first branch
+ beging decisive of p0, we want:
+ p0 * (branch_cost - 4) > (1 - p0) * 5
+ ??? We don't get to see that probability to evaluate, so we can
+ only wildly guess that it might be 50%.
+ ??? The compiler also lacks the notion of branch predictability. */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT \
+ (BRANCH_COST (optimize_function_for_speed_p (cfun), \
+ false) > 9)
+
/* Nonzero if access to memory by bytes is slow and undesirable.
For RISC chips, it means that access to memory by bytes is no
better than access by words when possible, so grab a whole word
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index baf347876be..64b4162a877 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -4789,8 +4789,7 @@
{
/* ??? Can do better for when a scratch register
is known. But that would require extra testing. */
- arc_clear_unalign ();
- return ".p2align 2\;push_s r0\;add r0,pcl,%4-.+2\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-.+2\;sr r0,[3]; LP_END\;pop_s r0";
+ return "push_s r0\;add r0,pcl,%4-(.&-4)\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-(.&-4)\;sr r0,[3]; LP_END\;pop_s r0";
}
/* Check if the loop end is in range to be set by the lp instruction. */
size = INTVAL (operands[3]) < 2 ? 0 : 2048;
diff --git a/gcc/config/arm/aarch-cost-tables.h b/gcc/config/arm/aarch-cost-tables.h
new file mode 100644
index 00000000000..4b36abe0da4
--- /dev/null
+++ b/gcc/config/arm/aarch-cost-tables.h
@@ -0,0 +1,126 @@
+/* RTX cost tables shared between arm and aarch64.
+
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ 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/>. */
+
+#ifndef GCC_AARCH_COST_TABLES_H
+#define GCC_AARCH_COST_TABLES_H
+
+const struct cpu_cost_table generic_extra_costs =
+{
+ /* ALU */
+ {
+ 0, /* Arith. */
+ 0, /* Logical. */
+ 0, /* Shift. */
+ COSTS_N_INSNS (1), /* Shift_reg. */
+ 0, /* Arith_shift. */
+ COSTS_N_INSNS (1), /* Arith_shift_reg. */
+ 0, /* Log_shift. */
+ COSTS_N_INSNS (1), /* Log_shift_reg. */
+ 0, /* Extend. */
+ COSTS_N_INSNS (1), /* Extend_arith. */
+ 0, /* Bfi. */
+ 0, /* Bfx. */
+ 0, /* Clz. */
+ COSTS_N_INSNS (1), /* non_exec. */
+ false /* non_exec_costs_exec. */
+ },
+ {
+ /* MULT SImode */
+ {
+ COSTS_N_INSNS (2), /* Simple. */
+ COSTS_N_INSNS (1), /* Flag_setting. */
+ COSTS_N_INSNS (2), /* Extend. */
+ COSTS_N_INSNS (3), /* Add. */
+ COSTS_N_INSNS (3), /* Extend_add. */
+ COSTS_N_INSNS (8) /* Idiv. */
+ },
+ /* MULT DImode */
+ {
+ 0, /* Simple (N/A). */
+ 0, /* Flag_setting (N/A). */
+ COSTS_N_INSNS (2), /* Extend. */
+ 0, /* Add (N/A). */
+ COSTS_N_INSNS (3), /* Extend_add. */
+ 0 /* Idiv (N/A). */
+ }
+ },
+ /* LD/ST */
+ {
+ COSTS_N_INSNS (2), /* Load. */
+ COSTS_N_INSNS (2), /* Load_sign_extend. */
+ COSTS_N_INSNS (3), /* Ldrd. */
+ COSTS_N_INSNS (2), /* Ldm_1st. */
+ 1, /* Ldm_regs_per_insn_1st. */
+ 1, /* Ldm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (2), /* Loadf. */
+ COSTS_N_INSNS (3), /* Loadd. */
+ COSTS_N_INSNS (1), /* Load_unaligned. */
+ COSTS_N_INSNS (2), /* Store. */
+ COSTS_N_INSNS (3), /* Strd. */
+ COSTS_N_INSNS (2), /* Stm_1st. */
+ 1, /* Stm_regs_per_insn_1st. */
+ 1, /* Stm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (2), /* Storef. */
+ COSTS_N_INSNS (3), /* Stored. */
+ COSTS_N_INSNS (1) /* Store_unaligned. */
+ },
+ {
+ /* FP SFmode */
+ {
+ COSTS_N_INSNS (7), /* Div. */
+ COSTS_N_INSNS (2), /* Mult. */
+ COSTS_N_INSNS (3), /* Mult_addsub. */
+ COSTS_N_INSNS (3), /* Fma. */
+ COSTS_N_INSNS (1), /* Addsub. */
+ 0, /* Fpconst. */
+ 0, /* Neg. */
+ 0, /* Compare. */
+ 0, /* Widen. */
+ 0, /* Narrow. */
+ 0, /* Toint. */
+ 0, /* Fromint. */
+ 0 /* Roundint. */
+ },
+ /* FP DFmode */
+ {
+ COSTS_N_INSNS (15), /* Div. */
+ COSTS_N_INSNS (5), /* Mult. */
+ COSTS_N_INSNS (7), /* Mult_addsub. */
+ COSTS_N_INSNS (7), /* Fma. */
+ COSTS_N_INSNS (3), /* Addsub. */
+ 0, /* Fpconst. */
+ 0, /* Neg. */
+ 0, /* Compare. */
+ 0, /* Widen. */
+ 0, /* Narrow. */
+ 0, /* Toint. */
+ 0, /* Fromint. */
+ 0 /* Roundint. */
+ }
+ },
+ /* Vector */
+ {
+ COSTS_N_INSNS (1) /* Alu. */
+ }
+};
+
+#endif /* GCC_AARCH_COST_TABLES_H */
+
diff --git a/gcc/config/arm/arm-cores.def b/gcc/config/arm/arm-cores.def
index 79e2e87b72b..d664e736424 100644
--- a/gcc/config/arm/arm-cores.def
+++ b/gcc/config/arm/arm-cores.def
@@ -134,8 +134,8 @@ ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, cortex)
ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, cortex)
ARM_CORE("cortex-r5", cortexr5, 7R, FL_LDSCHED | FL_ARM_DIV, cortex)
ARM_CORE("cortex-r7", cortexr7, 7R, FL_LDSCHED | FL_ARM_DIV, cortex)
-ARM_CORE("cortex-m4", cortexm4, 7EM, FL_LDSCHED, cortex)
-ARM_CORE("cortex-m3", cortexm3, 7M, FL_LDSCHED, cortex)
+ARM_CORE("cortex-m4", cortexm4, 7EM, FL_LDSCHED, v7m)
+ARM_CORE("cortex-m3", cortexm3, 7M, FL_LDSCHED, v7m)
ARM_CORE("cortex-m1", cortexm1, 6M, FL_LDSCHED, v6m)
ARM_CORE("cortex-m0", cortexm0, 6M, FL_LDSCHED, v6m)
ARM_CORE("cortex-m0plus", cortexm0plus, 6M, FL_LDSCHED, v6m)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index de9d26710c7..378f4b67553 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -266,6 +266,7 @@ static reg_class_t arm_preferred_rename_class (reg_class_t rclass);
static unsigned int arm_autovectorize_vector_sizes (void);
static int arm_default_branch_cost (bool, bool);
static int arm_cortex_a5_branch_cost (bool, bool);
+static int arm_cortex_m_branch_cost (bool, bool);
static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
const unsigned char *sel);
@@ -949,106 +950,9 @@ struct cpu_vec_costs arm_default_vec_cost = {
1, /* cond_not_taken_branch_cost. */
};
+/* Cost tables for AArch32 + AArch64 cores should go in aarch-cost-tables.h */
+#include "aarch-cost-tables.h"
-const struct cpu_cost_table generic_extra_costs =
-{
- /* ALU */
- {
- 0, /* Arith. */
- 0, /* Logical. */
- 0, /* Shift. */
- COSTS_N_INSNS (1), /* Shift_reg. */
- 0, /* Arith_shift. */
- COSTS_N_INSNS (1), /* Arith_shift_reg. */
- 0, /* Log_shift. */
- COSTS_N_INSNS (1), /* Log_shift_reg. */
- 0, /* Extend. */
- COSTS_N_INSNS (1), /* Extend_arith. */
- 0, /* Bfi. */
- 0, /* Bfx. */
- 0, /* Clz. */
- COSTS_N_INSNS (1), /* non_exec. */
- false /* non_exec_costs_exec. */
- },
- /* MULT SImode */
- {
- {
- COSTS_N_INSNS (2), /* Simple. */
- COSTS_N_INSNS (1), /* Flag_setting. */
- COSTS_N_INSNS (2), /* Extend. */
- COSTS_N_INSNS (3), /* Add. */
- COSTS_N_INSNS (3), /* Extend_add. */
- COSTS_N_INSNS (8) /* Idiv. */
- },
- /* MULT DImode */
- {
- 0, /* Simple (N/A). */
- 0, /* Flag_setting (N/A). */
- COSTS_N_INSNS (2), /* Extend. */
- 0, /* Add (N/A). */
- COSTS_N_INSNS (3), /* Extend_add. */
- 0 /* Idiv (N/A). */
- }
- },
- /* LD/ST */
- {
- COSTS_N_INSNS (2), /* Load. */
- COSTS_N_INSNS (2), /* Load_sign_extend. */
- COSTS_N_INSNS (3), /* Ldrd. */
- COSTS_N_INSNS (2), /* Ldm_1st. */
- 1, /* Ldm_regs_per_insn_1st. */
- 1, /* Ldm_regs_per_insn_subsequent. */
- COSTS_N_INSNS (2), /* Loadf. */
- COSTS_N_INSNS (3), /* Loadd. */
- COSTS_N_INSNS (1), /* Load_unaligned. */
- COSTS_N_INSNS (2), /* Store. */
- COSTS_N_INSNS (3), /* Strd. */
- COSTS_N_INSNS (2), /* Stm_1st. */
- 1, /* Stm_regs_per_insn_1st. */
- 1, /* Stm_regs_per_insn_subsequent. */
- COSTS_N_INSNS (2), /* Storef. */
- COSTS_N_INSNS (3), /* Stored. */
- COSTS_N_INSNS (1) /* Store_unaligned. */
- },
- {
- /* FP SFmode */
- {
- COSTS_N_INSNS (7), /* Div. */
- COSTS_N_INSNS (2), /* Mult. */
- COSTS_N_INSNS (3), /* Mult_addsub. */
- COSTS_N_INSNS (3), /* Fma. */
- COSTS_N_INSNS (1), /* Addsub. */
- 0, /* Fpconst. */
- 0, /* Neg. */
- 0, /* Compare. */
- 0, /* Widen. */
- 0, /* Narrow. */
- 0, /* Toint. */
- 0, /* Fromint. */
- 0 /* Roundint. */
- },
- /* FP DFmode */
- {
- COSTS_N_INSNS (15), /* Div. */
- COSTS_N_INSNS (5), /* Mult. */
- COSTS_N_INSNS (7), /* Mult_addsub. */
- COSTS_N_INSNS (7), /* Fma. */
- COSTS_N_INSNS (3), /* Addsub. */
- 0, /* Fpconst. */
- 0, /* Neg. */
- 0, /* Compare. */
- 0, /* Widen. */
- 0, /* Narrow. */
- 0, /* Toint. */
- 0, /* Fromint. */
- 0 /* Roundint. */
- }
- },
- /* Vector */
- {
- COSTS_N_INSNS (1) /* Alu. */
- }
-};
const struct cpu_cost_table cortexa9_extra_costs =
@@ -1357,7 +1261,7 @@ const struct tune_params arm_slowmul_tune =
{
arm_slowmul_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
3, /* Constant limit. */
5, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1373,7 +1277,7 @@ const struct tune_params arm_fastmul_tune =
{
arm_fastmul_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
5, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1392,7 +1296,7 @@ const struct tune_params arm_strongarm_tune =
{
arm_fastmul_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
3, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1424,7 +1328,7 @@ const struct tune_params arm_9e_tune =
{
arm_9e_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
5, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1440,7 +1344,7 @@ const struct tune_params arm_v6t2_tune =
{
arm_9e_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
5, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1457,7 +1361,7 @@ const struct tune_params arm_cortex_tune =
{
arm_9e_rtx_costs,
&generic_extra_costs,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
5, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1489,7 +1393,7 @@ const struct tune_params arm_cortex_a15_tune =
{
arm_9e_rtx_costs,
&cortexa15_extra_costs,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
2, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1508,7 +1412,7 @@ const struct tune_params arm_cortex_a5_tune =
{
arm_9e_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
1, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -1536,13 +1440,36 @@ const struct tune_params arm_cortex_a9_tune =
false /* Prefer Neon for 64-bits bitops. */
};
+/* armv7m tuning. On Cortex-M4 cores for example, MOVW/MOVT take a single
+ cycle to execute each. An LDR from the constant pool also takes two cycles
+ to execute, but mildly increases pipelining opportunity (consecutive
+ loads/stores can be pipelined together, saving one cycle), and may also
+ improve icache utilisation. Hence we prefer the constant pool for such
+ processors. */
+
+const struct tune_params arm_v7m_tune =
+{
+ arm_9e_rtx_costs,
+ &generic_extra_costs,
+ NULL, /* Sched adj cost. */
+ 1, /* Constant limit. */
+ 5, /* Max cond insns. */
+ ARM_PREFETCH_NOT_BENEFICIAL,
+ true, /* Prefer constant pool. */
+ arm_cortex_m_branch_cost,
+ false, /* Prefer LDRD/STRD. */
+ {false, false}, /* Prefer non short circuit. */
+ &arm_default_vec_cost, /* Vectorizer costs. */
+ false /* Prefer Neon for 64-bits bitops. */
+};
+
/* The arm_v6m_tune is duplicated from arm_cortex_tune, rather than
arm_v6t2_tune. It is used for cortex-m0, cortex-m1 and cortex-m0plus. */
const struct tune_params arm_v6m_tune =
{
arm_9e_rtx_costs,
NULL,
- NULL,
+ NULL, /* Sched adj cost. */
1, /* Constant limit. */
5, /* Max cond insns. */
ARM_PREFETCH_NOT_BENEFICIAL,
@@ -9961,7 +9888,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
*cost = 0;
return true;
}
- break;
+ return false;
case ABS:
if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
@@ -11332,6 +11259,20 @@ arm_cortex_a5_branch_cost (bool speed_p, bool predictable_p)
return speed_p ? 0 : arm_default_branch_cost (speed_p, predictable_p);
}
+/* Thumb-2 branches are relatively cheap on Cortex-M processors ("1 + P cycles"
+ on Cortex-M4, where P varies from 1 to 3 according to some criteria), since
+ sequences of non-executed instructions in IT blocks probably take the same
+ amount of time as executed instructions (and the IT instruction itself takes
+ space in icache). This function was experimentally determined to give good
+ results on a popular embedded benchmark. */
+
+static int
+arm_cortex_m_branch_cost (bool speed_p, bool predictable_p)
+{
+ return (TARGET_32BIT && speed_p) ? 1
+ : arm_default_branch_cost (speed_p, predictable_p);
+}
+
static bool fp_consts_inited = false;
static REAL_VALUE_TYPE value_fp0;
diff --git a/gcc/config/arm/cortex-a15.md b/gcc/config/arm/cortex-a15.md
index ccad6207608..5a31a097918 100644
--- a/gcc/config/arm/cortex-a15.md
+++ b/gcc/config/arm/cortex-a15.md
@@ -158,7 +158,7 @@
"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")
+(include "../arm/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.
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index a7c36833b45..a37e02ff834 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -52,6 +52,7 @@
#include "hw-doloop.h"
#include "regrename.h"
#include "dumpfile.h"
+#include "gimple-expr.h"
/* Table of supported architecture variants. */
typedef struct
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 661795dc9f0..81e18dfb969 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "obstack.h"
#include "gimple.h"
+#include "gimplify.h"
#include "lto-streamer.h"
/* Darwin supports a feature called fix-and-continue, which is used
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e0506fe4624..9122eb303f8 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "reload.h"
#include "cgraph.h"
#include "gimple.h"
+#include "gimplify.h"
#include "dwarf2.h"
#include "df.h"
#include "tm-constrs.h"
@@ -3975,10 +3976,10 @@ ix86_option_override_internal (bool main_args_p,
if (flag_expensive_optimizations
&& !(opts_set->x_target_flags & MASK_VZEROUPPER))
opts->x_target_flags |= MASK_VZEROUPPER;
- if (!ix86_tune_features[X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL]
+ if (!ix86_tune_features[X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL]
&& !(opts_set->x_target_flags & MASK_AVX256_SPLIT_UNALIGNED_LOAD))
opts->x_target_flags |= MASK_AVX256_SPLIT_UNALIGNED_LOAD;
- if (!ix86_tune_features[X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL]
+ if (!ix86_tune_features[X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL]
&& !(opts_set->x_target_flags & MASK_AVX256_SPLIT_UNALIGNED_STORE))
opts->x_target_flags |= MASK_AVX256_SPLIT_UNALIGNED_STORE;
/* Enable 128-bit AVX instruction generation
@@ -14856,6 +14857,11 @@ ix86_print_operand (FILE *file, rtx x, int code)
/* We do not want to print value of the operand. */
return;
+ case 'N':
+ if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
+ fputs ("{z}", file);
+ return;
+
case '*':
if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('*', file);
@@ -23762,13 +23768,15 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
}
gcc_assert (desired_align >= 1 && align >= 1);
- /* Misaligned move sequences handles both prologues and epilogues at once.
- Default code generation results in smaller code for large alignments and
- also avoids redundant job when sizes are known precisely. */
- misaligned_prologue_used = (TARGET_MISALIGNED_MOVE_STRING_PROLOGUES
- && MAX (desired_align, epilogue_size_needed) <= 32
- && ((desired_align > align && !align_bytes)
- || (!count && epilogue_size_needed > 1)));
+ /* Misaligned move sequences handle both prologue and epilogue at once.
+ Default code generation results in a smaller code for large alignments
+ and also avoids redundant job when sizes are known precisely. */
+ misaligned_prologue_used
+ = (TARGET_MISALIGNED_MOVE_STRING_PRO_EPILOGUES
+ && MAX (desired_align, epilogue_size_needed) <= 32
+ && desired_align <= epilogue_size_needed
+ && ((desired_align > align && !align_bytes)
+ || (!count && epilogue_size_needed > 1)));
/* Do the cheap promotion to allow better CSE across the
main loop and epilogue (ie one load of the big constant in the
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 9836a40b46c..123e3faed4b 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -353,8 +353,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
#define TARGET_PROMOTE_QImode ix86_tune_features[X86_TUNE_PROMOTE_QIMODE]
#define TARGET_FAST_PREFIX ix86_tune_features[X86_TUNE_FAST_PREFIX]
#define TARGET_SINGLE_STRINGOP ix86_tune_features[X86_TUNE_SINGLE_STRINGOP]
-#define TARGET_MISALIGNED_MOVE_STRING_PROLOGUES_EPILOGUES \
- ix86_tune_features[TARGET_MISALIGNED_MOVE_STRING_PROLOGUES]
+#define TARGET_MISALIGNED_MOVE_STRING_PRO_EPILOGUES \
+ ix86_tune_features[X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES]
#define TARGET_QIMODE_MATH ix86_tune_features[X86_TUNE_QIMODE_MATH]
#define TARGET_HIMODE_MATH ix86_tune_features[X86_TUNE_HIMODE_MATH]
#define TARGET_PROMOTE_QI_REGS ix86_tune_features[X86_TUNE_PROMOTE_QI_REGS]
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a37fa64a03e..e23b3b6807e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -7978,7 +7978,18 @@
(const_int 0)))
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
(and:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
+ "TARGET_64BIT
+ && ix86_match_ccmode
+ (insn,
+ /* If we are going to emit andl instead of andq, and the operands[2]
+ constant might have the SImode sign bit set, make sure the sign
+ flag isn't tested, because the instruction will set the sign flag
+ based on bit 31 rather than bit 63. If it isn't CONST_INT,
+ conservatively assume it might have bit 31 set. */
+ (satisfies_constraint_Z (operands[2])
+ && (!CONST_INT_P (operands[2])
+ || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
+ ? CCZmode : CCNOmode)
&& ix86_binary_operator_ok (AND, DImode, operands)"
"@
and{l}\t{%k2, %k0|%k0, %k2}
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index e5dd90cfad2..66ac52fd8c4 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -687,6 +687,16 @@
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 3)")))
+;; Match 0 to 4.
+(define_predicate "const_0_to_4_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 4)")))
+
+;; Match 0 to 5.
+(define_predicate "const_0_to_5_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 5)")))
+
;; Match 0 to 7.
(define_predicate "const_0_to_7_operand"
(and (match_code "const_int")
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 7bb2d7795f6..6d6e16efcc8 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -87,6 +87,7 @@
;; For AVX512F support
UNSPEC_VPERMI2
UNSPEC_VPERMT2
+ UNSPEC_VPERMI2_MASK
UNSPEC_UNSIGNED_FIX_NOTRUNC
UNSPEC_UNSIGNED_PCMP
UNSPEC_TESTM
@@ -101,9 +102,15 @@
UNSPEC_GETMANT
UNSPEC_ALIGN
UNSPEC_CONFLICT
+ UNSPEC_COMPRESS
+ UNSPEC_COMPRESS_STORE
+ UNSPEC_EXPAND
UNSPEC_MASKED_EQ
UNSPEC_MASKED_GT
+ ;; For embed. rounding feature
+ UNSPEC_EMBEDDED_ROUNDING
+
;; For AVX512PF support
UNSPEC_GATHER_PREFETCH
UNSPEC_SCATTER_PREFETCH
@@ -551,6 +558,12 @@
(V8SF "7") (V4DF "3")
(V4SF "3") (V2DF "1")])
+(define_mode_attr ssescalarsize
+ [(V8DI "64") (V4DI "64") (V2DI "64")
+ (V32HI "16") (V16HI "16") (V8HI "16")
+ (V16SI "32") (V8SI "32") (V4SI "32")
+ (V16SF "32") (V8DF "64")])
+
;; SSE prefix for integer vector modes
(define_mode_attr sseintprefix
[(V2DI "p") (V2DF "")
@@ -607,6 +620,9 @@
(define_mode_attr bcstscalarsuff
[(V16SI "d") (V16SF "ss") (V8DI "q") (V8DF "sd")])
+;; Include define_subst patterns for instructions with mask
+(include "subst.md")
+
;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -746,6 +762,28 @@
]
(const_string "<sseinsnmode>")))])
+(define_insn "avx512f_load<mode>_mask"
+ [(set (match_operand:VI48F_512 0 "register_operand" "=v,v")
+ (vec_merge:VI48F_512
+ (match_operand:VI48F_512 1 "nonimmediate_operand" "v,m")
+ (match_operand:VI48F_512 2 "vector_move_operand" "0C,0C")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+{
+ switch (MODE_<sseinsnmode>)
+ {
+ case MODE_V8DF:
+ case MODE_V16SF:
+ return "vmova<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
+ default:
+ return "vmovdqa<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "memory" "none,load")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "avx512f_blendm<mode>"
[(set (match_operand:VI48F_512 0 "register_operand" "=v")
(vec_merge:VI48F_512
@@ -758,6 +796,28 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_insn "avx512f_store<mode>_mask"
+ [(set (match_operand:VI48F_512 0 "memory_operand" "=m")
+ (vec_merge:VI48F_512
+ (match_operand:VI48F_512 1 "register_operand" "v")
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "k")))]
+ "TARGET_AVX512F"
+{
+ switch (MODE_<sseinsnmode>)
+ {
+ case MODE_V8DF:
+ case MODE_V16SF:
+ return "vmova<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ default:
+ return "vmovdqa<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "memory" "store")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "sse2_movq128"
[(set (match_operand:V2DI 0 "register_operand" "=x")
(vec_concat:V2DI
@@ -852,21 +912,21 @@
DONE;
})
-(define_insn "<sse>_loadu<ssemodesuffix><avxsizesuffix>"
+(define_insn "<sse>_loadu<ssemodesuffix><avxsizesuffix><mask_name>"
[(set (match_operand:VF 0 "register_operand" "=v")
(unspec:VF
[(match_operand:VF 1 "nonimmediate_operand" "vm")]
UNSPEC_LOADU))]
- "TARGET_SSE"
+ "TARGET_SSE && <mask_mode512bit_condition>"
{
switch (get_attr_mode (insn))
{
case MODE_V16SF:
case MODE_V8SF:
case MODE_V4SF:
- return "%vmovups\t{%1, %0|%0, %1}";
+ return "%vmovups\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
default:
- return "%vmovu<ssemodesuffix>\t{%1, %0|%0, %1}";
+ return "%vmovu<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
}
}
[(set_attr "type" "ssemov")
@@ -913,12 +973,36 @@
]
(const_string "<MODE>")))])
-(define_insn "<sse2_avx_avx512f>_loaddqu<mode>"
+(define_insn "avx512f_storeu<ssemodesuffix>512_mask"
+ [(set (match_operand:VF_512 0 "memory_operand" "=m")
+ (vec_merge:VF_512
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "v")]
+ UNSPEC_STOREU)
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "k")))]
+ "TARGET_AVX512F"
+{
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V16SF:
+ return "vmovups\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ default:
+ return "vmovu<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
+ (set_attr "memory" "store")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "<sse2_avx_avx512f>_loaddqu<mode><mask_name>"
[(set (match_operand:VI_UNALIGNED_LOADSTORE 0 "register_operand" "=v")
(unspec:VI_UNALIGNED_LOADSTORE
[(match_operand:VI_UNALIGNED_LOADSTORE 1 "nonimmediate_operand" "vm")]
UNSPEC_LOADU))]
- "TARGET_SSE2"
+ "TARGET_SSE2 && <mask_mode512bit_condition>"
{
switch (get_attr_mode (insn))
{
@@ -927,9 +1011,9 @@
return "%vmovups\t{%1, %0|%0, %1}";
case MODE_XI:
if (<MODE>mode == V8DImode)
- return "vmovdqu64\t{%1, %0|%0, %1}";
+ return "vmovdqu64\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
else
- return "vmovdqu32\t{%1, %0|%0, %1}";
+ return "vmovdqu32\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
default:
return "%vmovdqu\t{%1, %0|%0, %1}";
}
@@ -992,6 +1076,27 @@
]
(const_string "<sseinsnmode>")))])
+(define_insn "avx512f_storedqu<mode>_mask"
+ [(set (match_operand:VI48_512 0 "memory_operand" "=m")
+ (vec_merge:VI48_512
+ (unspec:VI48_512
+ [(match_operand:VI48_512 1 "register_operand" "v")]
+ UNSPEC_STOREU)
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "k")))]
+ "TARGET_AVX512F"
+{
+ if (<MODE>mode == V8DImode)
+ return "vmovdqu64\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+ else
+ return "vmovdqu32\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
+ (set_attr "memory" "store")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "<sse3>_lddqu<avxsizesuffix>"
[(set (match_operand:VI1 0 "register_operand" "=x")
(unspec:VI1 [(match_operand:VI1 1 "memory_operand" "m")]
@@ -1119,26 +1224,26 @@
}
[(set_attr "isa" "noavx,noavx,avx,avx")])
-(define_expand "<plusminus_insn><mode>3"
+(define_expand "<plusminus_insn><mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand")
(plusminus:VF
(match_operand:VF 1 "nonimmediate_operand")
(match_operand:VF 2 "nonimmediate_operand")))]
- "TARGET_SSE"
+ "TARGET_SSE && <mask_mode512bit_condition>"
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
-(define_insn "*<plusminus_insn><mode>3"
+(define_insn "*<plusminus_insn><mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=x,v")
(plusminus:VF
(match_operand:VF 1 "nonimmediate_operand" "<comm>0,v")
(match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) && <mask_mode512bit_condition>"
"@
<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
- v<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ v<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseadd")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vm<plusminus_insn><mode>3"
@@ -1158,26 +1263,26 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "<ssescalarmode>")])
-(define_expand "mul<mode>3"
+(define_expand "mul<mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand")
(mult:VF
(match_operand:VF 1 "nonimmediate_operand")
(match_operand:VF 2 "nonimmediate_operand")))]
- "TARGET_SSE"
+ "TARGET_SSE && <mask_mode512bit_condition>"
"ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
-(define_insn "*mul<mode>3"
+(define_insn "*mul<mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=x,v")
(mult:VF
(match_operand:VF 1 "nonimmediate_operand" "%0,v")
(match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
+ "TARGET_SSE && ix86_binary_operator_ok (MULT, <MODE>mode, operands) && <mask_mode512bit_condition>"
"@
mul<ssemodesuffix>\t{%2, %0|%0, %2}
- vmul<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ vmul<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "ssemul")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "btver2_decode" "direct,double")
(set_attr "mode" "<MODE>")])
@@ -1195,7 +1300,7 @@
v<multdiv_mnemonic><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %<iptr>2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sse<multdiv_mnemonic>")
- (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "prefix" "orig,vex")
(set_attr "btver2_decode" "direct,double")
(set_attr "mode" "<ssescalarmode>")])
@@ -1225,18 +1330,18 @@
}
})
-(define_insn "<sse>_div<mode>3"
+(define_insn "<sse>_div<mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=x,v")
(div:VF
(match_operand:VF 1 "register_operand" "0,v")
(match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE"
+ "TARGET_SSE && <mask_mode512bit_condition>"
"@
div<ssemodesuffix>\t{%2, %0|%0, %2}
- vdiv<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ vdiv<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "ssediv")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_rcp<mode>2"
@@ -1269,18 +1374,18 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "SF")])
-(define_insn "rcp14<mode>"
+(define_insn "<mask_codefor>rcp14<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")]
UNSPEC_RCP14))]
"TARGET_AVX512F"
- "vrcp14<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vrcp14<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
-(define_insn "srcp14<mode>"
+(define_insn "*srcp14<mode>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
(unspec:VF_128
@@ -1316,11 +1421,11 @@
}
})
-(define_insn "<sse>_sqrt<mode>2"
+(define_insn "<sse>_sqrt<mode>2<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=v")
(sqrt:VF (match_operand:VF 1 "nonimmediate_operand" "vm")))]
- "TARGET_SSE"
- "%vsqrt<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "TARGET_SSE && <mask_mode512bit_condition>"
+ "%vsqrt<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "atom_sse_attr" "sqrt")
(set_attr "btver2_sse_attr" "sqrt")
@@ -1341,8 +1446,8 @@
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sse")
(set_attr "atom_sse_attr" "sqrt")
- (set_attr "btver2_sse_attr" "sqrt")
(set_attr "prefix" "orig,vex")
+ (set_attr "btver2_sse_attr" "sqrt")
(set_attr "mode" "<ssescalarmode>")])
(define_expand "rsqrt<mode>2"
@@ -1365,18 +1470,18 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")])
-(define_insn "rsqrt14<mode>"
+(define_insn "<mask_codefor>rsqrt14<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")]
UNSPEC_RSQRT14))]
"TARGET_AVX512F"
- "vrsqrt14<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vrsqrt14<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
-(define_insn "rsqrt14<mode>"
+(define_insn "*rsqrt14<mode>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
(unspec:VF_128
@@ -1411,47 +1516,49 @@
;; isn't really correct, as those rtl operators aren't defined when
;; applied to NaNs. Hopefully the optimizers won't get too smart on us.
-(define_expand "<code><mode>3"
+(define_expand "<code><mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand")
(smaxmin:VF
(match_operand:VF 1 "nonimmediate_operand")
(match_operand:VF 2 "nonimmediate_operand")))]
- "TARGET_SSE"
+ "TARGET_SSE && <mask_mode512bit_condition>"
{
if (!flag_finite_math_only)
operands[1] = force_reg (<MODE>mode, operands[1]);
ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
})
-(define_insn "*<code><mode>3_finite"
+(define_insn "*<code><mode>3_finite<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=x,v")
(smaxmin:VF
(match_operand:VF 1 "nonimmediate_operand" "%0,v")
(match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE && flag_finite_math_only
- && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
+ && <mask_mode512bit_condition>"
"@
<maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
- v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ v<maxmin_float><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseadd")
(set_attr "btver2_sse_attr" "maxmin")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "mode" "<MODE>")])
-(define_insn "*<code><mode>3"
+(define_insn "*<code><mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=x,v")
(smaxmin:VF
(match_operand:VF 1 "register_operand" "0,v")
(match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE && !flag_finite_math_only"
+ "TARGET_SSE && !flag_finite_math_only
+ && <mask_mode512bit_condition>"
"@
<maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
- v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ v<maxmin_float><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseadd")
(set_attr "btver2_sse_attr" "maxmin")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vm<code><mode>3"
@@ -2029,6 +2136,24 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
+(define_insn "avx512f_vmcmp<mode>3_mask"
+ [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
+ (and:<avx512fmaskmode>
+ (unspec:<avx512fmaskmode>
+ [(match_operand:VF_128 1 "register_operand" "v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm")
+ (match_operand:SI 3 "const_0_to_31_operand" "n")]
+ UNSPEC_PCMP)
+ (and:<avx512fmaskmode>
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")
+ (const_int 1))))]
+ "TARGET_AVX512F"
+ "vcmp<ssescalarmodesuffix>\t{%3, %2, %1, %0%{%4%}|%0%{%4%}, %1, %2, %3}"
+ [(set_attr "type" "ssecmp")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<ssescalarmode>")])
+
(define_insn "avx512f_maskcmp<mode>3"
[(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
(match_operator:<avx512fmaskmode> 3 "sse_comparison_operator"
@@ -2583,7 +2708,39 @@
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
-(define_insn "fma_fmsub_<mode>"
+(define_insn "avx512f_fmadd_<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v,v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (match_operand:VF_512 1 "register_operand" "0,0")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm,v")
+ (match_operand:VF_512 3 "nonimmediate_operand" "v,vm"))
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "@
+ vfmadd132<ssemodesuffix>\t{%2, %3, %0%{%4%}|%0%{%4%}, %3, %2}
+ vfmadd213<ssemodesuffix>\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}"
+ [(set_attr "isa" "fma_avx512f,fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "avx512f_fmadd_<mode>_mask3"
+ [(set (match_operand:VF_512 0 "register_operand" "=x")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (match_operand:VF_512 1 "register_operand" "x")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")
+ (match_operand:VF_512 3 "register_operand" "0"))
+ (match_dup 3)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfmadd231<ssemodesuffix>\t{%2, %1, %0%{%4%}|%0%{%4%}, %1, %2}"
+ [(set_attr "isa" "fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*fma_fmsub_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0, v, x,x")
@@ -2601,7 +2758,41 @@
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
-(define_insn "fma_fnmadd_<mode>"
+(define_insn "avx512f_fmsub_<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v,v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (match_operand:VF_512 1 "register_operand" "0,0")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm,v")
+ (neg:VF_512
+ (match_operand:VF_512 3 "nonimmediate_operand" "v,vm")))
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "@
+ vfmsub132<ssemodesuffix>\t{%2, %3, %0%{%4%}|%0%{%4%}, %3, %2}
+ vfmsub213<ssemodesuffix>\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}"
+ [(set_attr "isa" "fma_avx512f,fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "avx512f_fmsub_<mode>_mask3"
+ [(set (match_operand:VF_512 0 "register_operand" "=v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (match_operand:VF_512 1 "register_operand" "v")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")
+ (neg:VF_512
+ (match_operand:VF_512 3 "register_operand" "0")))
+ (match_dup 3)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfmsub231<ssemodesuffix>\t{%2, %1, %0%{%4%}|%0%{%4%}, %1, %2}"
+ [(set_attr "isa" "fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*fma_fnmadd_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
(neg:FMAMODE
@@ -2619,6 +2810,40 @@
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
+(define_insn "avx512f_fnmadd_<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v,v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (neg:VF_512
+ (match_operand:VF_512 1 "register_operand" "0,0"))
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm,v")
+ (match_operand:VF_512 3 "nonimmediate_operand" "v,vm"))
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "@
+ vfnmadd132<ssemodesuffix>\t{%2, %3, %0%{%4%}|%0%{%4%}, %3, %2}
+ vfnmadd213<ssemodesuffix>\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}"
+ [(set_attr "isa" "fma_avx512f,fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "avx512f_fnmadd_<mode>_mask3"
+ [(set (match_operand:VF_512 0 "register_operand" "=v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (neg:VF_512
+ (match_operand:VF_512 1 "register_operand" "v"))
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")
+ (match_operand:VF_512 3 "register_operand" "0"))
+ (match_dup 3)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfnmadd231<ssemodesuffix>\t{%2, %1, %0%{%4%}|%0%{%4%}, %1, %2}"
+ [(set_attr "isa" "fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*fma_fnmsub_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
@@ -2638,6 +2863,42 @@
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
+(define_insn "avx512f_fnmsub_<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v,v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (neg:VF_512
+ (match_operand:VF_512 1 "register_operand" "0,0"))
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm,v")
+ (neg:VF_512
+ (match_operand:VF_512 3 "nonimmediate_operand" "v,vm")))
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "@
+ vfnmsub132<ssemodesuffix>\t{%2, %3, %0%{%4%}|%0%{%4%}, %3, %2}
+ vfnmsub213<ssemodesuffix>\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}"
+ [(set_attr "isa" "fma_avx512f,fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "avx512f_fnmsub_<mode>_mask3"
+ [(set (match_operand:VF_512 0 "register_operand" "=v")
+ (vec_merge:VF_512
+ (fma:VF_512
+ (neg:VF_512
+ (match_operand:VF_512 1 "register_operand" "v"))
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")
+ (neg:VF_512
+ (match_operand:VF_512 3 "register_operand" "0")))
+ (match_dup 3)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfnmsub231<ssemodesuffix>\t{%2, %1, %0%{%4%}|%0%{%4%}, %1, %2}"
+ [(set_attr "isa" "fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
;; FMA parallel floating point multiply addsub and subadd operations.
;; It would be possible to represent these without the UNSPEC as
@@ -2676,6 +2937,40 @@
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
+(define_insn "avx512f_fmaddsub_<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v,v")
+ (vec_merge:VF_512
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "0,0")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm,v")
+ (match_operand:VF_512 3 "nonimmediate_operand" "v,vm")]
+ UNSPEC_FMADDSUB)
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "@
+ vfmaddsub132<ssemodesuffix>\t{%2, %3, %0%{%4%}|%0%{%4%}, %3, %2}
+ vfmaddsub213<ssemodesuffix>\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}"
+ [(set_attr "isa" "fma_avx512f,fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "avx512f_fmaddsub_<mode>_mask3"
+ [(set (match_operand:VF_512 0 "register_operand" "=v")
+ (vec_merge:VF_512
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "v")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")
+ (match_operand:VF_512 3 "register_operand" "0")]
+ UNSPEC_FMADDSUB)
+ (match_dup 3)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfmaddsub231<ssemodesuffix>\t{%2, %1, %0%{%4%}|%0%{%4%}, %1, %2}"
+ [(set_attr "isa" "fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*fma_fmsubadd_<mode>"
[(set (match_operand:VF 0 "register_operand" "=v,v,v,x,x")
(unspec:VF
@@ -2695,6 +2990,42 @@
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
+(define_insn "avx512f_fmsubadd_<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v,v")
+ (vec_merge:VF_512
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "0,0")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm,v")
+ (neg:VF_512
+ (match_operand:VF_512 3 "nonimmediate_operand" "v,vm"))]
+ UNSPEC_FMADDSUB)
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "@
+ vfmsubadd132<ssemodesuffix>\t{%2, %3, %0%{%4%}|%0%{%4%}, %3, %2}
+ vfmsubadd213<ssemodesuffix>\t{%3, %2, %0%{%4%}|%0%{%4%}, %2, %3}"
+ [(set_attr "isa" "fma_avx512f,fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "avx512f_fmsubadd_<mode>_mask3"
+ [(set (match_operand:VF_512 0 "register_operand" "=v")
+ (vec_merge:VF_512
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "v")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")
+ (neg:VF_512
+ (match_operand:VF_512 3 "register_operand" "0"))]
+ UNSPEC_FMADDSUB)
+ (match_dup 3)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfmsubadd231<ssemodesuffix>\t{%2, %1, %0%{%4%}|%0%{%4%}, %1, %2}"
+ [(set_attr "isa" "fma_avx512f")
+ (set_attr "type" "ssemuladd")
+ (set_attr "mode" "<MODE>")])
+
;; FMA3 floating point scalar intrinsics. These merge result with
;; high-order elements from the destination register.
@@ -3018,7 +3349,7 @@
[(set (match_operand:DI 0 "register_operand" "=r,r")
(fix:DI
(vec_select:SF
- (match_operand:V4SF 1 "nonimmediate_operand" "v,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" "v,vm")
(parallel [(const_int 0)]))))]
"TARGET_SSE && TARGET_64BIT"
"%vcvttss2si{q}\t{%1, %0|%0, %k1}"
@@ -3058,22 +3389,22 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
-(define_insn "float<sseintvecmodelower><mode>2"
+(define_insn "float<sseintvecmodelower><mode>2<mask_name>"
[(set (match_operand:VF1 0 "register_operand" "=v")
(float:VF1
(match_operand:<sseintvecmode> 1 "nonimmediate_operand" "vm")))]
- "TARGET_SSE2"
- "%vcvtdq2ps\t{%1, %0|%0, %1}"
+ "TARGET_SSE2 && <mask_mode512bit_condition>"
+ "%vcvtdq2ps\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "ufloatv16siv16sf2"
+(define_insn "ufloatv16siv16sf2<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
(unsigned_float:V16SF
(match_operand:V16SI 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vcvtudq2ps\t{%1, %0|%0, %1}"
+ "vcvtudq2ps\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -3108,34 +3439,34 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_fix_notruncv16sfv16si"
+(define_insn "<mask_codefor>avx512f_fix_notruncv16sfv16si<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(unspec:V16SI
[(match_operand:V16SF 1 "nonimmediate_operand" "vm")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_AVX512F"
- "vcvtps2dq\t{%1, %0|%0, %1}"
+ "vcvtps2dq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
-(define_insn "avx512f_ufix_notruncv16sfv16si"
+(define_insn "<mask_codefor>avx512f_ufix_notruncv16sfv16si<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(unspec:V16SI
[(match_operand:V16SF 1 "nonimmediate_operand" "vm")]
UNSPEC_UNSIGNED_FIX_NOTRUNC))]
"TARGET_AVX512F"
- "vcvtps2udq\t{%1, %0|%0, %1}"
+ "vcvtps2udq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
-(define_insn "<fixsuffix>fix_truncv16sfv16si2"
+(define_insn "<fixsuffix>fix_truncv16sfv16si2<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(any_fix:V16SI
(match_operand:V16SF 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vcvttps2<fixsuffix>dq\t{%1, %0|%0, %1}"
+ "vcvttps2<fixsuffix>dq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -3465,20 +3796,21 @@
(define_mode_attr si2dfmodelower
[(V8DF "v8si") (V4DF "v4si")])
-(define_insn "float<si2dfmodelower><mode>2"
+(define_insn "float<si2dfmodelower><mode>2<mask_name>"
[(set (match_operand:VF2_512_256 0 "register_operand" "=v")
(float:VF2_512_256 (match_operand:<si2dfmode> 1 "nonimmediate_operand" "vm")))]
- "TARGET_AVX"
- "vcvtdq2pd\t{%1, %0|%0, %1}"
+ "TARGET_AVX && <mask_mode512bit_condition>"
+ "vcvtdq2pd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")])
-(define_insn "ufloatv8siv8df"
+(define_insn "ufloatv8siv8df<mask_name>"
[(set (match_operand:V8DF 0 "register_operand" "=v")
- (unsigned_float:V8DF (match_operand:V8SI 1 "nonimmediate_operand" "vm")))]
+ (unsigned_float:V8DF
+ (match_operand:V8SI 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vcvtudq2pd\t{%1, %0|%0, %1}"
+ "vcvtudq2pd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "V8DF")])
@@ -3523,12 +3855,13 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V2DF")])
-(define_insn "avx512f_cvtpd2dq512"
+(define_insn "<mask_codefor>avx512f_cvtpd2dq512<mask_name>"
[(set (match_operand:V8SI 0 "register_operand" "=v")
- (unspec:V8SI [(match_operand:V8DF 1 "nonimmediate_operand" "vm")]
- UNSPEC_FIX_NOTRUNC))]
+ (unspec:V8SI
+ [(match_operand:V8DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_FIX_NOTRUNC))]
"TARGET_AVX512F"
- "vcvtpd2dq\t{%1, %0|%0, %1}"
+ "vcvtpd2dq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "OI")])
@@ -3596,22 +3929,23 @@
(set_attr "athlon_decode" "vector")
(set_attr "bdver1_decode" "double")])
-(define_insn "avx512f_ufix_notruncv8dfv8si"
+(define_insn "avx512f_ufix_notruncv8dfv8si<mask_name>"
[(set (match_operand:V8SI 0 "register_operand" "=v")
(unspec:V8SI
[(match_operand:V8DF 1 "nonimmediate_operand" "vm")]
UNSPEC_UNSIGNED_FIX_NOTRUNC))]
"TARGET_AVX512F"
- "vcvtpd2udq\t{%1, %0|%0, %1}"
+ "vcvtpd2udq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "OI")])
-(define_insn "<fixsuffix>fix_truncv8dfv8si2"
+(define_insn "<fixsuffix>fix_truncv8dfv8si2<mask_name>"
[(set (match_operand:V8SI 0 "register_operand" "=v")
- (any_fix:V8SI (match_operand:V8DF 1 "nonimmediate_operand" "vm")))]
+ (any_fix:V8SI
+ (match_operand:V8DF 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vcvttpd2<fixsuffix>dq\t{%1, %0|%0, %1}"
+ "vcvttpd2<fixsuffix>dq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "OI")])
@@ -3717,12 +4051,12 @@
(set_attr "prefix" "orig,orig,vex")
(set_attr "mode" "DF")])
-(define_insn "avx512f_cvtpd2ps512"
+(define_insn "<mask_codefor>avx512f_cvtpd2ps512<mask_name>"
[(set (match_operand:V8SF 0 "register_operand" "=v")
(float_truncate:V8SF
(match_operand:V8DF 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vcvtpd2ps\t{%1, %0|%0, %1}"
+ "vcvtpd2ps\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "V8SF")])
@@ -3772,12 +4106,12 @@
(define_mode_attr sf2dfmode
[(V8DF "V8SF") (V4DF "V4SF")])
-(define_insn "<sse2_avx_avx512f>_cvtps2pd<avxsizesuffix>"
+(define_insn "<sse2_avx_avx512f>_cvtps2pd<avxsizesuffix><mask_name>"
[(set (match_operand:VF2_512_256 0 "register_operand" "=v")
(float_extend:VF2_512_256
(match_operand:<sf2dfmode> 1 "nonimmediate_operand" "vm")))]
- "TARGET_AVX"
- "vcvtps2pd\t{%1, %0|%0, %1}"
+ "TARGET_AVX && <mask_mode512bit_condition>"
+ "vcvtps2pd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")])
@@ -4126,6 +4460,30 @@
DONE;
})
+(define_expand "vec_unpacku_float_lo_v16si"
+ [(match_operand:V8DF 0 "register_operand")
+ (match_operand:V16SI 1 "nonimmediate_operand")]
+ "TARGET_AVX512F"
+{
+ REAL_VALUE_TYPE TWO32r;
+ rtx k, x, tmp[3];
+
+ real_ldexp (&TWO32r, &dconst1, 32);
+ x = const_double_from_real_value (TWO32r, DFmode);
+
+ tmp[0] = force_reg (V8DFmode, CONST0_RTX (V8DFmode));
+ tmp[1] = force_reg (V8DFmode, ix86_build_const_vector (V8DFmode, 1, x));
+ tmp[2] = gen_reg_rtx (V8DFmode);
+ k = gen_reg_rtx (QImode);
+
+ emit_insn (gen_avx512f_cvtdq2pd512_2 (tmp[2], operands[1]));
+ emit_insn (gen_rtx_SET (VOIDmode, k,
+ gen_rtx_LT (QImode, tmp[2], tmp[0])));
+ emit_insn (gen_addv8df3_mask (tmp[2], tmp[2], tmp[1], tmp[2], k));
+ emit_move_insn (operands[0], tmp[2]);
+ DONE;
+})
+
(define_expand "vec_pack_trunc_<mode>"
[(set (match_dup 3)
(float_truncate:<sf2dfmode>
@@ -4415,7 +4773,7 @@
(set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
(set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
-(define_insn "avx512f_unpckhps512"
+(define_insn "<mask_codefor>avx512f_unpckhps512<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
(vec_select:V16SF
(vec_concat:V32SF
@@ -4430,7 +4788,7 @@
(const_int 14) (const_int 30)
(const_int 15) (const_int 31)])))]
"TARGET_AVX512F"
- "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
+ "vunpckhps\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -4503,7 +4861,7 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "V4SF")])
-(define_insn "avx512f_unpcklps512"
+(define_insn "<mask_codefor>avx512f_unpcklps512<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
(vec_select:V16SF
(vec_concat:V32SF
@@ -4518,7 +4876,7 @@
(const_int 12) (const_int 28)
(const_int 13) (const_int 29)])))]
"TARGET_AVX512F"
- "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
+ "vunpcklps\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -4626,7 +4984,7 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
-(define_insn "avx512f_movshdup512"
+(define_insn "<mask_codefor>avx512f_movshdup512<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
(vec_select:V16SF
(vec_concat:V32SF
@@ -4641,7 +4999,7 @@
(const_int 13) (const_int 13)
(const_int 15) (const_int 15)])))]
"TARGET_AVX512F"
- "vmovshdup\t{%1, %0|%0, %1}"
+ "vmovshdup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -4679,7 +5037,7 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
-(define_insn "avx512f_movsldup512"
+(define_insn "<mask_codefor>avx512f_movsldup512<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
(vec_select:V16SF
(vec_concat:V32SF
@@ -4694,7 +5052,7 @@
(const_int 12) (const_int 12)
(const_int 14) (const_int 14)])))]
"TARGET_AVX512F"
- "vmovsldup\t{%1, %0|%0, %1}"
+ "vmovsldup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -5228,8 +5586,71 @@
operands[1] = adjust_address (operands[1], SFmode, INTVAL (operands[2]) * 4);
})
-(define_insn "avx512f_vextract<shuffletype>32x4_1"
- [(set (match_operand:<ssequartermode> 0 "nonimmediate_operand" "=vm")
+(define_expand "avx512f_vextract<shuffletype>32x4_mask"
+ [(match_operand:<ssequartermode> 0 "nonimmediate_operand")
+ (match_operand:V16FI 1 "register_operand")
+ (match_operand:SI 2 "const_0_to_3_operand")
+ (match_operand:<ssequartermode> 3 "nonimmediate_operand")
+ (match_operand:QI 4 "register_operand")]
+ "TARGET_AVX512F"
+{
+ if (MEM_P (operands[0]) && GET_CODE (operands[3]) == CONST_VECTOR)
+ operands[0] = force_reg (<ssequartermode>mode, operands[0]);
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ emit_insn (gen_avx512f_vextract<shuffletype>32x4_1_mask (operands[0],
+ operands[1], GEN_INT (0), GEN_INT (1), GEN_INT (2),
+ GEN_INT (3), operands[3], operands[4]));
+ break;
+ case 1:
+ emit_insn (gen_avx512f_vextract<shuffletype>32x4_1_mask (operands[0],
+ operands[1], GEN_INT (4), GEN_INT (5), GEN_INT (6),
+ GEN_INT (7), operands[3], operands[4]));
+ break;
+ case 2:
+ emit_insn (gen_avx512f_vextract<shuffletype>32x4_1_mask (operands[0],
+ operands[1], GEN_INT (8), GEN_INT (9), GEN_INT (10),
+ GEN_INT (11), operands[3], operands[4]));
+ break;
+ case 3:
+ emit_insn (gen_avx512f_vextract<shuffletype>32x4_1_mask (operands[0],
+ operands[1], GEN_INT (12), GEN_INT (13), GEN_INT (14),
+ GEN_INT (15), operands[3], operands[4]));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ DONE;
+})
+
+(define_insn "avx512f_vextract<shuffletype>32x4_1_maskm"
+ [(set (match_operand:<ssequartermode> 0 "memory_operand" "=m")
+ (vec_merge:<ssequartermode>
+ (vec_select:<ssequartermode>
+ (match_operand:V16FI 1 "register_operand" "v")
+ (parallel [(match_operand 2 "const_0_to_15_operand")
+ (match_operand 3 "const_0_to_15_operand")
+ (match_operand 4 "const_0_to_15_operand")
+ (match_operand 5 "const_0_to_15_operand")]))
+ (match_operand:<ssequartermode> 6 "memory_operand" "0")
+ (match_operand:QI 7 "register_operand" "k")))]
+ "TARGET_AVX512F && (INTVAL (operands[2]) = INTVAL (operands[3]) - 1)
+ && (INTVAL (operands[3]) = INTVAL (operands[4]) - 1)
+ && (INTVAL (operands[4]) = INTVAL (operands[5]) - 1)"
+{
+ operands[2] = GEN_INT ((INTVAL (operands[2])) >> 2);
+ return "vextract<shuffletype>32x4\t{%2, %1, %0%{%7%}|%0%{%7%}, %1, %2}";
+}
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "memory" "store")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "<mask_codefor>avx512f_vextract<shuffletype>32x4_1<mask_name>"
+ [(set (match_operand:<ssequartermode> 0 "<store_mask_predicate>" "=<store_mask_constraint>")
(vec_select:<ssequartermode>
(match_operand:V16FI 1 "register_operand" "v")
(parallel [(match_operand 2 "const_0_to_15_operand")
@@ -5241,7 +5662,7 @@
&& (INTVAL (operands[4]) = INTVAL (operands[5]) - 1)"
{
operands[2] = GEN_INT ((INTVAL (operands[2])) >> 2);
- return "vextract<shuffletype>32x4\t{%2, %1, %0|%0, %1, %2}";
+ return "vextract<shuffletype>32x4\t{%2, %1, %0<mask_operand6>|%0<mask_operand6>, %1, %2}";
}
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
@@ -5253,6 +5674,35 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_expand "avx512f_vextract<shuffletype>64x4_mask"
+ [(match_operand:<ssehalfvecmode> 0 "nonimmediate_operand")
+ (match_operand:V8FI 1 "register_operand")
+ (match_operand:SI 2 "const_0_to_1_operand")
+ (match_operand:<ssehalfvecmode> 3 "nonimmediate_operand")
+ (match_operand:QI 4 "register_operand")]
+ "TARGET_AVX512F"
+{
+ rtx (*insn)(rtx, rtx, rtx, rtx);
+
+ if (MEM_P (operands[0]) && GET_CODE (operands[3]) == CONST_VECTOR)
+ operands[0] = force_reg (<ssequartermode>mode, operands[0]);
+
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ insn = gen_vec_extract_lo_<mode>_mask;
+ break;
+ case 1:
+ insn = gen_vec_extract_hi_<mode>_mask;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ emit_insn (insn (operands[0], operands[1], operands[3], operands[4]));
+ DONE;
+})
+
(define_split
[(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand")
(vec_select:<ssehalfvecmode>
@@ -5272,14 +5722,36 @@
DONE;
})
-(define_insn "vec_extract_lo_<mode>"
- [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=vm")
+(define_insn "vec_extract_lo_<mode>_maskm"
+ [(set (match_operand:<ssehalfvecmode> 0 "memory_operand" "=m")
+ (vec_merge:<ssehalfvecmode>
+ (vec_select:<ssehalfvecmode>
+ (match_operand:V8FI 1 "register_operand" "v")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)]))
+ (match_operand:<ssehalfvecmode> 2 "memory_operand" "0")
+ (match_operand:QI 3 "register_operand" "k")))]
+ "TARGET_AVX512F"
+"vextract<shuffletype>64x4\t{$0x0, %1, %0%{%3%}|%0%{%3%}, %1, 0x0}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "vec_extract_lo_<mode><mask_name>"
+ [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=<store_mask_constraint>")
(vec_select:<ssehalfvecmode>
(match_operand:V8FI 1 "nonimmediate_operand" "vm")
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)])))]
"TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "#"
+{
+ if (<mask_applied>)
+ return "vextract<shuffletype>64x4\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
+ else
+ return "#";
+}
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
@@ -5290,14 +5762,32 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "vec_extract_hi_<mode>"
- [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=vm")
+(define_insn "vec_extract_hi_<mode>_maskm"
+ [(set (match_operand:<ssehalfvecmode> 0 "memory_operand" "=m")
+ (vec_merge:<ssehalfvecmode>
+ (vec_select:<ssehalfvecmode>
+ (match_operand:V8FI 1 "register_operand" "v")
+ (parallel [(const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))
+ (match_operand:<ssehalfvecmode> 2 "memory_operand" "0")
+ (match_operand:QI 3 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vextract<shuffletype>64x4\t{$0x1, %1, %0%{%3%}|%0%{%3%}, %1, 0x1}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "memory" "store")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "vec_extract_hi_<mode><mask_name>"
+ [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=<store_mask_constraint>")
(vec_select:<ssehalfvecmode>
(match_operand:V8FI 1 "register_operand" "v")
(parallel [(const_int 4) (const_int 5)
(const_int 6) (const_int 7)])))]
"TARGET_AVX512F"
- "vextract<shuffletype>64x4\t{$0x1, %1, %0|%0, %1, 0x1}"
+ "vextract<shuffletype>64x4\t{$0x1, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x1}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
@@ -5643,7 +6133,7 @@
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define_insn "avx512f_unpckhpd512"
+(define_insn "<mask_codefor>avx512f_unpckhpd512<mask_name>"
[(set (match_operand:V8DF 0 "register_operand" "=v")
(vec_select:V8DF
(vec_concat:V16DF
@@ -5654,7 +6144,7 @@
(const_int 5) (const_int 13)
(const_int 7) (const_int 15)])))]
"TARGET_AVX512F"
- "vunpckhpd\t{%2, %1, %0|%0, %1, %2}"
+ "vunpckhpd\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "V8DF")])
@@ -5739,7 +6229,7 @@
(set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex")
(set_attr "mode" "V2DF,V2DF,DF,V1DF,V1DF,V1DF")])
-(define_expand "avx512f_movddup512"
+(define_expand "avx512f_movddup512<mask_name>"
[(set (match_operand:V8DF 0 "register_operand")
(vec_select:V8DF
(vec_concat:V16DF
@@ -5751,7 +6241,7 @@
(const_int 6) (const_int 14)])))]
"TARGET_AVX512F")
-(define_expand "avx512f_unpcklpd512"
+(define_expand "avx512f_unpcklpd512<mask_name>"
[(set (match_operand:V8DF 0 "register_operand")
(vec_select:V8DF
(vec_concat:V16DF
@@ -5763,7 +6253,7 @@
(const_int 6) (const_int 14)])))]
"TARGET_AVX512F")
-(define_insn "*avx512f_unpcklpd512"
+(define_insn "*avx512f_unpcklpd512<mask_name>"
[(set (match_operand:V8DF 0 "register_operand" "=v,v")
(vec_select:V8DF
(vec_concat:V16DF
@@ -5775,8 +6265,8 @@
(const_int 6) (const_int 14)])))]
"TARGET_AVX512F"
"@
- vmovddup\t{%1, %0|%0, %1}
- vunpcklpd\t{%2, %1, %0|%0, %1, %2}"
+ vmovddup\t{%1, %0<mask_operand3>|%0<mask_operand3>, %1}
+ vunpcklpd\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "V8DF")])
@@ -5913,12 +6403,13 @@
operands[1] = adjust_address (operands[1], DFmode, INTVAL (operands[2]) * 8);
})
-(define_insn "avx512f_vmscalef<mode>"
+(define_insn "*avx512f_vmscalef<mode>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
- (unspec:VF_128 [(match_operand:VF_128 1 "register_operand" "v")
- (match_operand:VF_128 2 "nonimmediate_operand" "vm")]
- UNSPEC_SCALEF)
+ (unspec:VF_128
+ [(match_operand:VF_128 1 "register_operand" "v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm")]
+ UNSPEC_SCALEF)
(match_dup 1)
(const_int 1)))]
"TARGET_AVX512F"
@@ -5926,13 +6417,14 @@
[(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
-(define_insn "avx512f_scalef<mode>"
+(define_insn "avx512f_scalef<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
- (unspec:VF_512 [(match_operand:VF_512 1 "register_operand" "v")
- (match_operand:VF_512 2 "nonimmediate_operand" "vm")]
- UNSPEC_SCALEF))]
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "v")
+ (match_operand:VF_512 2 "nonimmediate_operand" "vm")]
+ UNSPEC_SCALEF))]
"TARGET_AVX512F"
- "%vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "%vscalef<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
@@ -5950,21 +6442,39 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_getexp<mode>"
+(define_insn "avx512f_vternlog<mode>_mask"
+ [(set (match_operand:VI48_512 0 "register_operand" "=v")
+ (vec_merge:VI48_512
+ (unspec:VI48_512
+ [(match_operand:VI48_512 1 "register_operand" "0")
+ (match_operand:VI48_512 2 "register_operand" "v")
+ (match_operand:VI48_512 3 "nonimmediate_operand" "vm")
+ (match_operand:SI 4 "const_0_to_255_operand")]
+ UNSPEC_VTERNLOG)
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 5 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vpternlog<ssemodesuffix>\t{%4, %3, %2, %0%{%5%}|%0%{%5%}, %2, %3, %4}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "avx512f_getexp<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512 [(match_operand:VF_512 1 "nonimmediate_operand" "vm")]
UNSPEC_GETEXP))]
"TARGET_AVX512F"
- "vgetexp<ssemodesuffix>\t{%1, %0|%0, %1}";
+ "vgetexp<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
(define_insn "avx512f_sgetexp<mode>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
- (unspec:VF_128 [(match_operand:VF_128 1 "register_operand" "v")
- (match_operand:VF_128 2 "nonimmediate_operand" "vm")]
- UNSPEC_GETEXP)
+ (unspec:VF_128
+ [(match_operand:VF_128 1 "register_operand" "v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm")]
+ UNSPEC_GETEXP)
(match_dup 1)
(const_int 1)))]
"TARGET_AVX512F"
@@ -5972,17 +6482,48 @@
[(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
-(define_insn "avx512f_align<mode>"
+(define_insn "<mask_codefor>avx512f_align<mode><mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v")
(unspec:VI48_512 [(match_operand:VI48_512 1 "register_operand" "v")
(match_operand:VI48_512 2 "nonimmediate_operand" "vm")
(match_operand:SI 3 "const_0_to_255_operand")]
UNSPEC_ALIGN))]
"TARGET_AVX512F"
- "valign<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ "valign<ssemodesuffix>\t{%3, %2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2, %3}";
[(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_expand "avx512f_shufps512_mask"
+ [(match_operand:V16SF 0 "register_operand")
+ (match_operand:V16SF 1 "register_operand")
+ (match_operand:V16SF 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_0_to_255_operand")
+ (match_operand:V16SF 4 "register_operand")
+ (match_operand:HI 5 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[3]);
+ emit_insn (gen_avx512f_shufps512_1_mask (operands[0], operands[1], operands[2],
+ GEN_INT ((mask >> 0) & 3),
+ GEN_INT ((mask >> 2) & 3),
+ GEN_INT (((mask >> 4) & 3) + 16),
+ GEN_INT (((mask >> 6) & 3) + 16),
+ GEN_INT (((mask >> 0) & 3) + 4),
+ GEN_INT (((mask >> 2) & 3) + 4),
+ GEN_INT (((mask >> 4) & 3) + 20),
+ GEN_INT (((mask >> 6) & 3) + 20),
+ GEN_INT (((mask >> 0) & 3) + 8),
+ GEN_INT (((mask >> 2) & 3) + 8),
+ GEN_INT (((mask >> 4) & 3) + 24),
+ GEN_INT (((mask >> 6) & 3) + 24),
+ GEN_INT (((mask >> 0) & 3) + 12),
+ GEN_INT (((mask >> 2) & 3) + 12),
+ GEN_INT (((mask >> 4) & 3) + 28),
+ GEN_INT (((mask >> 6) & 3) + 28),
+ operands[4], operands[5]));
+ DONE;
+})
+
(define_insn "avx512f_fixupimm<mode>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
@@ -5996,6 +6537,22 @@
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
+(define_insn "avx512f_fixupimm<mode>_mask"
+ [(set (match_operand:VF_512 0 "register_operand" "=v")
+ (vec_merge:VF_512
+ (unspec:VF_512
+ [(match_operand:VF_512 1 "register_operand" "0")
+ (match_operand:VF_512 2 "register_operand" "v")
+ (match_operand:<sseintvecmode> 3 "nonimmediate_operand" "vm")
+ (match_operand:SI 4 "const_0_to_255_operand")]
+ UNSPEC_FIXUPIMM)
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 5 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfixupimm<ssemodesuffix>\t{%4, %3, %2, %0%{%5%}|%0%{%5%}, %2, %3, %4}";
+ [(set_attr "prefix" "evex")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "avx512f_sfixupimm<mode>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
@@ -6012,19 +6569,38 @@
[(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
-(define_insn "avx512f_rndscale<mode>"
+(define_insn "avx512f_sfixupimm<mode>_mask"
+ [(set (match_operand:VF_128 0 "register_operand" "=v")
+ (vec_merge:VF_128
+ (vec_merge:VF_128
+ (unspec:VF_128
+ [(match_operand:VF_128 1 "register_operand" "0")
+ (match_operand:VF_128 2 "register_operand" "v")
+ (match_operand:<sseintvecmode> 3 "nonimmediate_operand" "vm")
+ (match_operand:SI 4 "const_0_to_255_operand")]
+ UNSPEC_FIXUPIMM)
+ (match_dup 1)
+ (const_int 1))
+ (match_dup 1)
+ (match_operand:<avx512fmaskmode> 5 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vfixupimm<ssescalarmodesuffix>\t{%4, %3, %2, %0%{%5%}|%0%{%5%}, %2, %3, %4}";
+ [(set_attr "prefix" "evex")
+ (set_attr "mode" "<ssescalarmode>")])
+
+(define_insn "avx512f_rndscale<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")
(match_operand:SI 2 "const_0_to_255_operand")]
UNSPEC_ROUND))]
"TARGET_AVX512F"
- "vrndscale<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "vrndscale<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
-(define_insn "avx512f_rndscale<mode>"
+(define_insn "*avx512f_rndscale<mode>"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
(unspec:VF_128
@@ -6041,7 +6617,7 @@
(set_attr "mode" "<MODE>")])
;; One bit in mask selects 2 elements.
-(define_insn "avx512f_shufps512_1"
+(define_insn "avx512f_shufps512_1<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
(vec_select:V16SF
(vec_concat:V32SF
@@ -6084,14 +6660,37 @@
mask |= (INTVAL (operands[6]) - 16) << 6;
operands[3] = GEN_INT (mask);
- return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ return "vshufps\t{%3, %2, %1, %0<mask_operand19>|%0<mask_operand19>, %1, %2, %3}";
}
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
-(define_insn "avx512f_shufpd512_1"
+(define_expand "avx512f_shufpd512_mask"
+ [(match_operand:V8DF 0 "register_operand")
+ (match_operand:V8DF 1 "register_operand")
+ (match_operand:V8DF 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_0_to_255_operand")
+ (match_operand:V8DF 4 "register_operand")
+ (match_operand:QI 5 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[3]);
+ emit_insn (gen_avx512f_shufpd512_1_mask (operands[0], operands[1], operands[2],
+ GEN_INT (mask & 1),
+ GEN_INT (mask & 2 ? 9 : 8),
+ GEN_INT (mask & 4 ? 3 : 2),
+ GEN_INT (mask & 8 ? 11 : 10),
+ GEN_INT (mask & 16 ? 5 : 4),
+ GEN_INT (mask & 32 ? 13 : 12),
+ GEN_INT (mask & 64 ? 7 : 6),
+ GEN_INT (mask & 128 ? 15 : 14),
+ operands[4], operands[5]));
+ DONE;
+})
+
+(define_insn "avx512f_shufpd512_1<mask_name>"
[(set (match_operand:V8DF 0 "register_operand" "=v")
(vec_select:V8DF
(vec_concat:V16DF
@@ -6118,7 +6717,7 @@
mask |= (INTVAL (operands[10]) - 14) << 7;
operands[3] = GEN_INT (mask);
- return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ return "vshufpd\t{%3, %2, %1, %0<mask_operand11>|%0<mask_operand11>, %1, %2, %3}";
}
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
@@ -6198,7 +6797,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
-(define_insn "avx512f_interleave_highv8di"
+(define_insn "<mask_codefor>avx512f_interleave_highv8di<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(vec_select:V8DI
(vec_concat:V16DI
@@ -6209,7 +6808,7 @@
(const_int 5) (const_int 13)
(const_int 7) (const_int 15)])))]
"TARGET_AVX512F"
- "vpunpckhqdq\t{%2, %1, %0|%0, %1, %2}"
+ "vpunpckhqdq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -6248,7 +6847,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
-(define_insn "avx512f_interleave_lowv8di"
+(define_insn "<mask_codefor>avx512f_interleave_lowv8di<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(vec_select:V8DI
(vec_concat:V16DI
@@ -6259,7 +6858,7 @@
(const_int 4) (const_int 12)
(const_int 6) (const_int 14)])))]
"TARGET_AVX512F"
- "vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}"
+ "vpunpcklqdq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -6630,6 +7229,20 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_insn "avx512f_<code><pmov_src_lower><mode>2_mask"
+ [(set (match_operand:PMOV_DST_MODE 0 "nonimmediate_operand" "=v,m")
+ (vec_merge:PMOV_DST_MODE
+ (any_truncate:PMOV_DST_MODE
+ (match_operand:<pmov_src_mode> 1 "register_operand" "v,v"))
+ (match_operand:PMOV_DST_MODE 2 "vector_move_operand" "0C,0")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "k,k")))]
+ "TARGET_AVX512F"
+ "vpmov<trunsuffix><pmov_suff>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "memory" "none,store")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "*avx512f_<code>v8div16qi2"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(vec_concat:V16QI
@@ -6663,6 +7276,55 @@
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
+(define_insn "avx512f_<code>v8div16qi2_mask"
+ [(set (match_operand:V16QI 0 "register_operand" "=v")
+ (vec_concat:V16QI
+ (vec_merge:V8QI
+ (any_truncate:V8QI
+ (match_operand:V8DI 1 "register_operand" "v"))
+ (vec_select:V8QI
+ (match_operand:V16QI 2 "vector_move_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)
+ (const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))
+ (match_operand:QI 3 "register_operand" "k"))
+ (const_vector:V8QI [(const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)])))]
+ "TARGET_AVX512F"
+ "vpmov<trunsuffix>qb\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*avx512f_<code>v8div16qi2_store_mask"
+ [(set (match_operand:V16QI 0 "memory_operand" "=m")
+ (vec_concat:V16QI
+ (vec_merge:V8QI
+ (any_truncate:V8QI
+ (match_operand:V8DI 1 "register_operand" "v"))
+ (vec_select:V8QI
+ (match_dup 0)
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)
+ (const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))
+ (match_operand:QI 2 "register_operand" "k"))
+ (vec_select:V8QI
+ (match_dup 0)
+ (parallel [(const_int 8) (const_int 9)
+ (const_int 10) (const_int 11)
+ (const_int 12) (const_int 13)
+ (const_int 14) (const_int 15)]))))]
+ "TARGET_AVX512F"
+ "vpmov<trunsuffix>qb\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "memory" "store")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Parallel integral arithmetic
@@ -6677,27 +7339,27 @@
"TARGET_SSE2"
"operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
-(define_expand "<plusminus_insn><mode>3"
+(define_expand "<plusminus_insn><mode>3<mask_name>"
[(set (match_operand:VI_AVX2 0 "register_operand")
(plusminus:VI_AVX2
(match_operand:VI_AVX2 1 "nonimmediate_operand")
(match_operand:VI_AVX2 2 "nonimmediate_operand")))]
- "TARGET_SSE2"
+ "TARGET_SSE2 && <mask_mode512bit_condition>"
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
-(define_insn "*<plusminus_insn><mode>3"
+(define_insn "*<plusminus_insn><mode>3<mask_name>"
[(set (match_operand:VI_AVX2 0 "register_operand" "=x,v")
(plusminus:VI_AVX2
(match_operand:VI_AVX2 1 "nonimmediate_operand" "<comm>0,v")
(match_operand:VI_AVX2 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) && <mask_mode512bit_condition>"
"@
p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
- vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseiadd")
(set_attr "prefix_data16" "1,*")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "mode" "<sseinsnmode>")])
(define_expand "<sse2_avx2>_<plusminus_insn><mode>3"
@@ -6787,7 +7449,7 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_expand "vec_widen_umult_even_v16si"
+(define_expand "vec_widen_umult_even_v16si<mask_name>"
[(set (match_operand:V8DI 0 "register_operand")
(mult:V8DI
(zero_extend:V8DI
@@ -6807,7 +7469,7 @@
"TARGET_AVX512F"
"ix86_fixup_binary_operands_no_copy (MULT, V16SImode, operands);")
-(define_insn "*vec_widen_umult_even_v16si"
+(define_insn "*vec_widen_umult_even_v16si<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(mult:V8DI
(zero_extend:V8DI
@@ -6825,7 +7487,7 @@
(const_int 8) (const_int 10)
(const_int 12) (const_int 14)])))))]
"TARGET_AVX512F && ix86_binary_operator_ok (MULT, V16SImode, operands)"
- "vpmuludq\t{%2, %1, %0|%0, %1, %2}"
+ "vpmuludq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "avx512f")
(set_attr "type" "sseimul")
(set_attr "prefix_extra" "1")
@@ -6902,7 +7564,7 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "TI")])
-(define_expand "vec_widen_smult_even_v16si"
+(define_expand "vec_widen_smult_even_v16si<mask_name>"
[(set (match_operand:V8DI 0 "register_operand")
(mult:V8DI
(sign_extend:V8DI
@@ -6922,7 +7584,7 @@
"TARGET_AVX512F"
"ix86_fixup_binary_operands_no_copy (MULT, V16SImode, operands);")
-(define_insn "*vec_widen_smult_even_v16si"
+(define_insn "*vec_widen_smult_even_v16si<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(mult:V8DI
(sign_extend:V8DI
@@ -6940,7 +7602,7 @@
(const_int 8) (const_int 10)
(const_int 12) (const_int 14)])))))]
"TARGET_AVX512F && ix86_binary_operator_ok (MULT, V16SImode, operands)"
- "vpmuldq\t{%2, %1, %0|%0, %1, %2}"
+ "vpmuldq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "avx512f")
(set_attr "type" "sseimul")
(set_attr "prefix_extra" "1")
@@ -7150,12 +7812,12 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "TI")])
-(define_expand "mul<mode>3"
+(define_expand "mul<mode>3<mask_name>"
[(set (match_operand:VI4_AVX512F 0 "register_operand")
(mult:VI4_AVX512F
(match_operand:VI4_AVX512F 1 "general_vector_operand")
(match_operand:VI4_AVX512F 2 "general_vector_operand")))]
- "TARGET_SSE2"
+ "TARGET_SSE2 && <mask_mode512bit_condition>"
{
if (TARGET_SSE4_1)
{
@@ -7172,19 +7834,19 @@
}
})
-(define_insn "*<sse4_1_avx2>_mul<mode>3"
+(define_insn "*<sse4_1_avx2>_mul<mode>3<mask_name>"
[(set (match_operand:VI4_AVX512F 0 "register_operand" "=x,v")
(mult:VI4_AVX512F
(match_operand:VI4_AVX512F 1 "nonimmediate_operand" "%0,v")
(match_operand:VI4_AVX512F 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
+ "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, <MODE>mode, operands) && <mask_mode512bit_condition>"
"@
pmulld\t{%2, %0|%0, %2}
- vpmulld\t{%2, %1, %0|%0, %1, %2}"
+ vpmulld\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseimul")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set_attr "btver2_decode" "vector,vector")
(set_attr "mode" "<sseinsnmode>")])
@@ -7297,6 +7959,20 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "<sseinsnmode>")])
+(define_insn "ashr<mode>3<mask_name>"
+ [(set (match_operand:VI48_512 0 "register_operand" "=v,v")
+ (ashiftrt:VI48_512
+ (match_operand:VI48_512 1 "nonimmediate_operand" "v,vm")
+ (match_operand:SI 2 "nonmemory_operand" "v,N")))]
+ "TARGET_AVX512F && <mask_mode512bit_condition>"
+ "vpsra<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand")
+ (const_string "1")
+ (const_string "0")))
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "<shift_insn><mode>3"
[(set (match_operand:VI248_AVX2 0 "register_operand" "=x,x")
(any_lshift:VI248_AVX2
@@ -7316,13 +7992,13 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<shift_insn><mode>3"
+(define_insn "<shift_insn><mode>3<mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v,v")
(any_lshift:VI48_512
(match_operand:VI48_512 1 "register_operand" "v,m")
(match_operand:SI 2 "nonmemory_operand" "vN,N")))]
- "TARGET_AVX512F"
- "vp<vshift><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "TARGET_AVX512F && <mask_mode512bit_condition>"
+ "vp<vshift><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "isa" "avx512f")
(set_attr "type" "sseishft")
(set (attr "length_immediate")
@@ -7332,6 +8008,7 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+
(define_expand "vec_shl_<mode>"
[(set (match_dup 3)
(ashift:V1TI
@@ -7411,41 +8088,42 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_<rotate>v<mode>"
+(define_insn "avx512f_<rotate>v<mode><mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v")
(any_rotate:VI48_512
(match_operand:VI48_512 1 "register_operand" "v")
(match_operand:VI48_512 2 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vp<rotate>v<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "vp<rotate>v<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_<rotate><mode>"
+(define_insn "avx512f_<rotate><mode><mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v")
(any_rotate:VI48_512
(match_operand:VI48_512 1 "nonimmediate_operand" "vm")
(match_operand:SI 2 "const_0_to_255_operand")))]
"TARGET_AVX512F"
- "vp<rotate><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "vp<rotate><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_expand "<code><mode>3"
+(define_expand "<code><mode>3<mask_name>"
[(set (match_operand:VI124_256_48_512 0 "register_operand")
(maxmin:VI124_256_48_512
(match_operand:VI124_256_48_512 1 "nonimmediate_operand")
(match_operand:VI124_256_48_512 2 "nonimmediate_operand")))]
- "TARGET_AVX2"
+ "TARGET_AVX2 && <mask_mode512bit_condition>"
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
-(define_insn "*avx2_<code><mode>3"
+(define_insn "*avx2_<code><mode>3<mask_name>"
[(set (match_operand:VI124_256_48_512 0 "register_operand" "=v")
(maxmin:VI124_256_48_512
(match_operand:VI124_256_48_512 1 "nonimmediate_operand" "%v")
(match_operand:VI124_256_48_512 2 "nonimmediate_operand" "vm")))]
- "TARGET_AVX2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "vp<maxmin_int><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "TARGET_AVX2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
+ && <mask_mode512bit_condition>"
+ "vp<maxmin_int><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sseiadd")
(set_attr "prefix_extra" "1")
(set_attr "prefix" "maybe_evex")
@@ -7981,19 +8659,19 @@
operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
})
-(define_expand "<sse2_avx2>_andnot<mode>3"
+(define_expand "<sse2_avx2>_andnot<mode>3<mask_name>"
[(set (match_operand:VI_AVX2 0 "register_operand")
(and:VI_AVX2
(not:VI_AVX2 (match_operand:VI_AVX2 1 "register_operand"))
(match_operand:VI_AVX2 2 "nonimmediate_operand")))]
- "TARGET_SSE2")
+ "TARGET_SSE2 && <mask_mode512bit_condition>")
-(define_insn "*andnot<mode>3"
+(define_insn "*andnot<mode>3<mask_name>"
[(set (match_operand:VI 0 "register_operand" "=x,v")
(and:VI
(not:VI (match_operand:VI 1 "register_operand" "0,v"))
(match_operand:VI 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE"
+ "TARGET_SSE && <mask_mode512bit_condition>"
{
static char buf[64];
const char *ops;
@@ -8033,7 +8711,7 @@
ops = "%s\t{%%2, %%0|%%0, %%2}";
break;
case 1:
- ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+ ops = "v%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
break;
default:
gcc_unreachable ();
@@ -8050,7 +8728,7 @@
(eq_attr "mode" "TI"))
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set (attr "mode")
(cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
(const_string "<ssePSmode>")
@@ -8078,12 +8756,12 @@
DONE;
})
-(define_insn "*<code><mode>3"
+(define_insn "<mask_codefor><code><mode>3<mask_name>"
[(set (match_operand:VI 0 "register_operand" "=x,v")
(any_logic:VI
(match_operand:VI 1 "nonimmediate_operand" "%0,v")
(match_operand:VI 2 "nonimmediate_operand" "xm,vm")))]
- "TARGET_SSE
+ "TARGET_SSE && <mask_mode512bit_condition>
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
{
static char buf[64];
@@ -8125,7 +8803,7 @@
ops = "%s\t{%%2, %%0|%%0, %%2}";
break;
case 1:
- ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+ ops = "v%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
break;
default:
gcc_unreachable ();
@@ -8142,7 +8820,7 @@
(eq_attr "mode" "TI"))
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "<mask_prefix3>")
(set (attr "mode")
(cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
(const_string "<ssePSmode>")
@@ -8450,7 +9128,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
-(define_insn "avx512f_interleave_highv16si"
+(define_insn "<mask_codefor>avx512f_interleave_highv16si<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(vec_select:V16SI
(vec_concat:V32SI
@@ -8465,7 +9143,7 @@
(const_int 14) (const_int 30)
(const_int 15) (const_int 31)])))]
"TARGET_AVX512F"
- "vpunpckhdq\t{%2, %1, %0|%0, %1, %2}"
+ "vpunpckhdq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -8505,7 +9183,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
-(define_insn "avx512f_interleave_lowv16si"
+(define_insn "<mask_codefor>avx512f_interleave_lowv16si<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(vec_select:V16SI
(vec_concat:V32SI
@@ -8520,7 +9198,7 @@
(const_int 12) (const_int 28)
(const_int 13) (const_int 29)])))]
"TARGET_AVX512F"
- "vpunpckldq\t{%2, %1, %0|%0, %1, %2}"
+ "vpunpckldq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -8645,7 +9323,45 @@
(set_attr "prefix" "orig,orig,vex,vex")
(set_attr "mode" "TI")])
-(define_insn "avx512f_vinsert<shuffletype>32x4_1"
+(define_expand "avx512f_vinsert<shuffletype>32x4_mask"
+ [(match_operand:V16FI 0 "register_operand")
+ (match_operand:V16FI 1 "register_operand")
+ (match_operand:<ssequartermode> 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_0_to_3_operand")
+ (match_operand:V16FI 4 "register_operand")
+ (match_operand:<avx512fmaskmode> 5 "register_operand")]
+ "TARGET_AVX512F"
+{
+ switch (INTVAL (operands[3]))
+ {
+ case 0:
+ emit_insn (gen_avx512f_vinsert<shuffletype>32x4_1_mask (operands[0],
+ operands[1], operands[2], GEN_INT (0xFFF), operands[4],
+ operands[5]));
+ break;
+ case 1:
+ emit_insn (gen_avx512f_vinsert<shuffletype>32x4_1_mask (operands[0],
+ operands[1], operands[2], GEN_INT (0xF0FF), operands[4],
+ operands[5]));
+ break;
+ case 2:
+ emit_insn (gen_avx512f_vinsert<shuffletype>32x4_1_mask (operands[0],
+ operands[1], operands[2], GEN_INT (0xFF0F), operands[4],
+ operands[5]));
+ break;
+ case 3:
+ emit_insn (gen_avx512f_vinsert<shuffletype>32x4_1_mask (operands[0],
+ operands[1], operands[2], GEN_INT (0xFFF0), operands[4],
+ operands[5]));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ DONE;
+
+})
+
+(define_insn "<mask_codefor>avx512f_vinsert<shuffletype>32x4_1<mask_name>"
[(set (match_operand:V16FI 0 "register_operand" "=v")
(vec_merge:V16FI
(match_operand:V16FI 1 "register_operand" "v")
@@ -8668,14 +9384,35 @@
operands[3] = GEN_INT (mask);
- return "vinsert<shuffletype>32x4\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ return "vinsert<shuffletype>32x4\t{%3, %2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2, %3}";
}
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "vec_set_lo_<mode>"
+(define_expand "avx512f_vinsert<shuffletype>64x4_mask"
+ [(match_operand:V8FI 0 "register_operand")
+ (match_operand:V8FI 1 "register_operand")
+ (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_0_to_1_operand")
+ (match_operand:V8FI 4 "register_operand")
+ (match_operand:<avx512fmaskmode> 5 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[3]);
+ if (mask == 0)
+ emit_insn (gen_vec_set_lo_<mode>_mask
+ (operands[0], operands[1], operands[2],
+ operands[4], operands[5]));
+ else
+ emit_insn (gen_vec_set_hi_<mode>_mask
+ (operands[0], operands[1], operands[2],
+ operands[4], operands[5]));
+ DONE;
+})
+
+(define_insn "vec_set_lo_<mode><mask_name>"
[(set (match_operand:V8FI 0 "register_operand" "=v")
(vec_concat:V8FI
(match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "vm")
@@ -8684,13 +9421,13 @@
(parallel [(const_int 4) (const_int 5)
(const_int 6) (const_int 7)]))))]
"TARGET_AVX512F"
- "vinsert<shuffletype>64x4\t{$0x0, %2, %1, %0|%0, %1, %2, $0x0}"
+ "vinsert<shuffletype>64x4\t{$0x0, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, $0x0}"
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
-(define_insn "vec_set_hi_<mode>"
+(define_insn "vec_set_hi_<mode><mask_name>"
[(set (match_operand:V8FI 0 "register_operand" "=v")
(vec_concat:V8FI
(match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "vm")
@@ -8699,13 +9436,37 @@
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)]))))]
"TARGET_AVX512F"
- "vinsert<shuffletype>64x4\t{$0x1, %2, %1, %0|%0, %1, %2, $0x1}"
+ "vinsert<shuffletype>64x4\t{$0x1, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, $0x1}"
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
-(define_insn "avx512f_shuf_<shuffletype>64x2_1"
+(define_expand "avx512f_shuf_<shuffletype>64x2_mask"
+ [(match_operand:V8FI 0 "register_operand")
+ (match_operand:V8FI 1 "register_operand")
+ (match_operand:V8FI 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_0_to_255_operand")
+ (match_operand:V8FI 4 "register_operand")
+ (match_operand:QI 5 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[3]);
+ emit_insn (gen_avx512f_shuf_<shuffletype>64x2_1_mask
+ (operands[0], operands[1], operands[2],
+ GEN_INT (((mask >> 0) & 3) * 2),
+ GEN_INT (((mask >> 0) & 3) * 2 + 1),
+ GEN_INT (((mask >> 2) & 3) * 2),
+ GEN_INT (((mask >> 2) & 3) * 2 + 1),
+ GEN_INT (((mask >> 4) & 3) * 2 + 8),
+ GEN_INT (((mask >> 4) & 3) * 2 + 9),
+ GEN_INT (((mask >> 6) & 3) * 2 + 8),
+ GEN_INT (((mask >> 6) & 3) * 2 + 9),
+ operands[4], operands[5]));
+ DONE;
+})
+
+(define_insn "avx512f_shuf_<shuffletype>64x2_1<mask_name>"
[(set (match_operand:V8FI 0 "register_operand" "=v")
(vec_select:V8FI
(vec_concat:<ssedoublemode>
@@ -8732,14 +9493,46 @@
mask |= (INTVAL (operands[9]) - 8) / 2 << 6;
operands[3] = GEN_INT (mask);
- return "vshuf<shuffletype>64x2\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ return "vshuf<shuffletype>64x2\t{%3, %2, %1, %0<mask_operand11>|%0<mask_operand11>, %1, %2, %3}";
}
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_shuf_<shuffletype>32x4_1"
+(define_expand "avx512f_shuf_<shuffletype>32x4_mask"
+ [(match_operand:V16FI 0 "register_operand")
+ (match_operand:V16FI 1 "register_operand")
+ (match_operand:V16FI 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_0_to_255_operand")
+ (match_operand:V16FI 4 "register_operand")
+ (match_operand:HI 5 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[3]);
+ emit_insn (gen_avx512f_shuf_<shuffletype>32x4_1_mask
+ (operands[0], operands[1], operands[2],
+ GEN_INT (((mask >> 0) & 3) * 4),
+ GEN_INT (((mask >> 0) & 3) * 4 + 1),
+ GEN_INT (((mask >> 0) & 3) * 4 + 2),
+ GEN_INT (((mask >> 0) & 3) * 4 + 3),
+ GEN_INT (((mask >> 2) & 3) * 4),
+ GEN_INT (((mask >> 2) & 3) * 4 + 1),
+ GEN_INT (((mask >> 2) & 3) * 4 + 2),
+ GEN_INT (((mask >> 2) & 3) * 4 + 3),
+ GEN_INT (((mask >> 4) & 3) * 4 + 16),
+ GEN_INT (((mask >> 4) & 3) * 4 + 17),
+ GEN_INT (((mask >> 4) & 3) * 4 + 18),
+ GEN_INT (((mask >> 4) & 3) * 4 + 19),
+ GEN_INT (((mask >> 6) & 3) * 4 + 16),
+ GEN_INT (((mask >> 6) & 3) * 4 + 17),
+ GEN_INT (((mask >> 6) & 3) * 4 + 18),
+ GEN_INT (((mask >> 6) & 3) * 4 + 19),
+ operands[4], operands[5]));
+ DONE;
+})
+
+(define_insn "avx512f_shuf_<shuffletype>32x4_1<mask_name>"
[(set (match_operand:V16FI 0 "register_operand" "=v")
(vec_select:V16FI
(vec_concat:<ssedoublemode>
@@ -8782,14 +9575,44 @@
mask |= (INTVAL (operands[15]) - 16) / 4 << 6;
operands[3] = GEN_INT (mask);
- return "vshuf<shuffletype>32x4\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ return "vshuf<shuffletype>32x4\t{%3, %2, %1, %0<mask_operand19>|%0<mask_operand19>, %1, %2, %3}";
}
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_pshufd_1"
+(define_expand "avx512f_pshufdv3_mask"
+ [(match_operand:V16SI 0 "register_operand")
+ (match_operand:V16SI 1 "nonimmediate_operand")
+ (match_operand:SI 2 "const_0_to_255_operand")
+ (match_operand:V16SI 3 "register_operand")
+ (match_operand:HI 4 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[2]);
+ emit_insn (gen_avx512f_pshufd_1_mask (operands[0], operands[1],
+ GEN_INT ((mask >> 0) & 3),
+ GEN_INT ((mask >> 2) & 3),
+ GEN_INT ((mask >> 4) & 3),
+ GEN_INT ((mask >> 6) & 3),
+ GEN_INT (((mask >> 0) & 3) + 4),
+ GEN_INT (((mask >> 2) & 3) + 4),
+ GEN_INT (((mask >> 4) & 3) + 4),
+ GEN_INT (((mask >> 6) & 3) + 4),
+ GEN_INT (((mask >> 0) & 3) + 8),
+ GEN_INT (((mask >> 2) & 3) + 8),
+ GEN_INT (((mask >> 4) & 3) + 8),
+ GEN_INT (((mask >> 6) & 3) + 8),
+ GEN_INT (((mask >> 0) & 3) + 12),
+ GEN_INT (((mask >> 2) & 3) + 12),
+ GEN_INT (((mask >> 4) & 3) + 12),
+ GEN_INT (((mask >> 6) & 3) + 12),
+ operands[3], operands[4]));
+ DONE;
+})
+
+(define_insn "avx512f_pshufd_1<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(vec_select:V16SI
(match_operand:V16SI 1 "nonimmediate_operand" "vm")
@@ -8830,7 +9653,7 @@
mask |= INTVAL (operands[5]) << 6;
operands[2] = GEN_INT (mask);
- return "vpshufd\t{%2, %1, %0|%0, %1, %2}";
+ return "vpshufd\t{%2, %1, %0<mask_operand18>|%0<mask_operand18>, %1, %2}";
}
[(set_attr "type" "sselog1")
(set_attr "prefix" "evex")
@@ -10281,12 +11104,12 @@
(set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
-(define_insn "*abs<mode>2"
+(define_insn "<mask_codefor>abs<mode>2<mask_name>"
[(set (match_operand:VI124_AVX2_48_AVX512F 0 "register_operand" "=v")
(abs:VI124_AVX2_48_AVX512F
(match_operand:VI124_AVX2_48_AVX512F 1 "nonimmediate_operand" "vm")))]
- "TARGET_SSSE3"
- "%vpabs<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "TARGET_SSSE3 && <mask_mode512bit_condition>"
+ "%vpabs<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sselog1")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
@@ -10640,12 +11463,12 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
-(define_insn "avx512f_<code>v16qiv16si2"
+(define_insn "<mask_codefor>avx512f_<code>v16qiv16si2<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(any_extend:V16SI
(match_operand:V16QI 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vpmov<extsuffix>bd\t{%1, %0|%0, %q1}"
+ "vpmov<extsuffix>bd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %q1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -10680,12 +11503,12 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
-(define_insn "avx512f_<code>v16hiv16si2"
+(define_insn "avx512f_<code>v16hiv16si2<mask_name>"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(any_extend:V16SI
(match_operand:V16HI 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vpmov<extsuffix>wd\t{%1, %0|%0, %1}"
+ "vpmov<extsuffix>wd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -10715,7 +11538,7 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
-(define_insn "avx512f_<code>v8qiv8di2"
+(define_insn "avx512f_<code>v8qiv8di2<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(any_extend:V8DI
(vec_select:V8QI
@@ -10725,7 +11548,7 @@
(const_int 4) (const_int 5)
(const_int 6) (const_int 7)]))))]
"TARGET_AVX512F"
- "vpmov<extsuffix>bq\t{%1, %0|%0, %k1}"
+ "vpmov<extsuffix>bq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %k1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -10757,12 +11580,12 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
-(define_insn "avx512f_<code>v8hiv8di2"
+(define_insn "avx512f_<code>v8hiv8di2<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(any_extend:V8DI
(match_operand:V8HI 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vpmov<extsuffix>wq\t{%1, %0|%0, %q1}"
+ "vpmov<extsuffix>wq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %q1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -10794,12 +11617,12 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
-(define_insn "avx512f_<code>v8siv8di2"
+(define_insn "avx512f_<code>v8siv8di2<mask_name>"
[(set (match_operand:V8DI 0 "register_operand" "=v")
(any_extend:V8DI
(match_operand:V8SI 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vpmov<extsuffix>dq\t{%1, %0|%0, %1}"
+ "vpmov<extsuffix>dq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
@@ -11582,33 +12405,33 @@
(set_attr "prefix" "evex")
(set_attr "mode" "XI")])
-(define_insn "*avx512er_exp2<mode>"
+(define_insn "avx512er_exp2<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")]
UNSPEC_EXP2))]
"TARGET_AVX512ER"
- "vexp2<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vexp2<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
-(define_insn "*avx512er_rcp28<mode>"
+(define_insn "<mask_codefor>avx512er_rcp28<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")]
UNSPEC_RCP28))]
"TARGET_AVX512ER"
- "vrcp28<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vrcp28<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
-(define_insn "avx512er_rsqrt28<mode>"
+(define_insn "<mask_codefor>avx512er_rsqrt28<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")]
UNSPEC_RSQRT28))]
"TARGET_AVX512ER"
- "vrsqrt28<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vrsqrt28<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
@@ -12658,16 +13481,16 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<avx2_avx512f>_permvar<mode>"
+(define_insn "<avx2_avx512f>_permvar<mode><mask_name>"
[(set (match_operand:VI48F_256_512 0 "register_operand" "=v")
(unspec:VI48F_256_512
[(match_operand:VI48F_256_512 1 "nonimmediate_operand" "vm")
(match_operand:<sseintvecmode> 2 "register_operand" "v")]
UNSPEC_VPERMVAR))]
- "TARGET_AVX2"
- "vperm<ssemodesuffix>\t{%1, %2, %0|%0, %2, %1}"
+ "TARGET_AVX2 && <mask_mode512bit_condition>"
+ "vperm<ssemodesuffix>\t{%1, %2, %0<mask_operand3>|%0<mask_operand3>, %2, %1}"
[(set_attr "type" "sselog")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "<mask_prefix2>")
(set_attr "mode" "<sseinsnmode>")])
(define_expand "<avx2_avx512f>_perm<mode>"
@@ -12678,14 +13501,32 @@
{
int mask = INTVAL (operands[2]);
emit_insn (gen_<avx2_avx512f>_perm<mode>_1 (operands[0], operands[1],
- GEN_INT ((mask >> 0) & 3),
- GEN_INT ((mask >> 2) & 3),
- GEN_INT ((mask >> 4) & 3),
- GEN_INT ((mask >> 6) & 3)));
+ GEN_INT ((mask >> 0) & 3),
+ GEN_INT ((mask >> 2) & 3),
+ GEN_INT ((mask >> 4) & 3),
+ GEN_INT ((mask >> 6) & 3)));
+ DONE;
+})
+
+(define_expand "avx512f_perm<mode>_mask"
+ [(match_operand:V8FI 0 "register_operand")
+ (match_operand:V8FI 1 "nonimmediate_operand")
+ (match_operand:SI 2 "const_0_to_255_operand")
+ (match_operand:V8FI 3 "vector_move_operand")
+ (match_operand:<avx512fmaskmode> 4 "register_operand")]
+ "TARGET_AVX512F"
+{
+ int mask = INTVAL (operands[2]);
+ emit_insn (gen_<avx2_avx512f>_perm<mode>_1_mask (operands[0], operands[1],
+ GEN_INT ((mask >> 0) & 3),
+ GEN_INT ((mask >> 2) & 3),
+ GEN_INT ((mask >> 4) & 3),
+ GEN_INT ((mask >> 6) & 3),
+ operands[3], operands[4]));
DONE;
})
-(define_insn "<avx2_avx512f>_perm<mode>_1"
+(define_insn "<avx2_avx512f>_perm<mode>_1<mask_name>"
[(set (match_operand:VI8F_256_512 0 "register_operand" "=v")
(vec_select:VI8F_256_512
(match_operand:VI8F_256_512 1 "nonimmediate_operand" "vm")
@@ -12693,7 +13534,7 @@
(match_operand 3 "const_0_to_3_operand")
(match_operand 4 "const_0_to_3_operand")
(match_operand 5 "const_0_to_3_operand")])))]
- "TARGET_AVX2"
+ "TARGET_AVX2 && <mask_mode512bit_condition>"
{
int mask = 0;
mask |= INTVAL (operands[2]) << 0;
@@ -12701,10 +13542,10 @@
mask |= INTVAL (operands[4]) << 4;
mask |= INTVAL (operands[5]) << 6;
operands[2] = GEN_INT (mask);
- return "vperm<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}";
+ return "vperm<ssemodesuffix>\t{%2, %1, %0<mask_operand6>|%0<mask_operand6>, %1, %2}";
}
[(set_attr "type" "sselog")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "<mask_prefix2>")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "avx2_permv2ti"
@@ -12751,58 +13592,58 @@
(set_attr "isa" "*,avx2,noavx2")
(set_attr "mode" "V8SF")])
-(define_insn "avx512f_vec_dup<mode>"
+(define_insn "<mask_codefor>avx512f_vec_dup<mode><mask_name>"
[(set (match_operand:VI48F_512 0 "register_operand" "=v")
(vec_duplicate:VI48F_512
(vec_select:<ssescalarmode>
(match_operand:<ssexmmmode> 1 "nonimmediate_operand" "vm")
(parallel [(const_int 0)]))))]
"TARGET_AVX512F"
- "v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0|%0, %1}"
+ "v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_broadcast<mode>"
+(define_insn "<mask_codefor>avx512f_broadcast<mode><mask_name>"
[(set (match_operand:V16FI 0 "register_operand" "=v,v")
(vec_duplicate:V16FI
(match_operand:<ssexmmmode> 1 "nonimmediate_operand" "v,m")))]
"TARGET_AVX512F"
"@
- vshuf<shuffletype>32x4\t{$0x0, %g1, %g1, %0|%0, %g1, %g1, 0x0}
- vbroadcast<shuffletype>32x4\t{%1, %0|%0, %1}"
+ vshuf<shuffletype>32x4\t{$0x0, %g1, %g1, %0<mask_operand2>|%0<mask_operand2>, %g1, %g1, 0x0}
+ vbroadcast<shuffletype>32x4\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_broadcast<mode>"
+(define_insn "<mask_codefor>avx512f_broadcast<mode><mask_name>"
[(set (match_operand:V8FI 0 "register_operand" "=v,v")
(vec_duplicate:V8FI
(match_operand:<ssehalfvecmode> 1 "nonimmediate_operand" "v,m")))]
"TARGET_AVX512F"
"@
- vshuf<shuffletype>64x2\t{$0x44, %g1, %g1, %0|%0, %g1, %g1, 0x44}
- vbroadcast<shuffletype>64x4\t{%1, %0|%0, %1}"
+ vshuf<shuffletype>64x2\t{$0x44, %g1, %g1, %0<mask_operand2>|%0<mask_operand2>, %g1, %g1, 0x44}
+ vbroadcast<shuffletype>64x4\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_vec_dup_gpr<mode>"
+(define_insn "<mask_codefor>avx512f_vec_dup_gpr<mode><mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v")
(vec_duplicate:VI48_512
(match_operand:<ssescalarmode> 1 "register_operand" "r")))]
"TARGET_AVX512F && (<MODE>mode != V8DImode || TARGET_64BIT)"
- "vpbroadcast<bcstscalarsuff>\t{%1, %0|%0, %1}"
+ "vpbroadcast<bcstscalarsuff>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_vec_dup_mem<mode>"
+(define_insn "<mask_codefor>avx512f_vec_dup_mem<mode><mask_name>"
[(set (match_operand:VI48F_512 0 "register_operand" "=v")
(vec_duplicate:VI48F_512
(match_operand:<ssescalarmode> 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0|%0, %1}"
+ "v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
@@ -12942,12 +13783,12 @@
elt * GET_MODE_SIZE (<ssescalarmode>mode));
})
-(define_expand "<sse2_avx_avx512f>_vpermil<mode>"
+(define_expand "<sse2_avx_avx512f>_vpermil<mode><mask_name>"
[(set (match_operand:VF2 0 "register_operand")
(vec_select:VF2
(match_operand:VF2 1 "nonimmediate_operand")
(match_operand:SI 2 "const_0_to_255_operand")))]
- "TARGET_AVX"
+ "TARGET_AVX && <mask_mode512bit_condition>"
{
int mask = INTVAL (operands[2]);
rtx perm[<ssescalarnum>];
@@ -12963,12 +13804,12 @@
= gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (<ssescalarnum>, perm));
})
-(define_expand "<sse2_avx_avx512f>_vpermil<mode>"
+(define_expand "<sse2_avx_avx512f>_vpermil<mode><mask_name>"
[(set (match_operand:VF1 0 "register_operand")
(vec_select:VF1
(match_operand:VF1 1 "nonimmediate_operand")
(match_operand:SI 2 "const_0_to_255_operand")))]
- "TARGET_AVX"
+ "TARGET_AVX && <mask_mode512bit_condition>"
{
int mask = INTVAL (operands[2]);
rtx perm[<ssescalarnum>];
@@ -12986,37 +13827,37 @@
= gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (<ssescalarnum>, perm));
})
-(define_insn "*<sse2_avx_avx512f>_vpermilp<mode>"
+(define_insn "*<sse2_avx_avx512f>_vpermilp<mode><mask_name>"
[(set (match_operand:VF 0 "register_operand" "=v")
(vec_select:VF
(match_operand:VF 1 "nonimmediate_operand" "vm")
(match_parallel 2 ""
[(match_operand 3 "const_int_operand")])))]
- "TARGET_AVX
+ "TARGET_AVX && <mask_mode512bit_condition>
&& avx_vpermilp_parallel (operands[2], <MODE>mode)"
{
int mask = avx_vpermilp_parallel (operands[2], <MODE>mode) - 1;
operands[2] = GEN_INT (mask);
- return "vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}";
+ return "vpermil<ssemodesuffix>\t{%2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2}";
}
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "<mask_prefix>")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<sse2_avx_avx512f>_vpermilvar<mode>3"
+(define_insn "<sse2_avx_avx512f>_vpermilvar<mode>3<mask_name>"
[(set (match_operand:VF 0 "register_operand" "=v")
(unspec:VF
[(match_operand:VF 1 "register_operand" "v")
(match_operand:<sseintvecmode> 2 "nonimmediate_operand" "vm")]
UNSPEC_VPERMIL))]
- "TARGET_AVX"
- "vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "TARGET_AVX && <mask_mode512bit_condition>"
+ "vpermil<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "btver2_decode" "vector")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "<mask_prefix>")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "avx512f_vpermi2var<mode>3"
@@ -13032,6 +13873,22 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_insn "avx512f_vpermi2var<mode>3_mask"
+ [(set (match_operand:VI48F_512 0 "register_operand" "=v")
+ (vec_merge:VI48F_512
+ (unspec:VI48F_512
+ [(match_operand:VI48F_512 1 "register_operand" "v")
+ (match_operand:<sseintvecmode> 2 "register_operand" "0")
+ (match_operand:VI48F_512 3 "nonimmediate_operand" "vm")]
+ UNSPEC_VPERMI2_MASK)
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vpermi2<ssemodesuffix>\t{%3, %1, %0%{%4%}|%0%{%4%}, %1, %3}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "avx512f_vpermt2var<mode>3"
[(set (match_operand:VI48F_512 0 "register_operand" "=v")
(unspec:VI48F_512
@@ -13045,6 +13902,22 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_insn "avx512f_vpermt2var<mode>3_mask"
+ [(set (match_operand:VI48F_512 0 "register_operand" "=v")
+ (vec_merge:VI48F_512
+ (unspec:VI48F_512
+ [(match_operand:<sseintvecmode> 1 "register_operand" "v")
+ (match_operand:VI48F_512 2 "register_operand" "0")
+ (match_operand:VI48F_512 3 "nonimmediate_operand" "vm")]
+ UNSPEC_VPERMT2)
+ (match_dup 2)
+ (match_operand:<avx512fmaskmode> 4 "register_operand" "k")))]
+ "TARGET_AVX512F"
+ "vpermt2<ssemodesuffix>\t{%3, %1, %0%{%4%}|%0%{%4%}, %1, %3}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_expand "avx_vperm2f128<mode>3"
[(set (match_operand:AVX256MODE2P 0 "register_operand")
(unspec:AVX256MODE2P
@@ -13435,24 +14308,24 @@
DONE;
})
-(define_insn "<avx2_avx512f>_ashrv<mode>"
+(define_insn "<avx2_avx512f>_ashrv<mode><mask_name>"
[(set (match_operand:VI48_AVX512F 0 "register_operand" "=v")
(ashiftrt:VI48_AVX512F
(match_operand:VI48_AVX512F 1 "register_operand" "v")
(match_operand:VI48_AVX512F 2 "nonimmediate_operand" "vm")))]
- "TARGET_AVX2"
- "vpsrav<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "TARGET_AVX2 && <mask_mode512bit_condition>"
+ "vpsrav<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix" "maybe_evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<avx2_avx512f>_<shift_insn>v<mode>"
+(define_insn "<avx2_avx512f>_<shift_insn>v<mode><mask_name>"
[(set (match_operand:VI48_AVX2_48_AVX512F 0 "register_operand" "=v")
(any_lshift:VI48_AVX2_48_AVX512F
(match_operand:VI48_AVX2_48_AVX512F 1 "register_operand" "v")
(match_operand:VI48_AVX2_48_AVX512F 2 "nonimmediate_operand" "vm")))]
- "TARGET_AVX2"
- "vp<vshift>v<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ "TARGET_AVX2 && <mask_mode512bit_condition>"
+ "vp<vshift>v<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix" "maybe_evex")
(set_attr "mode" "<sseinsnmode>")])
@@ -13535,12 +14408,13 @@
(set_attr "btver2_decode" "double")
(set_attr "mode" "V8SF")])
-(define_insn "avx512f_vcvtph2ps512"
+(define_insn "<mask_codefor>avx512f_vcvtph2ps512<mask_name>"
[(set (match_operand:V16SF 0 "register_operand" "=v")
- (unspec:V16SF [(match_operand:V16HI 1 "nonimmediate_operand" "vm")]
- UNSPEC_VCVTPH2PS))]
+ (unspec:V16SF
+ [(match_operand:V16HI 1 "nonimmediate_operand" "vm")]
+ UNSPEC_VCVTPH2PS))]
"TARGET_AVX512F"
- "vcvtph2ps\t{%1, %0|%0, %1}"
+ "vcvtph2ps\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -13591,13 +14465,14 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "V8SF")])
-(define_insn "avx512f_vcvtps2ph512"
+(define_insn "<mask_codefor>avx512f_vcvtps2ph512<mask_name>"
[(set (match_operand:V16HI 0 "nonimmediate_operand" "=vm")
- (unspec:V16HI [(match_operand:V16SF 1 "register_operand" "v")
- (match_operand:SI 2 "const_0_to_255_operand" "N")]
- UNSPEC_VCVTPS2PH))]
+ (unspec:V16HI
+ [(match_operand:V16SF 1 "register_operand" "v")
+ (match_operand:SI 2 "const_0_to_255_operand" "N")]
+ UNSPEC_VCVTPS2PH))]
"TARGET_AVX512F"
- "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
+ "vcvtps2ph\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "V16SF")])
@@ -13987,14 +14862,55 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "avx512f_getmant<mode>"
+(define_insn "avx512f_compress<mode>_mask"
+ [(set (match_operand:VI48F_512 0 "register_operand" "=v")
+ (unspec:VI48F_512
+ [(match_operand:VI48F_512 1 "register_operand" "v")
+ (match_operand:VI48F_512 2 "vector_move_operand" "0C")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "k")]
+ UNSPEC_COMPRESS))]
+ "TARGET_AVX512F"
+ "v<sseintprefix>compress<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "avx512f_compressstore<mode>_mask"
+ [(set (match_operand:VI48F_512 0 "memory_operand" "=m")
+ (unspec:VI48F_512
+ [(match_operand:VI48F_512 1 "register_operand" "x")
+ (match_dup 0)
+ (match_operand:<avx512fmaskmode> 2 "register_operand" "k")]
+ UNSPEC_COMPRESS_STORE))]
+ "TARGET_AVX512F"
+ "v<sseintprefix>compress<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "memory" "store")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "avx512f_expand<mode>_mask"
+ [(set (match_operand:VI48F_512 0 "register_operand" "=v,v")
+ (unspec:VI48F_512
+ [(match_operand:VI48F_512 1 "nonimmediate_operand" "v,m")
+ (match_operand:VI48F_512 2 "vector_move_operand" "0C,0C")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "k,k")]
+ UNSPEC_EXPAND))]
+ "TARGET_AVX512F"
+ "v<sseintprefix>expand<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "memory" "none,load")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "avx512f_getmant<mode><mask_name>"
[(set (match_operand:VF_512 0 "register_operand" "=v")
(unspec:VF_512
[(match_operand:VF_512 1 "nonimmediate_operand" "vm")
(match_operand:SI 2 "const_0_to_15_operand")]
UNSPEC_GETMANT))]
"TARGET_AVX512F"
- "vgetmant<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}";
+ "vgetmant<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}";
[(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
@@ -14013,23 +14929,23 @@
[(set_attr "prefix" "evex")
(set_attr "mode" "<ssescalarmode>")])
-(define_insn "clz<mode>2"
+(define_insn "clz<mode>2<mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v")
(clz:VI48_512
(match_operand:VI48_512 1 "nonimmediate_operand" "vm")))]
"TARGET_AVX512CD"
- "vplzcnt<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vplzcnt<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "conflict<mode>"
+(define_insn "<mask_codefor>conflict<mode><mask_name>"
[(set (match_operand:VI48_512 0 "register_operand" "=v")
(unspec:VI48_512
[(match_operand:VI48_512 1 "nonimmediate_operand" "vm")]
UNSPEC_CONFLICT))]
"TARGET_AVX512CD"
- "vpconflict<ssemodesuffix>\t{%1, %0|%0, %1}"
+ "vpconflict<ssemodesuffix>\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md
new file mode 100644
index 00000000000..6b45d058f22
--- /dev/null
+++ b/gcc/config/i386/subst.md
@@ -0,0 +1,56 @@
+;; GCC machine description for AVX512F instructions
+;; Copyright (C) 2013 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/>.
+
+;; Some iterators for extending subst as much as possible
+;; All vectors (Use it for destination)
+(define_mode_iterator SUBST_V
+ [V16QI
+ V16HI V8HI
+ V16SI V8SI V4SI
+ V8DI V4DI V2DI
+ V16SF V8SF V4SF
+ V8DF V4DF V2DF])
+
+(define_subst_attr "mask_name" "mask" "" "_mask")
+(define_subst_attr "mask_applied" "mask" "false" "true")
+(define_subst_attr "mask_operand2" "mask" "" "%{%3%}%N2")
+(define_subst_attr "mask_operand3" "mask" "" "%{%4%}%N3")
+(define_subst_attr "mask_operand3_1" "mask" "" "%%{%%4%%}%%N3") ;; for sprintf
+(define_subst_attr "mask_operand4" "mask" "" "%{%5%}%N4")
+(define_subst_attr "mask_operand6" "mask" "" "%{%7%}%N6")
+(define_subst_attr "mask_operand11" "mask" "" "%{%12%}%N11")
+(define_subst_attr "mask_operand18" "mask" "" "%{%19%}%N18")
+(define_subst_attr "mask_operand19" "mask" "" "%{%20%}%N19")
+(define_subst_attr "mask_codefor" "mask" "*" "")
+(define_subst_attr "mask_mode512bit_condition" "mask" "1" "(GET_MODE_SIZE (GET_MODE (operands[0])) == 64)")
+(define_subst_attr "store_mask_constraint" "mask" "vm" "v")
+(define_subst_attr "store_mask_predicate" "mask" "nonimmediate_operand" "register_operand")
+(define_subst_attr "mask_prefix" "mask" "vex" "evex")
+(define_subst_attr "mask_prefix2" "mask" "maybe_vex" "evex")
+(define_subst_attr "mask_prefix3" "mask" "orig,vex" "evex")
+
+(define_subst "mask"
+ [(set (match_operand:SUBST_V 0)
+ (match_operand:SUBST_V 1))]
+ "TARGET_AVX512F"
+ [(set (match_dup 0)
+ (vec_merge:SUBST_V
+ (match_dup 1)
+ (match_operand:SUBST_V 2 "vector_move_operand" "0C")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "k")))])
diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def
index 1a85ce266df..4c13c3a0ec6 100644
--- a/gcc/config/i386/x86-tune.def
+++ b/gcc/config/i386/x86-tune.def
@@ -257,13 +257,13 @@ DEF_TUNE (X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE, "avoid_mem_opnd_for_cmove",
as MOVS and STOS (without a REP prefix) to move/set sequences of bytes. */
DEF_TUNE (X86_TUNE_SINGLE_STRINGOP, "single_stringop", m_386 | m_P4_NOCONA)
-/* TARGET_MISALIGNED_MOVE_STRING_PROLOGUES: Enable generation of compace
- prologues and epilogues by issuing a misaligned moves. This require
- target to handle misaligned moves and partial memory stalls resonably
- well.
- FIXME: This actualy may be a win on more targets than listed here. */
-DEF_TUNE (TARGET_MISALIGNED_MOVE_STRING_PROLOGUES,
- "misaligned_move_string_prologues",
+/* X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES: Enable generation of
+ compact prologues and epilogues by issuing a misaligned moves. This
+ requires target to handle misaligned moves and partial memory stalls
+ reasonably well.
+ FIXME: This may actualy be a win on more targets than listed here. */
+DEF_TUNE (X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES,
+ "misaligned_move_string_pro_epilogues",
m_386 | m_486 | m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC)
/* X86_TUNE_USE_SAHF: Controls use of SAHF. */
@@ -318,12 +318,12 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill",
/* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL: Use movups for misaligned loads instead
of a sequence loading registers by parts. */
DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
- m_COREI7 | m_COREI7_AVX | m_AMDFAM10 | m_BDVER | m_BTVER | m_SLM | m_GENERIC)
+ m_COREI7 | m_COREI7_AVX | m_HASWELL | m_AMDFAM10 | m_BDVER | m_BTVER | m_SLM | m_GENERIC)
/* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores instead
of a sequence loading registers by parts. */
DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal",
- m_COREI7 | m_COREI7_AVX | m_BDVER | m_SLM | m_GENERIC)
+ m_COREI7 | m_COREI7_AVX | m_HASWELL | m_BDVER | m_SLM | m_GENERIC)
/* Use packed single precision instructions where posisble. I.e. movups instead
of movupd. */
@@ -376,15 +376,15 @@ DEF_TUNE (X86_TUNE_USE_VECTOR_CONVERTS, "use_vector_converts", m_AMDFAM10)
/* AVX instruction selection tuning (some of SSE flags affects AVX, too) */
/*****************************************************************************/
-/* X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL: if true, unaligned loads are
+/* X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL: if false, unaligned loads are
split. */
DEF_TUNE (X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL, "256_unaligned_load_optimal",
- ~(m_COREI7 | m_GENERIC))
+ ~(m_COREI7 | m_COREI7_AVX | m_GENERIC))
-/* X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL: if true, unaligned loads are
+/* X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL: if false, unaligned stores are
split. */
-DEF_TUNE (X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL, "256_unaligned_load_optimal",
- ~(m_COREI7 | m_BDVER | m_GENERIC))
+DEF_TUNE (X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL, "256_unaligned_store_optimal",
+ ~(m_COREI7 | m_COREI7_AVX | m_BDVER | m_GENERIC))
/* X86_TUNE_AVX128_OPTIMAL: Enable 128-bit AVX instruction generation for
the auto-vectorizer. */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 1bf3e2fe928..e6bd96df881 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "hash-table.h"
#include "langhooks.h"
#include "gimple.h"
+#include "gimplify.h"
#include "intl.h"
#include "df.h"
#include "debug.h"
@@ -1529,12 +1530,19 @@ ia64_split_tmode_move (rtx operands[])
&& reg_overlap_mentioned_p (operands[0], operands[1]))
{
rtx base = XEXP (operands[1], 0);
+ rtx first_write = gen_rtx_REG (DImode, REGNO (operands[0]));
while (GET_CODE (base) != REG)
base = XEXP (base, 0);
if (REGNO (base) == REGNO (operands[0]))
- reversed = true;
- dead = true;
+ {
+ reversed = true;
+ first_write = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
+ }
+
+ if (GET_CODE (operands[0]) == REG
+ && reg_overlap_mentioned_p (first_write, operands[1]))
+ dead = true;
}
/* Another reason to do the moves in reversed order is if the first
element of the target register pair is also the second element of
diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c
index 7d85436c74c..4f986ed8b5e 100644
--- a/gcc/config/mep/mep.c
+++ b/gcc/config/mep/mep.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "df.h"
#include "gimple.h"
+#include "gimplify.h"
#include "opts.h"
#include "dumpfile.h"
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index d2672133259..80bbb00c2c8 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "sched-int.h"
#include "gimple.h"
+#include "gimplify.h"
#include "bitmap.h"
#include "diagnostic.h"
#include "target-globals.h"
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c
index 09daa685261..7dfcdc7366d 100644
--- a/gcc/config/nds32/nds32.c
+++ b/gcc/config/nds32/nds32.c
@@ -4677,7 +4677,7 @@ nds32_output_casesi_pc_relative (rtx *operands)
enum machine_mode mode;
rtx diff_vec;
- diff_vec = PATTERN (next_active_insn (operands[1]));
+ diff_vec = PATTERN (NEXT_INSN (operands[1]));
gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 9f4b6a4b392..23a425e30cb 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -59,8 +59,6 @@
UNSPEC_VSUMSWS
UNSPEC_VPERM
UNSPEC_VPERM_UNS
- UNSPEC_VPERM_X
- UNSPEC_VPERM_UNS_X
UNSPEC_VRFIN
UNSPEC_VCFUX
UNSPEC_VCFSX
@@ -1393,91 +1391,21 @@
"vrfiz %0,%1"
[(set_attr "type" "vecfloat")])
-(define_insn_and_split "altivec_vperm_<mode>"
+(define_insn "altivec_vperm_<mode>"
[(set (match_operand:VM 0 "register_operand" "=v")
(unspec:VM [(match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")
(match_operand:V16QI 3 "register_operand" "v")]
- UNSPEC_VPERM_X))]
- "TARGET_ALTIVEC"
- "#"
- "!reload_in_progress && !reload_completed"
- [(set (match_dup 0) (match_dup 4))]
-{
- if (BYTES_BIG_ENDIAN)
- operands[4] = gen_rtx_UNSPEC (<MODE>mode,
- gen_rtvec (3, operands[1],
- operands[2], operands[3]),
- UNSPEC_VPERM);
- else
- {
- /* We want to subtract from 31, but we can't vspltisb 31 since
- it's out of range. -1 works as well because only the low-order
- five bits of the permute control vector elements are used. */
- rtx splat = gen_rtx_VEC_DUPLICATE (V16QImode,
- gen_rtx_CONST_INT (QImode, -1));
- rtx tmp = gen_reg_rtx (V16QImode);
- emit_move_insn (tmp, splat);
- rtx sel = gen_rtx_MINUS (V16QImode, tmp, operands[3]);
- emit_move_insn (tmp, sel);
- operands[4] = gen_rtx_UNSPEC (<MODE>mode,
- gen_rtvec (3, operands[2],
- operands[1], tmp),
- UNSPEC_VPERM);
- }
-}
- [(set_attr "type" "vecperm")])
-
-(define_insn "*altivec_vperm_<mode>_internal"
- [(set (match_operand:VM 0 "register_operand" "=v")
- (unspec:VM [(match_operand:VM 1 "register_operand" "v")
- (match_operand:VM 2 "register_operand" "v")
- (match_operand:V16QI 3 "register_operand" "+v")]
UNSPEC_VPERM))]
"TARGET_ALTIVEC"
"vperm %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
-(define_insn_and_split "altivec_vperm_<mode>_uns"
+(define_insn "altivec_vperm_<mode>_uns"
[(set (match_operand:VM 0 "register_operand" "=v")
(unspec:VM [(match_operand:VM 1 "register_operand" "v")
(match_operand:VM 2 "register_operand" "v")
(match_operand:V16QI 3 "register_operand" "v")]
- UNSPEC_VPERM_UNS_X))]
- "TARGET_ALTIVEC"
- "#"
- "!reload_in_progress && !reload_completed"
- [(set (match_dup 0) (match_dup 4))]
-{
- if (BYTES_BIG_ENDIAN)
- operands[4] = gen_rtx_UNSPEC (<MODE>mode,
- gen_rtvec (3, operands[1],
- operands[2], operands[3]),
- UNSPEC_VPERM_UNS);
- else
- {
- /* We want to subtract from 31, but we can't vspltisb 31 since
- it's out of range. -1 works as well because only the low-order
- five bits of the permute control vector elements are used. */
- rtx splat = gen_rtx_VEC_DUPLICATE (V16QImode,
- gen_rtx_CONST_INT (QImode, -1));
- rtx tmp = gen_reg_rtx (V16QImode);
- emit_move_insn (tmp, splat);
- rtx sel = gen_rtx_MINUS (V16QImode, tmp, operands[3]);
- emit_move_insn (tmp, sel);
- operands[4] = gen_rtx_UNSPEC (<MODE>mode,
- gen_rtvec (3, operands[2],
- operands[1], tmp),
- UNSPEC_VPERM_UNS);
- }
-}
- [(set_attr "type" "vecperm")])
-
-(define_insn "*altivec_vperm_<mode>_uns_internal"
- [(set (match_operand:VM 0 "register_operand" "=v")
- (unspec:VM [(match_operand:VM 1 "register_operand" "v")
- (match_operand:VM 2 "register_operand" "v")
- (match_operand:V16QI 3 "register_operand" "+v")]
UNSPEC_VPERM_UNS))]
"TARGET_ALTIVEC"
"vperm %0,%1,%2,%3"
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index c1adbd78a4d..78e84531300 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -25,9 +25,6 @@
#ifndef RS6000_BI_ARCH
-#undef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
-
#undef TARGET_64BIT
#define TARGET_64BIT 1
@@ -88,6 +85,12 @@ extern int dot_symbols;
#define INVALID_64BIT "-m%s not supported in this configuration"
#define INVALID_32BIT INVALID_64BIT
+#ifdef LINUX64_DEFAULT_ABI_ELFv2
+#define ELFv2_ABI_CHECK (rs6000_elf_abi != 1)
+#else
+#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2)
+#endif
+
#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
do \
@@ -102,6 +105,12 @@ extern int dot_symbols;
error (INVALID_64BIT, "call"); \
} \
dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \
+ if (ELFv2_ABI_CHECK) \
+ { \
+ rs6000_current_abi = ABI_ELFv2; \
+ if (dot_symbols) \
+ error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \
+ } \
if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \
{ \
rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \
@@ -355,7 +364,11 @@ extern int dot_symbols;
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
#define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
+#ifdef LINUX64_DEFAULT_ABI_ELFv2
+#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
+#else
+#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
+#endif
#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
#if DEFAULT_LIBC == LIBC_UCLIBC
diff --git a/gcc/config/rs6000/option-defaults.h b/gcc/config/rs6000/option-defaults.h
index 2d7e36a6137..0d7ba1ea3ac 100644
--- a/gcc/config/rs6000/option-defaults.h
+++ b/gcc/config/rs6000/option-defaults.h
@@ -54,6 +54,7 @@
--with-float is ignored if -mhard-float or -msoft-float are
specified. */
#define OPTION_DEFAULT_SPECS \
+ {"abi", "%{!mabi=elfv*:-mabi=%(VALUE)}" }, \
{"tune", "%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}" }, \
{"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \
{"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \
diff --git a/gcc/config/rs6000/ppc-asm.h b/gcc/config/rs6000/ppc-asm.h
index db490b6c9b8..8108efd07f5 100644
--- a/gcc/config/rs6000/ppc-asm.h
+++ b/gcc/config/rs6000/ppc-asm.h
@@ -256,7 +256,30 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
* the real function with one or two leading periods respectively.
*/
-#if defined (__powerpc64__)
+#if defined(__powerpc64__) && _CALL_ELF == 2
+
+/* Defining "toc" above breaks @toc in assembler code. */
+#undef toc
+
+#define FUNC_NAME(name) GLUE(__USER_LABEL_PREFIX__,name)
+#define JUMP_TARGET(name) FUNC_NAME(name)
+#define FUNC_START(name) \
+ .type FUNC_NAME(name),@function; \
+ .globl FUNC_NAME(name); \
+FUNC_NAME(name): \
+0: addis 2,12,(.TOC.-0b)@ha; \
+ addi 2,2,(.TOC.-0b)@l; \
+ .localentry FUNC_NAME(name),.-FUNC_NAME(name)
+
+#define HIDDEN_FUNC(name) \
+ FUNC_START(name) \
+ .hidden FUNC_NAME(name);
+
+#define FUNC_END(name) \
+ .size FUNC_NAME(name),.-FUNC_NAME(name)
+
+#elif defined (__powerpc64__)
+
#define FUNC_NAME(name) GLUE(.,name)
#define JUMP_TARGET(name) FUNC_NAME(name)
#define FUNC_START(name) \
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 97aa1553775..585df9a44f4 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1050,7 +1050,8 @@
(and (match_code "symbol_ref")
(match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
&& ((SYMBOL_REF_LOCAL_P (op)
- && (DEFAULT_ABI != ABI_AIX
+ && ((DEFAULT_ABI != ABI_AIX
+ && DEFAULT_ABI != ABI_ELFv2)
|| !SYMBOL_REF_EXTERNAL_P (op)))
|| (op == XEXP (DECL_RTL (current_function_decl),
0)))")))
@@ -1537,6 +1538,26 @@
return 1;
})
+;; Return 1 if OP is valid for crsave insn, known to be a PARALLEL.
+(define_predicate "crsave_operation"
+ (match_code "parallel")
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ for (i = 1; i < count; i++)
+ {
+ rtx exp = XVECEXP (op, 0, i);
+
+ if (GET_CODE (exp) != USE
+ || GET_CODE (XEXP (exp, 0)) != REG
+ || GET_MODE (XEXP (exp, 0)) != CCmode
+ || ! CR_REGNO_P (REGNO (XEXP (exp, 0))))
+ return 0;
+ }
+ return 1;
+})
+
;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL.
(define_predicate "lmw_operation"
(match_code "parallel")
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 4cf85dbab36..e2e5409d998 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -462,6 +462,10 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
case ABI_AIX:
builtin_define ("_CALL_AIXDESC");
builtin_define ("_CALL_AIX");
+ builtin_define ("_CALL_ELF=1");
+ break;
+ case ABI_ELFv2:
+ builtin_define ("_CALL_ELF=2");
break;
case ABI_DARWIN:
builtin_define ("_CALL_DARWIN");
@@ -474,6 +478,13 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
builtin_define ("__NO_FPRS__");
+ /* Whether aggregates passed by value are aligned to a 16 byte boundary
+ if their alignment is 16 bytes or larger. */
+ if ((TARGET_MACHO && rs6000_darwin64_abi)
+ || DEFAULT_ABI == ABI_ELFv2
+ || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
+ builtin_define ("__STRUCT_PARM_ALIGN__=16");
+
/* Generate defines for Xilinx FPU. */
if (rs6000_xilinx_fpu)
{
diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h
index d528a4fd87a..6d6d69379d5 100644
--- a/gcc/config/rs6000/rs6000-opts.h
+++ b/gcc/config/rs6000/rs6000-opts.h
@@ -107,7 +107,8 @@ enum group_termination
/* Enumeration to give which calling sequence to use. */
enum rs6000_abi {
ABI_NONE,
- ABI_AIX, /* IBM's AIX */
+ ABI_AIX, /* IBM's AIX, or Linux ELFv1 */
+ ABI_ELFv2, /* Linux ELFv2 ABI */
ABI_V4, /* System V.4/eabi */
ABI_DARWIN /* Apple's Darwin (OS X kernel) */
};
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index d1d1737dca1..2ad6f08f47d 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -158,6 +158,7 @@ extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *);
extern rtx rs6000_libcall_value (enum machine_mode);
extern rtx rs6000_va_arg (tree, tree);
extern int function_ok_for_sibcall (tree);
+extern int rs6000_reg_parm_stack_space (tree);
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
extern bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX
@@ -182,7 +183,8 @@ extern unsigned int rs6000_dbx_register_number (unsigned int);
extern void rs6000_emit_epilogue (int);
extern void rs6000_emit_eh_reg_restore (rtx, rtx);
extern const char * output_isel (rtx *);
-extern void rs6000_call_indirect_aix (rtx, rtx, rtx);
+extern void rs6000_call_aix (rtx, rtx, rtx, rtx);
+extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx);
extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
extern void get_ppc476_thunk_name (char name[32]);
extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bc7781c54c2..a2b679c2e3c 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -52,6 +52,9 @@
#include "cfgloop.h"
#include "sched-int.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "intl.h"
#include "params.h"
#include "tm-constrs.h"
@@ -97,6 +100,7 @@ typedef struct rs6000_stack {
int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
int varargs_save_offset; /* offset to save the varargs registers */
int ehrd_offset; /* offset to EH return data */
+ int ehcr_offset; /* offset to EH CR field data */
int reg_size; /* register size (4 or 8) */
HOST_WIDE_INT vars_size; /* variable save area size */
int parm_size; /* outgoing parameter size */
@@ -140,6 +144,8 @@ typedef struct GTY(()) machine_function
64-bits wide and is allocated early enough so that the offset
does not overflow the 16-bit load/store offset field. */
rtx sdmode_stack_slot;
+ /* Flag if r2 setup is needed with ELFv2 ABI. */
+ bool r2_setup_needed;
} machine_function;
/* Support targetm.vectorize.builtin_mask_for_load. */
@@ -1446,6 +1452,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
+#undef TARGET_RETURN_IN_MSB
+#define TARGET_RETURN_IN_MSB rs6000_return_in_msb
+
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
@@ -2234,6 +2243,7 @@ rs6000_debug_reg_global (void)
{
case ABI_NONE: abi_str = "none"; break;
case ABI_AIX: abi_str = "aix"; break;
+ case ABI_ELFv2: abi_str = "ELFv2"; break;
case ABI_V4: abi_str = "V4"; break;
case ABI_DARWIN: abi_str = "darwin"; break;
default: abi_str = "unknown"; break;
@@ -3672,7 +3682,7 @@ rs6000_option_override_internal (bool global_init_p)
/* We should always be splitting complex arguments, but we can't break
Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
- if (DEFAULT_ABI != ABI_AIX)
+ if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN)
targetm.calls.split_complex_arg = NULL;
}
@@ -4764,7 +4774,11 @@ rs6000_file_start (void)
putc ('\n', file);
}
- if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
+ if (DEFAULT_ABI == ABI_ELFv2)
+ fprintf (file, "\t.abiversion 2\n");
+
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2
+ || (TARGET_ELF && flag_pic == 2))
{
switch_to_section (toc_section);
switch_to_section (text_section);
@@ -6392,7 +6406,7 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
{
bool large_toc_ok;
- if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
+ if (DEFAULT_ABI == ABI_V4 && flag_pic)
return false;
/* LRA don't use LEGITIMIZE_RELOAD_ADDRESS as it usually calls
push_reload from reload pass code. LEGITIMIZE_RELOAD_ADDRESS
@@ -6980,10 +6994,13 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
1, const0_rtx, Pmode);
r3 = gen_rtx_REG (Pmode, 3);
- if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
- insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
- else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
- insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ if (TARGET_64BIT)
+ insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
+ else
+ insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+ }
else if (DEFAULT_ABI == ABI_V4)
insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
else
@@ -7002,10 +7019,13 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
1, const0_rtx, Pmode);
r3 = gen_rtx_REG (Pmode, 3);
- if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
- insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
- else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
- insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ if (TARGET_64BIT)
+ insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
+ else
+ insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+ }
else if (DEFAULT_ABI == ABI_V4)
insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
else
@@ -7632,7 +7652,7 @@ rs6000_conditional_register_usage (void)
/* The TOC register is not killed across calls in a way that is
visible to the compiler. */
- if (DEFAULT_ABI == ABI_AIX)
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
call_really_used_regs[2] = 0;
if (DEFAULT_ABI == ABI_V4
@@ -8434,18 +8454,231 @@ rs6000_member_type_forces_blk (const_tree field, enum machine_mode mode)
}
/* Nonzero if we can use a floating-point register to pass this arg. */
-#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
+#define USE_FP_FOR_ARG_P(CUM,MODE) \
(SCALAR_FLOAT_MODE_P (MODE) \
&& (CUM)->fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT && TARGET_FPRS)
/* Nonzero if we can use an AltiVec register to pass this arg. */
-#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,NAMED) \
(ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
&& (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
&& TARGET_ALTIVEC_ABI \
&& (NAMED))
+/* Walk down the type tree of TYPE counting consecutive base elements.
+ If *MODEP is VOIDmode, then set it to the first valid floating point
+ or vector type. If a non-floating point or vector type is found, or
+ if a floating point or vector type that doesn't match a non-VOIDmode
+ *MODEP is found, then return -1, otherwise return the count in the
+ sub-tree. */
+
+static int
+rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
+{
+ enum machine_mode mode;
+ HOST_WIDE_INT size;
+
+ switch (TREE_CODE (type))
+ {
+ case REAL_TYPE:
+ mode = TYPE_MODE (type);
+ if (!SCALAR_FLOAT_MODE_P (mode))
+ return -1;
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ if (*modep == mode)
+ return 1;
+
+ break;
+
+ case COMPLEX_TYPE:
+ mode = TYPE_MODE (TREE_TYPE (type));
+ if (!SCALAR_FLOAT_MODE_P (mode))
+ return -1;
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ if (*modep == mode)
+ return 2;
+
+ break;
+
+ case VECTOR_TYPE:
+ if (!TARGET_ALTIVEC_ABI || !TARGET_ALTIVEC)
+ return -1;
+
+ /* Use V4SImode as representative of all 128-bit vector types. */
+ size = int_size_in_bytes (type);
+ switch (size)
+ {
+ case 16:
+ mode = V4SImode;
+ break;
+ default:
+ return -1;
+ }
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ /* Vector modes are considered to be opaque: two vectors are
+ equivalent for the purposes of being homogeneous aggregates
+ if they are the same size. */
+ if (*modep == mode)
+ return 1;
+
+ break;
+
+ case ARRAY_TYPE:
+ {
+ int count;
+ tree index = TYPE_DOMAIN (type);
+
+ /* Can't handle incomplete types. */
+ if (!COMPLETE_TYPE_P (type))
+ return -1;
+
+ count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
+ if (count == -1
+ || !index
+ || !TYPE_MAX_VALUE (index)
+ || !host_integerp (TYPE_MAX_VALUE (index), 1)
+ || !TYPE_MIN_VALUE (index)
+ || !host_integerp (TYPE_MIN_VALUE (index), 1)
+ || count < 0)
+ return -1;
+
+ count *= (1 + tree_low_cst (TYPE_MAX_VALUE (index), 1)
+ - tree_low_cst (TYPE_MIN_VALUE (index), 1));
+
+ /* There must be no padding. */
+ if (!host_integerp (TYPE_SIZE (type), 1)
+ || (tree_low_cst (TYPE_SIZE (type), 1)
+ != count * GET_MODE_BITSIZE (*modep)))
+ return -1;
+
+ return count;
+ }
+
+ case RECORD_TYPE:
+ {
+ int count = 0;
+ int sub_count;
+ tree field;
+
+ /* Can't handle incomplete types. */
+ if (!COMPLETE_TYPE_P (type))
+ return -1;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+ if (sub_count < 0)
+ return -1;
+ count += sub_count;
+ }
+
+ /* There must be no padding. */
+ if (!host_integerp (TYPE_SIZE (type), 1)
+ || (tree_low_cst (TYPE_SIZE (type), 1)
+ != count * GET_MODE_BITSIZE (*modep)))
+ return -1;
+
+ return count;
+ }
+
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ /* These aren't very interesting except in a degenerate case. */
+ int count = 0;
+ int sub_count;
+ tree field;
+
+ /* Can't handle incomplete types. */
+ if (!COMPLETE_TYPE_P (type))
+ return -1;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+ if (sub_count < 0)
+ return -1;
+ count = count > sub_count ? count : sub_count;
+ }
+
+ /* There must be no padding. */
+ if (!host_integerp (TYPE_SIZE (type), 1)
+ || (tree_low_cst (TYPE_SIZE (type), 1)
+ != count * GET_MODE_BITSIZE (*modep)))
+ return -1;
+
+ return count;
+ }
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+/* If an argument, whose type is described by TYPE and MODE, is a homogeneous
+ float or vector aggregate that shall be passed in FP/vector registers
+ according to the ELFv2 ABI, return the homogeneous element mode in
+ *ELT_MODE and the number of elements in *N_ELTS, and return TRUE.
+
+ Otherwise, set *ELT_MODE to MODE and *N_ELTS to 1, and return FALSE. */
+
+static bool
+rs6000_discover_homogeneous_aggregate (enum machine_mode mode, const_tree type,
+ enum machine_mode *elt_mode,
+ int *n_elts)
+{
+ /* Note that we do not accept complex types at the top level as
+ homogeneous aggregates; these types are handled via the
+ targetm.calls.split_complex_arg mechanism. Complex types
+ can be elements of homogeneous aggregates, however. */
+ if (DEFAULT_ABI == ABI_ELFv2 && type && AGGREGATE_TYPE_P (type))
+ {
+ enum machine_mode field_mode = VOIDmode;
+ int field_count = rs6000_aggregate_candidate (type, &field_mode);
+
+ if (field_count > 0)
+ {
+ int n_regs = (SCALAR_FLOAT_MODE_P (field_mode)?
+ (GET_MODE_SIZE (field_mode) + 7) >> 3 : 1);
+
+ /* The ELFv2 ABI allows homogeneous aggregates to occupy
+ up to AGGR_ARG_NUM_REG registers. */
+ if (field_count * n_regs <= AGGR_ARG_NUM_REG)
+ {
+ if (elt_mode)
+ *elt_mode = field_mode;
+ if (n_elts)
+ *n_elts = field_count;
+ return true;
+ }
+ }
+ }
+
+ if (elt_mode)
+ *elt_mode = mode;
+ if (n_elts)
+ *n_elts = 1;
+ return false;
+}
+
/* Return a nonzero value to say to return the function value in
memory, just as large structures are always returned. TYPE will be
the data type of the value, and FNTYPE will be the type of the
@@ -8498,6 +8731,16 @@ rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
/* Otherwise fall through to more conventional ABI rules. */
}
+ /* The ELFv2 ABI returns homogeneous VFP aggregates in registers */
+ if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (type), type,
+ NULL, NULL))
+ return false;
+
+ /* The ELFv2 ABI returns aggregates up to 16B in registers */
+ if (DEFAULT_ABI == ABI_ELFv2 && AGGREGATE_TYPE_P (type)
+ && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) <= 16)
+ return false;
+
if (AGGREGATE_TYPE_P (type)
&& (aix_struct_return
|| (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
@@ -8529,6 +8772,19 @@ rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
return false;
}
+/* Specify whether values returned in registers should be at the most
+ significant end of a register. We want aggregates returned by
+ value to match the way aggregates are passed to functions. */
+
+static bool
+rs6000_return_in_msb (const_tree valtype)
+{
+ return (DEFAULT_ABI == ABI_ELFv2
+ && BYTES_BIG_ENDIAN
+ && AGGREGATE_TYPE_P (valtype)
+ && FUNCTION_ARG_PADDING (TYPE_MODE (valtype), valtype) == upward);
+}
+
#ifdef HAVE_AS_GNU_ATTRIBUTE
/* Return TRUE if a call to function FNDECL may be one that
potentially affects the function calling ABI of the object file. */
@@ -8665,7 +8921,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
static bool
rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
{
- if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 || TARGET_64BIT)
return must_pass_in_stack_var_size (mode, type);
else
return must_pass_in_stack_var_size_or_pad (mode, type);
@@ -8746,6 +9002,11 @@ function_arg_padding (enum machine_mode mode, const_tree type)
static unsigned int
rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
{
+ enum machine_mode elt_mode;
+ int n_elts;
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
if (DEFAULT_ABI == ABI_V4
&& (GET_MODE_SIZE (mode) == 8
|| (TARGET_HARD_FLOAT
@@ -8757,11 +9018,12 @@ rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
&& int_size_in_bytes (type) >= 8
&& int_size_in_bytes (type) < 16))
return 64;
- else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
+ else if (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode)
|| (type && TREE_CODE (type) == VECTOR_TYPE
&& int_size_in_bytes (type) >= 16))
return 128;
else if (((TARGET_MACHO && rs6000_darwin64_abi)
+ || DEFAULT_ABI == ABI_ELFv2
|| (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
&& mode == BLKmode
&& type && TYPE_ALIGN (type) > 64)
@@ -8770,6 +9032,16 @@ rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
return PARM_BOUNDARY;
}
+/* The offset in words to the start of the parameter save area. */
+
+static unsigned int
+rs6000_parm_offset (void)
+{
+ return (DEFAULT_ABI == ABI_V4 ? 2
+ : DEFAULT_ABI == ABI_ELFv2 ? 4
+ : 6);
+}
+
/* For a function parm of MODE and TYPE, return the starting word in
the parameter area. NWORDS of the parameter area are already used. */
@@ -8778,11 +9050,9 @@ rs6000_parm_start (enum machine_mode mode, const_tree type,
unsigned int nwords)
{
unsigned int align;
- unsigned int parm_offset;
align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
- parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
- return nwords + (-(parm_offset + nwords) & align);
+ return nwords + (-(rs6000_parm_offset () + nwords) & align);
}
/* Compute the size (in words) of a function argument. */
@@ -8889,7 +9159,7 @@ rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
if (TREE_CODE (ftype) == RECORD_TYPE)
rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
- else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
+ else if (USE_FP_FOR_ARG_P (cum, mode))
{
unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
@@ -8930,7 +9200,7 @@ rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
else
cum->words += n_fpregs;
}
- else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
+ else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, 1))
{
rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
cum->vregno++;
@@ -8967,6 +9237,11 @@ static void
rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
const_tree type, bool named, int depth)
{
+ enum machine_mode elt_mode;
+ int n_elts;
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
/* Only tick off an argument if we're not recursing. */
if (depth == 0)
cum->nargs_prototype--;
@@ -8987,15 +9262,16 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
#endif
if (TARGET_ALTIVEC_ABI
- && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
+ && (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode)
|| (type && TREE_CODE (type) == VECTOR_TYPE
&& int_size_in_bytes (type) == 16)))
{
bool stack = false;
- if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
+ if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
{
- cum->vregno++;
+ cum->vregno += n_elts;
+
if (!TARGET_ALTIVEC)
error ("cannot pass argument in vector register because"
" altivec instructions are disabled, use -maltivec"
@@ -9004,7 +9280,8 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
/* PowerPC64 Linux and AIX allocate GPRs for a vector argument
even if it is going to be passed in a vector register.
Darwin does the same for variable-argument functions. */
- if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+ if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && TARGET_64BIT)
|| (cum->stdarg && DEFAULT_ABI != ABI_V4))
stack = true;
}
@@ -9015,15 +9292,13 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
{
int align;
- /* Vector parameters must be 16-byte aligned. This places
- them at 2 mod 4 in terms of words in 32-bit mode, since
- the parameter save area starts at offset 24 from the
- stack. In 64-bit mode, they just have to start on an
- even word, since the parameter save area is 16-byte
- aligned. Space for GPRs is reserved even if the argument
- will be passed in memory. */
+ /* Vector parameters must be 16-byte aligned. In 32-bit
+ mode this means we need to take into account the offset
+ to the parameter save area. In 64-bit mode, they just
+ have to start on an even word, since the parameter save
+ area is 16-byte aligned. */
if (TARGET_32BIT)
- align = (2 - cum->words) & 3;
+ align = -(rs6000_parm_offset () + cum->words) & 3;
else
align = cum->words & 1;
cum->words += align + rs6000_arg_size (mode, type);
@@ -9148,15 +9423,15 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
cum->words = align_words + n_words;
- if (SCALAR_FLOAT_MODE_P (mode)
+ if (SCALAR_FLOAT_MODE_P (elt_mode)
&& TARGET_HARD_FLOAT && TARGET_FPRS)
{
/* _Decimal128 must be passed in an even/odd float register pair.
This assumes that the register number is odd when fregno is
odd. */
- if (mode == TDmode && (cum->fregno % 2) == 1)
+ if (elt_mode == TDmode && (cum->fregno % 2) == 1)
cum->fregno++;
- cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
+ cum->fregno += n_elts * ((GET_MODE_SIZE (elt_mode) + 7) >> 3);
}
if (TARGET_DEBUG_ARG)
@@ -9366,7 +9641,7 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
if (TREE_CODE (ftype) == RECORD_TYPE)
rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
- else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
+ else if (cum->named && USE_FP_FOR_ARG_P (cum, mode))
{
unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
#if 0
@@ -9394,7 +9669,7 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
if (mode == TFmode || mode == TDmode)
cum->fregno++;
}
- else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
+ else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, 1))
{
rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
rvec[(*k)++]
@@ -9511,6 +9786,84 @@ rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
}
+/* We have an argument of MODE and TYPE that goes into FPRs or VRs,
+ but must also be copied into the parameter save area starting at
+ offset ALIGN_WORDS. Fill in RVEC with the elements corresponding
+ to the GPRs and/or memory. Return the number of elements used. */
+
+static int
+rs6000_psave_function_arg (enum machine_mode mode, const_tree type,
+ int align_words, rtx *rvec)
+{
+ int k = 0;
+
+ if (align_words < GP_ARG_NUM_REG)
+ {
+ int n_words = rs6000_arg_size (mode, type);
+
+ if (align_words + n_words > GP_ARG_NUM_REG
+ || mode == BLKmode
+ || (TARGET_32BIT && TARGET_POWERPC64))
+ {
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here. */
+ enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
+ int i = 0;
+
+ if (align_words + n_words > GP_ARG_NUM_REG)
+ {
+ /* Not all of the arg fits in gprs. Say that it goes in memory
+ too, using a magic NULL_RTX component. Also see comment in
+ rs6000_mixed_function_arg for why the normal
+ function_arg_partial_nregs scheme doesn't work in this case. */
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
+ }
+
+ do
+ {
+ rtx r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
+ rtx off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+ while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
+ }
+ else
+ {
+ /* The whole arg fits in gprs. */
+ rtx r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
+ }
+ }
+ else
+ {
+ /* It's entirely in memory. */
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
+ }
+
+ return k;
+}
+
+/* RVEC is a vector of K components of an argument of mode MODE.
+ Construct the final function_arg return value from it. */
+
+static rtx
+rs6000_finish_function_arg (enum machine_mode mode, rtx *rvec, int k)
+{
+ gcc_assert (k >= 1);
+
+ /* Avoid returning a PARALLEL in the trivial cases. */
+ if (k == 1)
+ {
+ if (XEXP (rvec[0], 0) == NULL_RTX)
+ return NULL_RTX;
+
+ if (GET_MODE (XEXP (rvec[0], 0)) == mode)
+ return XEXP (rvec[0], 0);
+ }
+
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
+}
+
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -9545,6 +9898,8 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
enum rs6000_abi abi = DEFAULT_ABI;
+ enum machine_mode elt_mode;
+ int n_elts;
/* Return a marker to indicate whether CR1 needs to set or clear the
bit that V.4 uses to say fp args were passed in registers.
@@ -9571,6 +9926,8 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
}
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
{
rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
@@ -9579,33 +9936,30 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
/* Else fall through to usual handling. */
}
- if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
- if (TARGET_64BIT && ! cum->prototype)
- {
- /* Vector parameters get passed in vector register
- and also in GPRs or memory, in absence of prototype. */
- int align_words;
- rtx slot;
- align_words = (cum->words + 1) & ~1;
+ if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
+ {
+ rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
+ rtx r, off;
+ int i, k = 0;
- if (align_words >= GP_ARG_NUM_REG)
- {
- slot = NULL_RTX;
- }
- else
- {
- slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
- }
- return gen_rtx_PARALLEL (mode,
- gen_rtvec (2,
- gen_rtx_EXPR_LIST (VOIDmode,
- slot, const0_rtx),
- gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode, cum->vregno),
- const0_rtx)));
- }
- else
- return gen_rtx_REG (mode, cum->vregno);
+ /* Do we also need to pass this argument in the parameter
+ save area? */
+ if (TARGET_64BIT && ! cum->prototype)
+ {
+ int align_words = (cum->words + 1) & ~1;
+ k = rs6000_psave_function_arg (mode, type, align_words, rvec);
+ }
+
+ /* Describe where this argument goes in the vector registers. */
+ for (i = 0; i < n_elts && cum->vregno + i <= ALTIVEC_ARG_MAX_REG; i++)
+ {
+ r = gen_rtx_REG (elt_mode, cum->vregno + i);
+ off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+
+ return rs6000_finish_function_arg (mode, rvec, k);
+ }
else if (TARGET_ALTIVEC_ABI
&& (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
|| (type && TREE_CODE (type) == VECTOR_TYPE
@@ -9620,13 +9974,13 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
int align, align_words, n_words;
enum machine_mode part_mode;
- /* Vector parameters must be 16-byte aligned. This places them at
- 2 mod 4 in terms of words in 32-bit mode, since the parameter
- save area starts at offset 24 from the stack. In 64-bit mode,
- they just have to start on an even word, since the parameter
- save area is 16-byte aligned. */
+ /* Vector parameters must be 16-byte aligned. In 32-bit
+ mode this means we need to take into account the offset
+ to the parameter save area. In 64-bit mode, they just
+ have to start on an even word, since the parameter save
+ area is 16-byte aligned. */
if (TARGET_32BIT)
- align = (2 - cum->words) & 3;
+ align = -(rs6000_parm_offset () + cum->words) & 3;
else
align = cum->words & 1;
align_words = cum->words + align;
@@ -9704,101 +10058,50 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
/* _Decimal128 must be passed in an even/odd float register pair.
This assumes that the register number is odd when fregno is odd. */
- if (mode == TDmode && (cum->fregno % 2) == 1)
+ if (elt_mode == TDmode && (cum->fregno % 2) == 1)
cum->fregno++;
- if (USE_FP_FOR_ARG_P (cum, mode, type))
+ if (USE_FP_FOR_ARG_P (cum, elt_mode))
{
- rtx rvec[GP_ARG_NUM_REG + 1];
- rtx r;
- int k;
- bool needs_psave;
- enum machine_mode fmode = mode;
- unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
+ rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
+ rtx r, off;
+ int i, k = 0;
+ unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
- if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
- {
- /* Currently, we only ever need one reg here because complex
- doubles are split. */
- gcc_assert (cum->fregno == FP_ARG_MAX_REG
- && (fmode == TFmode || fmode == TDmode));
-
- /* Long double or _Decimal128 split over regs and memory. */
- fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
- }
-
- /* Do we also need to pass this arg in the parameter save
- area? */
- needs_psave = (type
- && (cum->nargs_prototype <= 0
- || (DEFAULT_ABI == ABI_AIX
- && TARGET_XL_COMPAT
- && align_words >= GP_ARG_NUM_REG)));
+ /* Do we also need to pass this argument in the parameter
+ save area? */
+ if (type && (cum->nargs_prototype <= 0
+ || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && TARGET_XL_COMPAT
+ && align_words >= GP_ARG_NUM_REG)))
+ k = rs6000_psave_function_arg (mode, type, align_words, rvec);
- if (!needs_psave && mode == fmode)
- return gen_rtx_REG (fmode, cum->fregno);
-
- k = 0;
- if (needs_psave)
+ /* Describe where this argument goes in the fprs. */
+ for (i = 0; i < n_elts
+ && cum->fregno + i * n_fpreg <= FP_ARG_MAX_REG; i++)
{
- /* Describe the part that goes in gprs or the stack.
- This piece must come first, before the fprs. */
- if (align_words < GP_ARG_NUM_REG)
+ /* Check if the argument is split over registers and memory.
+ This can only ever happen for long double or _Decimal128;
+ complex types are handled via split_complex_arg. */
+ enum machine_mode fmode = elt_mode;
+ if (cum->fregno + (i + 1) * n_fpreg > FP_ARG_MAX_REG + 1)
{
- unsigned long n_words = rs6000_arg_size (mode, type);
-
- if (align_words + n_words > GP_ARG_NUM_REG
- || (TARGET_32BIT && TARGET_POWERPC64))
- {
- /* If this is partially on the stack, then we only
- include the portion actually in registers here. */
- enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
- rtx off;
- int i = 0;
- if (align_words + n_words > GP_ARG_NUM_REG)
- /* Not all of the arg fits in gprs. Say that it
- goes in memory too, using a magic NULL_RTX
- component. Also see comment in
- rs6000_mixed_function_arg for why the normal
- function_arg_partial_nregs scheme doesn't work
- in this case. */
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
- const0_rtx);
- do
- {
- r = gen_rtx_REG (rmode,
- GP_ARG_MIN_REG + align_words);
- off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
- }
- while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
- }
- else
- {
- /* The whole arg fits in gprs. */
- r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
- }
+ gcc_assert (fmode == TFmode || fmode == TDmode);
+ fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
}
- else
- /* It's entirely in memory. */
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
- }
- /* Describe where this piece goes in the fprs. */
- r = gen_rtx_REG (fmode, cum->fregno);
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
+ r = gen_rtx_REG (fmode, cum->fregno + i * n_fpreg);
+ off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
- return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
+ return rs6000_finish_function_arg (mode, rvec, k);
}
else if (align_words < GP_ARG_NUM_REG)
{
if (TARGET_32BIT && TARGET_POWERPC64)
return rs6000_mixed_function_arg (mode, type, align_words);
- if (mode == BLKmode)
- mode = Pmode;
-
return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
}
else
@@ -9817,15 +10120,31 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
tree type, bool named)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ bool passed_in_gprs = true;
int ret = 0;
int align_words;
+ enum machine_mode elt_mode;
+ int n_elts;
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
if (DEFAULT_ABI == ABI_V4)
return 0;
- if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
- && cum->nargs_prototype >= 0)
- return 0;
+ if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
+ {
+ /* If we are passing this arg in the fixed parameter save area
+ (gprs or memory) as well as VRs, we do not use the partial
+ bytes mechanism; instead, rs6000_function_arg will return a
+ PARALLEL including a memory element as necessary. */
+ if (TARGET_64BIT && ! cum->prototype)
+ return 0;
+
+ /* Otherwise, we pass in VRs only. Check for partial copies. */
+ passed_in_gprs = false;
+ if (cum->vregno + n_elts > ALTIVEC_ARG_MAX_REG + 1)
+ ret = (ALTIVEC_ARG_MAX_REG + 1 - cum->vregno) * 16;
+ }
/* In this complicated case we just disable the partial_nregs code. */
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
@@ -9833,26 +10152,30 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
align_words = rs6000_parm_start (mode, type, cum->words);
- if (USE_FP_FOR_ARG_P (cum, mode, type))
+ if (USE_FP_FOR_ARG_P (cum, elt_mode))
{
+ unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
+
/* If we are passing this arg in the fixed parameter save area
- (gprs or memory) as well as fprs, then this function should
- return the number of partial bytes passed in the parameter
- save area rather than partial bytes passed in fprs. */
+ (gprs or memory) as well as FPRs, we do not use the partial
+ bytes mechanism; instead, rs6000_function_arg will return a
+ PARALLEL including a memory element as necessary. */
if (type
&& (cum->nargs_prototype <= 0
- || (DEFAULT_ABI == ABI_AIX
+ || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& TARGET_XL_COMPAT
&& align_words >= GP_ARG_NUM_REG)))
return 0;
- else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
- > FP_ARG_MAX_REG + 1)
- ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
- else if (cum->nargs_prototype >= 0)
- return 0;
+
+ /* Otherwise, we pass in FPRs only. Check for partial copies. */
+ passed_in_gprs = false;
+ if (cum->fregno + n_elts * n_fpreg > FP_ARG_MAX_REG + 1)
+ ret = ((FP_ARG_MAX_REG + 1 - cum->fregno)
+ * MIN (8, GET_MODE_SIZE (elt_mode)));
}
- if (align_words < GP_ARG_NUM_REG
+ if (passed_in_gprs
+ && align_words < GP_ARG_NUM_REG
&& GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
@@ -9933,6 +10256,139 @@ rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
return 0;
}
+/* Process parameter of type TYPE after ARGS_SO_FAR parameters were
+ already processes. Return true if the parameter must be passed
+ (fully or partially) on the stack. */
+
+static bool
+rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
+{
+ enum machine_mode mode;
+ int unsignedp;
+ rtx entry_parm;
+
+ /* Catch errors. */
+ if (type == NULL || type == error_mark_node)
+ return true;
+
+ /* Handle types with no storage requirement. */
+ if (TYPE_MODE (type) == VOIDmode)
+ return false;
+
+ /* Handle complex types. */
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ return (rs6000_parm_needs_stack (args_so_far, TREE_TYPE (type))
+ || rs6000_parm_needs_stack (args_so_far, TREE_TYPE (type)));
+
+ /* Handle transparent aggregates. */
+ if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
+ && TYPE_TRANSPARENT_AGGR (type))
+ type = TREE_TYPE (first_field (type));
+
+ /* See if this arg was passed by invisible reference. */
+ if (pass_by_reference (get_cumulative_args (args_so_far),
+ TYPE_MODE (type), type, true))
+ type = build_pointer_type (type);
+
+ /* Find mode as it is passed by the ABI. */
+ unsignedp = TYPE_UNSIGNED (type);
+ mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
+
+ /* If we must pass in stack, we need a stack. */
+ if (rs6000_must_pass_in_stack (mode, type))
+ return true;
+
+ /* If there is no incoming register, we need a stack. */
+ entry_parm = rs6000_function_arg (args_so_far, mode, type, true);
+ if (entry_parm == NULL)
+ return true;
+
+ /* Likewise if we need to pass both in registers and on the stack. */
+ if (GET_CODE (entry_parm) == PARALLEL
+ && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
+ return true;
+
+ /* Also true if we're partially in registers and partially not. */
+ if (rs6000_arg_partial_bytes (args_so_far, mode, type, true) != 0)
+ return true;
+
+ /* Update info on where next arg arrives in registers. */
+ rs6000_function_arg_advance (args_so_far, mode, type, true);
+ return false;
+}
+
+/* Return true if FUN has no prototype, has a variable argument
+ list, or passes any parameter in memory. */
+
+static bool
+rs6000_function_parms_need_stack (tree fun)
+{
+ function_args_iterator args_iter;
+ tree arg_type;
+ CUMULATIVE_ARGS args_so_far_v;
+ cumulative_args_t args_so_far;
+
+ if (!fun)
+ /* Must be a libcall, all of which only use reg parms. */
+ return false;
+ if (!TYPE_P (fun))
+ fun = TREE_TYPE (fun);
+
+ /* Varargs functions need the parameter save area. */
+ if (!prototype_p (fun) || stdarg_p (fun))
+ return true;
+
+ INIT_CUMULATIVE_INCOMING_ARGS (args_so_far_v, fun, NULL_RTX);
+ args_so_far = pack_cumulative_args (&args_so_far_v);
+
+ if (aggregate_value_p (TREE_TYPE (fun), fun))
+ {
+ tree type = build_pointer_type (TREE_TYPE (fun));
+ rs6000_parm_needs_stack (args_so_far, type);
+ }
+
+ FOREACH_FUNCTION_ARGS (fun, arg_type, args_iter)
+ if (rs6000_parm_needs_stack (args_so_far, arg_type))
+ return true;
+
+ return false;
+}
+
+/* Return the size of the REG_PARM_STACK_SPACE are for FUN. This is
+ usually a constant depending on the ABI. However, in the ELFv2 ABI
+ the register parameter area is optional when calling a function that
+ has a prototype is scope, has no variable argument list, and passes
+ all parameters in registers. */
+
+int
+rs6000_reg_parm_stack_space (tree fun)
+{
+ int reg_parm_stack_space;
+
+ switch (DEFAULT_ABI)
+ {
+ default:
+ reg_parm_stack_space = 0;
+ break;
+
+ case ABI_AIX:
+ case ABI_DARWIN:
+ reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
+ break;
+
+ case ABI_ELFv2:
+ /* ??? Recomputing this every time is a bit expensive. Is there
+ a place to cache this information? */
+ if (rs6000_function_parms_need_stack (fun))
+ reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
+ else
+ reg_parm_stack_space = 0;
+ break;
+ }
+
+ return reg_parm_stack_space;
+}
+
static void
rs6000_move_block_from_reg (int regno, rtx x, int nregs)
{
@@ -10312,6 +10768,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
if (((TARGET_MACHO
&& rs6000_darwin64_abi)
+ || DEFAULT_ABI == ABI_ELFv2
|| (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
&& integer_zerop (TYPE_SIZE (type)))
{
@@ -16643,6 +17100,7 @@ rs6000_output_function_entry (FILE *file, const char *fname)
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
break;
+ case ABI_ELFv2:
case ABI_V4:
case ABI_DARWIN:
break;
@@ -19594,7 +20052,7 @@ rs6000_savres_strategy (rs6000_stack_t *info,
}
else
{
- gcc_checking_assert (DEFAULT_ABI == ABI_AIX);
+ gcc_checking_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
if (info->first_fp_reg_save > 61)
strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
@@ -19605,7 +20063,8 @@ rs6000_savres_strategy (rs6000_stack_t *info,
by the static chain. It would require too much fiddling and the
static chain is rarely used anyway. FPRs are saved w.r.t the stack
pointer on Darwin, and AIX uses r1 or r12. */
- if (using_static_chain_p && DEFAULT_ABI != ABI_AIX)
+ if (using_static_chain_p
+ && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN))
strategy |= ((DEFAULT_ABI == ABI_DARWIN ? 0 : SAVE_INLINE_FPRS)
| SAVE_INLINE_GPRS
| SAVE_INLINE_VRS | REST_INLINE_VRS);
@@ -19738,6 +20197,34 @@ rs6000_savres_strategy (rs6000_stack_t *info,
The required alignment for AIX configurations is two words (i.e., 8
or 16 bytes).
+ The ELFv2 ABI is a variant of the AIX ABI. Stack frames look like:
+
+ SP----> +---------------------------------------+
+ | Back chain to caller | 0
+ +---------------------------------------+
+ | Save area for CR | 8
+ +---------------------------------------+
+ | Saved LR | 16
+ +---------------------------------------+
+ | Saved TOC pointer | 24
+ +---------------------------------------+
+ | Parameter save area (P) | 32
+ +---------------------------------------+
+ | Alloca space (A) | 32+P
+ +---------------------------------------+
+ | Local variable space (L) | 32+P+A
+ +---------------------------------------+
+ | Save area for AltiVec registers (W) | 32+P+A+L
+ +---------------------------------------+
+ | AltiVec alignment padding (Y) | 32+P+A+L+W
+ +---------------------------------------+
+ | Save area for GP registers (G) | 32+P+A+L+W+Y
+ +---------------------------------------+
+ | Save area for FP registers (F) | 32+P+A+L+W+Y+G
+ +---------------------------------------+
+ old SP->| back chain to caller's caller | 32+P+A+L+W+Y+G+F
+ +---------------------------------------+
+
V.4 stack frames look like:
@@ -19798,6 +20285,7 @@ rs6000_stack_info (void)
rs6000_stack_t *info_ptr = &stack_info;
int reg_size = TARGET_32BIT ? 4 : 8;
int ehrd_size;
+ int ehcr_size;
int save_align;
int first_gp;
HOST_WIDE_INT non_fixed_size;
@@ -19891,6 +20379,18 @@ rs6000_stack_info (void)
else
ehrd_size = 0;
+ /* In the ELFv2 ABI, we also need to allocate space for separate
+ CR field save areas if the function calls __builtin_eh_return. */
+ if (DEFAULT_ABI == ABI_ELFv2 && crtl->calls_eh_return)
+ {
+ /* This hard-codes that we have three call-saved CR fields. */
+ ehcr_size = 3 * reg_size;
+ /* We do *not* use the regular CR save mechanism. */
+ info_ptr->cr_save_p = 0;
+ }
+ else
+ ehcr_size = 0;
+
/* Determine various sizes. */
info_ptr->reg_size = reg_size;
info_ptr->fixed_size = RS6000_SAVE_AREA;
@@ -19930,6 +20430,7 @@ rs6000_stack_info (void)
gcc_unreachable ();
case ABI_AIX:
+ case ABI_ELFv2:
case ABI_DARWIN:
info_ptr->fp_save_offset = - info_ptr->fp_size;
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
@@ -19959,6 +20460,8 @@ rs6000_stack_info (void)
}
else
info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
+
+ info_ptr->ehcr_offset = info_ptr->ehrd_offset - ehcr_size;
info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
info_ptr->lr_save_offset = 2*reg_size;
break;
@@ -20021,6 +20524,7 @@ rs6000_stack_info (void)
+ info_ptr->spe_gp_size
+ info_ptr->spe_padding_size
+ ehrd_size
+ + ehcr_size
+ info_ptr->cr_size
+ info_ptr->vrsave_size,
save_align);
@@ -20034,7 +20538,7 @@ rs6000_stack_info (void)
/* Determine if we need to save the link register. */
if (info_ptr->calls_p
- || (DEFAULT_ABI == ABI_AIX
+ || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& crtl->profile
&& !TARGET_PROFILE_KERNEL)
|| (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
@@ -20180,6 +20684,7 @@ debug_stack_info (rs6000_stack_t *info)
default: abi_string = "Unknown"; break;
case ABI_NONE: abi_string = "NONE"; break;
case ABI_AIX: abi_string = "AIX"; break;
+ case ABI_ELFv2: abi_string = "ELFv2"; break;
case ABI_DARWIN: abi_string = "Darwin"; break;
case ABI_V4: abi_string = "V.4"; break;
}
@@ -20301,7 +20806,8 @@ rs6000_return_addr (int count, rtx frame)
/* Currently we don't optimize very well between prolog and body
code and for PIC code the code can be actually quite bad, so
don't try to be too clever here. */
- if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
+ if (count != 0
+ || ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN) && flag_pic))
{
cfun->machine->ra_needs_full_frame = 1;
@@ -20360,13 +20866,13 @@ rs6000_function_ok_for_sibcall (tree decl, tree exp)
return false;
}
- /* Under the AIX ABI we can't allow calls to non-local functions,
- because the callee may have a different TOC pointer to the
- caller and there's no way to ensure we restore the TOC when we
- return. With the secure-plt SYSV ABI we can't make non-local
+ /* Under the AIX or ELFv2 ABIs we can't allow calls to non-local
+ functions, because the callee may have a different TOC pointer to
+ the caller and there's no way to ensure we restore the TOC when
+ we return. With the secure-plt SYSV ABI we can't make non-local
calls when -fpic/PIC because the plt call stubs use r30. */
if (DEFAULT_ABI == ABI_DARWIN
- || (DEFAULT_ABI == ABI_AIX
+ || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& decl
&& !DECL_EXTERNAL (decl)
&& (*targetm.binds_local_p) (decl))
@@ -20449,7 +20955,7 @@ rs6000_emit_load_toc_table (int fromprolog)
rtx dest;
dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
- if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
+ if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic)
{
char buf[30];
rtx lab, tmp1, tmp2, got;
@@ -20477,7 +20983,7 @@ rs6000_emit_load_toc_table (int fromprolog)
emit_insn (gen_load_toc_v4_pic_si ());
emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
}
- else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
+ else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2)
{
char buf[30];
rtx temp0 = (fromprolog
@@ -20525,7 +21031,7 @@ rs6000_emit_load_toc_table (int fromprolog)
}
else
{
- gcc_assert (DEFAULT_ABI == ABI_AIX);
+ gcc_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
if (TARGET_32BIT)
emit_insn (gen_load_toc_aix_si (dest));
@@ -21244,7 +21750,7 @@ rs6000_savres_routine_name (rs6000_stack_t *info, int regno, int sel)
if ((sel & SAVRES_LR))
suffix = "_x";
}
- else if (DEFAULT_ABI == ABI_AIX)
+ else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
{
#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
/* No out-of-line save/restore routines for GPRs on AIX. */
@@ -21385,7 +21891,7 @@ rs6000_emit_stack_reset (rs6000_stack_t *info,
static inline unsigned
ptr_regno_for_savres (int sel)
{
- if (DEFAULT_ABI == ABI_AIX)
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
return (sel & SAVRES_REG) == SAVRES_FPR || (sel & SAVRES_LR) ? 1 : 12;
return DEFAULT_ABI == ABI_DARWIN && (sel & SAVRES_REG) == SAVRES_FPR ? 1 : 11;
}
@@ -21470,6 +21976,43 @@ rs6000_emit_savres_rtx (rs6000_stack_t *info,
return insn;
}
+/* Emit code to store CR fields that need to be saved into REG. */
+
+static void
+rs6000_emit_move_from_cr (rtx reg)
+{
+ /* Only the ELFv2 ABI allows storing only selected fields. */
+ if (DEFAULT_ABI == ABI_ELFv2 && TARGET_MFCRF)
+ {
+ int i, cr_reg[8], count = 0;
+
+ /* Collect CR fields that must be saved. */
+ for (i = 0; i < 8; i++)
+ if (save_reg_p (CR0_REGNO + i))
+ cr_reg[count++] = i;
+
+ /* If it's just a single one, use mfcrf. */
+ if (count == 1)
+ {
+ rtvec p = rtvec_alloc (1);
+ rtvec r = rtvec_alloc (2);
+ RTVEC_ELT (r, 0) = gen_rtx_REG (CCmode, CR0_REGNO + cr_reg[0]);
+ RTVEC_ELT (r, 1) = GEN_INT (1 << (7 - cr_reg[0]));
+ RTVEC_ELT (p, 0)
+ = gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_UNSPEC (SImode, r, UNSPEC_MOVESI_FROM_CR));
+
+ emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ return;
+ }
+
+ /* ??? It might be better to handle count == 2 / 3 cases here
+ as well, using logical operations to combine the values. */
+ }
+
+ emit_insn (gen_movesi_from_cr (reg));
+}
+
/* Determine whether the gp REG is really used. */
static bool
@@ -21535,6 +22078,17 @@ rs6000_emit_prologue (void)
#define NOT_INUSE(R) do {} while (0)
#endif
+ if (DEFAULT_ABI == ABI_ELFv2)
+ {
+ cfun->machine->r2_setup_needed = df_regs_ever_live_p (TOC_REGNUM);
+
+ /* With -mminimal-toc we may generate an extra use of r2 below. */
+ if (!TARGET_SINGLE_PIC_BASE
+ && TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
+ cfun->machine->r2_setup_needed = true;
+ }
+
+
if (flag_stack_usage_info)
current_function_static_stack_size = info->total_size;
@@ -21752,7 +22306,7 @@ rs6000_emit_prologue (void)
/* If we need to save CR, put it into r12 or r11. Choose r12 except when
r12 will be needed by out-of-line gpr restore. */
- cr_save_regno = (DEFAULT_ABI == ABI_AIX
+ cr_save_regno = ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& !(strategy & (SAVE_INLINE_GPRS
| SAVE_NOINLINE_GPRS_SAVES_LR))
? 11 : 12);
@@ -21761,21 +22315,9 @@ rs6000_emit_prologue (void)
&& REGNO (frame_reg_rtx) != cr_save_regno
&& !(using_static_chain_p && cr_save_regno == 11))
{
- rtx set;
-
cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno);
START_USE (cr_save_regno);
- insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
- /* Now, there's no way that dwarf2out_frame_debug_expr is going
- to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
- But that's OK. All we have to do is specify that _one_ condition
- code register is saved in this stack slot. The thrower's epilogue
- will then restore all the call-saved registers.
- We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
- set = gen_rtx_SET (VOIDmode, cr_save_rtx,
- gen_rtx_REG (SImode, CR2_REGNO));
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
+ rs6000_emit_move_from_cr (cr_save_rtx);
}
/* Do any required saving of fpr's. If only one or two to save, do
@@ -22027,7 +22569,8 @@ rs6000_emit_prologue (void)
be updated if we arrived at this function via a plt call or
toc adjusting stub. */
emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
- toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
+ toc_restore_insn = ((TARGET_32BIT ? 0x80410000 : 0xE8410000)
+ + RS6000_TOC_SAVE_SLOT);
hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
@@ -22046,7 +22589,7 @@ rs6000_emit_prologue (void)
LABEL_NUSES (toc_save_done) += 1;
save_insn = emit_frame_save (frame_reg_rtx, reg_mode,
- TOC_REGNUM, frame_off + 5 * reg_size,
+ TOC_REGNUM, frame_off + RS6000_TOC_SAVE_SLOT,
sp_off - frame_off);
emit_label (toc_save_done);
@@ -22086,26 +22629,121 @@ rs6000_emit_prologue (void)
rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->cr_save_offset + frame_off));
rtx mem = gen_frame_mem (SImode, addr);
- /* See the large comment above about why CR2_REGNO is used. */
- rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
/* If we didn't copy cr before, do so now using r0. */
if (cr_save_rtx == NULL_RTX)
{
- rtx set;
-
START_USE (0);
cr_save_rtx = gen_rtx_REG (SImode, 0);
- insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
- set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
+ rs6000_emit_move_from_cr (cr_save_rtx);
+ }
+
+ /* Saving CR requires a two-instruction sequence: one instruction
+ to move the CR to a general-purpose register, and a second
+ instruction that stores the GPR to memory.
+
+ We do not emit any DWARF CFI records for the first of these,
+ because we cannot properly represent the fact that CR is saved in
+ a register. One reason is that we cannot express that multiple
+ CR fields are saved; another reason is that on 64-bit, the size
+ of the CR register in DWARF (4 bytes) differs from the size of
+ a general-purpose register.
+
+ This means if any intervening instruction were to clobber one of
+ the call-saved CR fields, we'd have incorrect CFI. To prevent
+ this from happening, we mark the store to memory as a use of
+ those CR fields, which prevents any such instruction from being
+ scheduled in between the two instructions. */
+ rtx crsave_v[9];
+ int n_crsave = 0;
+ int i;
+
+ crsave_v[n_crsave++] = gen_rtx_SET (VOIDmode, mem, cr_save_rtx);
+ for (i = 0; i < 8; i++)
+ if (save_reg_p (CR0_REGNO + i))
+ crsave_v[n_crsave++]
+ = gen_rtx_USE (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO + i));
+
+ insn = emit_insn (gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec_v (n_crsave, crsave_v)));
+ END_USE (REGNO (cr_save_rtx));
+
+ /* Now, there's no way that dwarf2out_frame_debug_expr is going to
+ understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)',
+ so we need to construct a frame expression manually. */
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* Update address to be stack-pointer relative, like
+ rs6000_frame_related would do. */
+ addr = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM),
+ GEN_INT (info->cr_save_offset + sp_off));
+ mem = gen_frame_mem (SImode, addr);
+
+ if (DEFAULT_ABI == ABI_ELFv2)
+ {
+ /* In the ELFv2 ABI we generate separate CFI records for each
+ CR field that was actually saved. They all point to the
+ same 32-bit stack slot. */
+ rtx crframe[8];
+ int n_crframe = 0;
+
+ for (i = 0; i < 8; i++)
+ if (save_reg_p (CR0_REGNO + i))
+ {
+ crframe[n_crframe]
+ = gen_rtx_SET (VOIDmode, mem,
+ gen_rtx_REG (SImode, CR0_REGNO + i));
+
+ RTX_FRAME_RELATED_P (crframe[n_crframe]) = 1;
+ n_crframe++;
+ }
+
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+ gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec_v (n_crframe, crframe)));
+ }
+ else
+ {
+ /* In other ABIs, by convention, we use a single CR regnum to
+ represent the fact that all call-saved CR fields are saved.
+ We use CR2_REGNO to be compatible with gcc-2.95 on Linux. */
+ rtx set = gen_rtx_SET (VOIDmode, mem,
+ gen_rtx_REG (SImode, CR2_REGNO));
add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
}
- insn = emit_move_insn (mem, cr_save_rtx);
- END_USE (REGNO (cr_save_rtx));
+ }
- rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
- NULL_RTX, NULL_RTX);
+ /* In the ELFv2 ABI we need to save all call-saved CR fields into
+ *separate* slots if the routine calls __builtin_eh_return, so
+ that they can be independently restored by the unwinder. */
+ if (DEFAULT_ABI == ABI_ELFv2 && crtl->calls_eh_return)
+ {
+ int i, cr_off = info->ehcr_offset;
+ rtx crsave;
+
+ /* ??? We might get better performance by using multiple mfocrf
+ instructions. */
+ crsave = gen_rtx_REG (SImode, 0);
+ emit_insn (gen_movesi_from_cr (crsave));
+
+ for (i = 0; i < 8; i++)
+ if (!call_used_regs[CR0_REGNO + i])
+ {
+ rtvec p = rtvec_alloc (2);
+ RTVEC_ELT (p, 0)
+ = gen_frame_store (crsave, frame_reg_rtx, cr_off + frame_off);
+ RTVEC_ELT (p, 1)
+ = gen_rtx_USE (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO + i));
+
+ insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+ gen_frame_store (gen_rtx_REG (SImode, CR0_REGNO + i),
+ sp_reg_rtx, cr_off + sp_off));
+
+ cr_off += reg_size;
+ }
}
/* Update stack and set back pointer unless this is V.4,
@@ -22244,7 +22882,8 @@ rs6000_emit_prologue (void)
be using r12 as frame_reg_rtx and r11 as the static chain
pointer for nested functions. */
save_regno = 12;
- if (DEFAULT_ABI == ABI_AIX && !using_static_chain_p)
+ if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && !using_static_chain_p)
save_regno = 11;
else if (REGNO (frame_reg_rtx) == 12)
{
@@ -22283,7 +22922,7 @@ rs6000_emit_prologue (void)
can use register 0. This allows us to use a plain 'blr' to return
from the procedure more often. */
int save_LR_around_toc_setup = (TARGET_ELF
- && DEFAULT_ABI != ABI_AIX
+ && DEFAULT_ABI == ABI_V4
&& flag_pic
&& ! info->lr_save_p
&& EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
@@ -22345,7 +22984,7 @@ rs6000_emit_prologue (void)
if (rs6000_save_toc_in_prologue_p ())
{
rtx reg = gen_rtx_REG (reg_mode, TOC_REGNUM);
- emit_insn (gen_frame_store (reg, sp_reg_rtx, 5 * reg_size));
+ emit_insn (gen_frame_store (reg, sp_reg_rtx, RS6000_TOC_SAVE_SLOT));
}
}
@@ -22386,6 +23025,49 @@ rs6000_output_function_prologue (FILE *file,
}
}
+ /* ELFv2 ABI r2 setup code and local entry point. This must follow
+ immediately after the global entry point label. */
+ if (DEFAULT_ABI == ABI_ELFv2 && cfun->machine->r2_setup_needed)
+ {
+ const char *name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+
+ fprintf (file, "0:\taddis 2,12,.TOC.-0b@ha\n");
+ fprintf (file, "\taddi 2,2,.TOC.-0b@l\n");
+
+ fputs ("\t.localentry\t", file);
+ assemble_name (file, name);
+ fputs (",.-", file);
+ assemble_name (file, name);
+ fputs ("\n", file);
+ }
+
+ /* Output -mprofile-kernel code. This needs to be done here instead of
+ in output_function_profile since it must go after the ELFv2 ABI
+ local entry point. */
+ if (TARGET_PROFILE_KERNEL)
+ {
+ gcc_assert (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2);
+ gcc_assert (!TARGET_32BIT);
+
+ asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
+ asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
+
+ /* In the ELFv2 ABI we have no compiler stack word. It must be
+ the resposibility of _mcount to preserve the static chain
+ register if required. */
+ if (DEFAULT_ABI != ABI_ELFv2
+ && cfun->static_chain_decl != NULL)
+ {
+ asm_fprintf (file, "\tstd %s,24(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ asm_fprintf (file, "\tld %s,24(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
+ }
+ else
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ }
+
rs6000_pic_labelno++;
}
@@ -22438,6 +23120,7 @@ restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func)
if (using_mfcr_multiple && count > 1)
{
+ rtx insn;
rtvec p;
int ndx;
@@ -22455,16 +23138,43 @@ restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func)
gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
ndx++;
}
- emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
gcc_assert (ndx == count);
+
+ /* For the ELFv2 ABI we generate a CFA_RESTORE for each
+ CR field separately. */
+ if (!exit_func && DEFAULT_ABI == ABI_ELFv2 && flag_shrink_wrap)
+ {
+ for (i = 0; i < 8; i++)
+ if (save_reg_p (CR0_REGNO + i))
+ add_reg_note (insn, REG_CFA_RESTORE,
+ gen_rtx_REG (SImode, CR0_REGNO + i));
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
}
else
for (i = 0; i < 8; i++)
if (save_reg_p (CR0_REGNO + i))
- emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, CR0_REGNO + i),
- reg));
+ {
+ rtx insn = emit_insn (gen_movsi_to_cr_one
+ (gen_rtx_REG (CCmode, CR0_REGNO + i), reg));
+
+ /* For the ELFv2 ABI we generate a CFA_RESTORE for each
+ CR field separately, attached to the insn that in fact
+ restores this particular CR field. */
+ if (!exit_func && DEFAULT_ABI == ABI_ELFv2 && flag_shrink_wrap)
+ {
+ add_reg_note (insn, REG_CFA_RESTORE,
+ gen_rtx_REG (SImode, CR0_REGNO + i));
- if (!exit_func && (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap))
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ }
+
+ /* For other ABIs, we just generate a single CFA_RESTORE for CR2. */
+ if (!exit_func && DEFAULT_ABI != ABI_ELFv2
+ && (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap))
{
rtx insn = get_last_insn ();
rtx cr = gen_rtx_REG (SImode, CR2_REGNO);
@@ -22505,10 +23215,22 @@ restore_saved_lr (int regno, bool exit_func)
static rtx
add_crlr_cfa_restore (const rs6000_stack_t *info, rtx cfa_restores)
{
- if (info->cr_save_p)
+ if (DEFAULT_ABI == ABI_ELFv2)
+ {
+ int i;
+ for (i = 0; i < 8; i++)
+ if (save_reg_p (CR0_REGNO + i))
+ {
+ rtx cr = gen_rtx_REG (SImode, CR0_REGNO + i);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, cr,
+ cfa_restores);
+ }
+ }
+ else if (info->cr_save_p)
cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
gen_rtx_REG (SImode, CR2_REGNO),
cfa_restores);
+
if (info->lr_save_p)
cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
gen_rtx_REG (Pmode, LR_REGNO),
@@ -23006,6 +23728,35 @@ rs6000_emit_epilogue (int sibcall)
|| (!restoring_GPRs_inline
&& info->first_fp_reg_save == 64));
+ /* In the ELFv2 ABI we need to restore all call-saved CR fields from
+ *separate* slots if the routine calls __builtin_eh_return, so
+ that they can be independently restored by the unwinder. */
+ if (DEFAULT_ABI == ABI_ELFv2 && crtl->calls_eh_return)
+ {
+ int i, cr_off = info->ehcr_offset;
+
+ for (i = 0; i < 8; i++)
+ if (!call_used_regs[CR0_REGNO + i])
+ {
+ rtx reg = gen_rtx_REG (SImode, 0);
+ emit_insn (gen_frame_load (reg, frame_reg_rtx,
+ cr_off + frame_off));
+
+ insn = emit_insn (gen_movsi_to_cr_one
+ (gen_rtx_REG (CCmode, CR0_REGNO + i), reg));
+
+ if (!exit_func && flag_shrink_wrap)
+ {
+ add_reg_note (insn, REG_CFA_RESTORE,
+ gen_rtx_REG (SImode, CR0_REGNO + i));
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ cr_off += reg_size;
+ }
+ }
+
/* Get the old lr if we saved it. If we are restoring registers
out-of-line, then the out-of-line routines can do this for us. */
if (restore_lr && restoring_GPRs_inline)
@@ -23049,7 +23800,7 @@ rs6000_emit_epilogue (int sibcall)
{
rtx reg = gen_rtx_REG (reg_mode, 2);
emit_insn (gen_frame_load (reg, frame_reg_rtx,
- frame_off + 5 * reg_size));
+ frame_off + RS6000_TOC_SAVE_SLOT));
}
for (i = 0; ; ++i)
@@ -23335,6 +24086,7 @@ rs6000_emit_epilogue (int sibcall)
if (! restoring_FPRs_inline)
{
int i;
+ int reg;
rtx sym;
if (flag_shrink_wrap)
@@ -23343,10 +24095,9 @@ rs6000_emit_epilogue (int sibcall)
sym = rs6000_savres_routine_sym (info,
SAVRES_FPR | (lr ? SAVRES_LR : 0));
RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
- RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
- gen_rtx_REG (Pmode,
- DEFAULT_ABI == ABI_AIX
- ? 1 : 11));
+ reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11;
+ RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
+
for (i = 0; i < 64 - info->first_fp_reg_save; i++)
{
rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
@@ -23424,7 +24175,8 @@ rs6000_output_function_epilogue (FILE *file,
System V.4 Powerpc's (and the embedded ABI derived from it) use a
different traceback table. */
- if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
+ if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && ! flag_inhibit_size_directive
&& rs6000_traceback != traceback_none && !cfun->is_thunk)
{
const char *fname = NULL;
@@ -23752,6 +24504,12 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
SIBLING_CALL_P (insn) = 1;
emit_barrier ();
+ /* Ensure we have a global entry point for the thunk. ??? We could
+ avoid that if the target routine doesn't need a global entry point,
+ but we do not know whether this is the case at this point. */
+ if (DEFAULT_ABI == ABI_ELFv2)
+ cfun->machine->r2_setup_needed = true;
+
/* Run just enough of rest_of_compilation to get the insns emitted.
There's not really enough bulk here to make other passes such as
instruction scheduling worth while. Note that use_thunk calls
@@ -24436,7 +25194,7 @@ output_profile_hook (int labelno ATTRIBUTE_UNUSED)
if (TARGET_PROFILE_KERNEL)
return;
- if (DEFAULT_ABI == ABI_AIX)
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
{
#ifndef NO_PROFILE_COUNTERS
# define NO_PROFILE_COUNTERS 0
@@ -24580,29 +25338,9 @@ output_function_profiler (FILE *file, int labelno)
break;
case ABI_AIX:
+ case ABI_ELFv2:
case ABI_DARWIN:
- if (!TARGET_PROFILE_KERNEL)
- {
- /* Don't do anything, done in output_profile_hook (). */
- }
- else
- {
- gcc_assert (!TARGET_32BIT);
-
- asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
- asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
-
- if (cfun->static_chain_decl != NULL)
- {
- asm_fprintf (file, "\tstd %s,24(%s)\n",
- reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- asm_fprintf (file, "\tld %s,24(%s)\n",
- reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
- }
- else
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- }
+ /* Don't do anything, done in output_profile_hook (). */
break;
}
}
@@ -26538,6 +27276,11 @@ rs6000_trampoline_size (void)
ret = (TARGET_32BIT) ? 12 : 24;
break;
+ case ABI_ELFv2:
+ gcc_assert (!TARGET_32BIT);
+ ret = 32;
+ break;
+
case ABI_DARWIN:
case ABI_V4:
ret = (TARGET_32BIT) ? 40 : 48;
@@ -26593,6 +27336,7 @@ rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
break;
/* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
+ case ABI_ELFv2:
case ABI_DARWIN:
case ABI_V4:
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
@@ -26887,7 +27631,7 @@ rs6000_ms_bitfield_layout_p (const_tree record_type)
static void
rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_AIX
+ if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& TARGET_MINIMAL_TOC
&& !TARGET_RELOCATABLE)
{
@@ -26908,7 +27652,8 @@ rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
else
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
}
- else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
+ else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && !TARGET_RELOCATABLE)
fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
else
{
@@ -27458,7 +28203,7 @@ rs6000_elf_reloc_rw_mask (void)
{
if (flag_pic)
return 3;
- else if (DEFAULT_ABI == ABI_AIX)
+ else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
return 2;
else
return 0;
@@ -27534,7 +28279,7 @@ rs6000_elf_asm_out_destructor (rtx symbol, int priority)
void
rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
{
- if (TARGET_64BIT)
+ if (TARGET_64BIT && DEFAULT_ABI != ABI_ELFv2)
{
fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
ASM_OUTPUT_LABEL (file, name);
@@ -27600,8 +28345,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
fprintf (file, "%s:\n", desc_name);
fprintf (file, "\t.long %s\n", orig_name);
fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
- if (DEFAULT_ABI == ABI_AIX)
- fputs ("\t.long 0\n", file);
+ fputs ("\t.long 0\n", file);
fprintf (file, "\t.previous\n");
}
ASM_OUTPUT_LABEL (file, name);
@@ -27630,7 +28374,7 @@ rs6000_elf_file_end (void)
}
#endif
#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD)
- if (TARGET_32BIT)
+ if (TARGET_32BIT || DEFAULT_ABI == ABI_ELFv2)
file_end_indicate_exec_stack ();
#endif
}
@@ -29361,6 +30105,8 @@ rs6000_function_value (const_tree valtype,
{
enum machine_mode mode;
unsigned int regno;
+ enum machine_mode elt_mode;
+ int n_elts;
/* Special handling for structs in darwin64. */
if (TARGET_MACHO
@@ -29380,6 +30126,36 @@ rs6000_function_value (const_tree valtype,
/* Otherwise fall through to standard ABI rules. */
}
+ /* The ELFv2 ABI returns homogeneous VFP aggregates in registers. */
+ if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (valtype), valtype,
+ &elt_mode, &n_elts))
+ {
+ int first_reg, n_regs, i;
+ rtx par;
+
+ if (SCALAR_FLOAT_MODE_P (elt_mode))
+ {
+ /* _Decimal128 must use even/odd register pairs. */
+ first_reg = (elt_mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
+ n_regs = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
+ }
+ else
+ {
+ first_reg = ALTIVEC_ARG_RETURN;
+ n_regs = 1;
+ }
+
+ par = gen_rtx_PARALLEL (TYPE_MODE (valtype), rtvec_alloc (n_elts));
+ for (i = 0; i < n_elts; i++)
+ {
+ rtx r = gen_rtx_REG (elt_mode, first_reg + i * n_regs);
+ rtx off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
+ XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+
+ return par;
+ }
+
if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
{
/* Long long return value need be split in -mpowerpc64, 32bit ABI. */
@@ -30585,118 +31361,149 @@ rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
}
-/* A function pointer under AIX is a pointer to a data area whose first word
- contains the actual address of the function, whose second word contains a
- pointer to its TOC, and whose third word contains a value to place in the
- static chain register (r11). Note that if we load the static chain, our
- "trampoline" need not have any executable code. */
+
+/* Expand code to perform a call under the AIX or ELFv2 ABI. */
void
-rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag)
+rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
{
+ rtx toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
+ rtx toc_load = NULL_RTX;
+ rtx toc_restore = NULL_RTX;
rtx func_addr;
- rtx toc_reg;
- rtx sc_reg;
- rtx stack_ptr;
- rtx stack_toc_offset;
- rtx stack_toc_mem;
- rtx func_toc_offset;
- rtx func_toc_mem;
- rtx func_sc_offset;
- rtx func_sc_mem;
+ rtx abi_reg = NULL_RTX;
+ rtx call[4];
+ int n_call;
rtx insn;
- rtx (*call_func) (rtx, rtx, rtx, rtx);
- rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx);
-
- stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
- toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
- /* Load up address of the actual function. */
- func_desc = force_reg (Pmode, func_desc);
- func_addr = gen_reg_rtx (Pmode);
- emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
-
- if (TARGET_32BIT)
- {
+ /* Handle longcall attributes. */
+ if (INTVAL (cookie) & CALL_LONG)
+ func_desc = rs6000_longcall_ref (func_desc);
+
+ /* Handle indirect calls. */
+ if (GET_CODE (func_desc) != SYMBOL_REF
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func_desc)))
+ {
+ /* Save the TOC into its reserved slot before the call,
+ and prepare to restore it after the call. */
+ rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+ rtx stack_toc_offset = GEN_INT (RS6000_TOC_SAVE_SLOT);
+ rtx stack_toc_mem = gen_frame_mem (Pmode,
+ gen_rtx_PLUS (Pmode, stack_ptr,
+ stack_toc_offset));
+ toc_restore = gen_rtx_SET (VOIDmode, toc_reg, stack_toc_mem);
+
+ /* Can we optimize saving the TOC in the prologue or
+ do we need to do it at every call? */
+ if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
+ cfun->machine->save_toc_in_prologue = true;
+ else
+ {
+ MEM_VOLATILE_P (stack_toc_mem) = 1;
+ emit_move_insn (stack_toc_mem, toc_reg);
+ }
- stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT);
- func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT);
- func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT);
- if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
+ if (DEFAULT_ABI == ABI_ELFv2)
{
- call_func = gen_call_indirect_aix32bit;
- call_value_func = gen_call_value_indirect_aix32bit;
+ /* A function pointer in the ELFv2 ABI is just a plain address, but
+ the ABI requires it to be loaded into r12 before the call. */
+ func_addr = gen_rtx_REG (Pmode, 12);
+ emit_move_insn (func_addr, func_desc);
+ abi_reg = func_addr;
}
else
{
- call_func = gen_call_indirect_aix32bit_nor11;
- call_value_func = gen_call_value_indirect_aix32bit_nor11;
+ /* A function pointer under AIX is a pointer to a data area whose
+ first word contains the actual address of the function, whose
+ second word contains a pointer to its TOC, and whose third word
+ contains a value to place in the static chain register (r11).
+ Note that if we load the static chain, our "trampoline" need
+ not have any executable code. */
+
+ /* Load up address of the actual function. */
+ func_desc = force_reg (Pmode, func_desc);
+ func_addr = gen_reg_rtx (Pmode);
+ emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
+
+ /* Prepare to load the TOC of the called function. Note that the
+ TOC load must happen immediately before the actual call so
+ that unwinding the TOC registers works correctly. See the
+ comment in frob_update_context. */
+ rtx func_toc_offset = GEN_INT (GET_MODE_SIZE (Pmode));
+ rtx func_toc_mem = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, func_desc,
+ func_toc_offset));
+ toc_load = gen_rtx_USE (VOIDmode, func_toc_mem);
+
+ /* If we have a static chain, load it up. */
+ if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
+ {
+ rtx sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
+ rtx func_sc_offset = GEN_INT (2 * GET_MODE_SIZE (Pmode));
+ rtx func_sc_mem = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, func_desc,
+ func_sc_offset));
+ emit_move_insn (sc_reg, func_sc_mem);
+ abi_reg = sc_reg;
+ }
}
}
else
{
- stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT);
- func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT);
- func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT);
- if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
- {
- call_func = gen_call_indirect_aix64bit;
- call_value_func = gen_call_value_indirect_aix64bit;
- }
- else
- {
- call_func = gen_call_indirect_aix64bit_nor11;
- call_value_func = gen_call_value_indirect_aix64bit_nor11;
- }
+ /* Direct calls use the TOC: for local calls, the callee will
+ assume the TOC register is set; for non-local calls, the
+ PLT stub needs the TOC register. */
+ abi_reg = toc_reg;
+ func_addr = func_desc;
}
- /* Reserved spot to store the TOC. */
- stack_toc_mem = gen_frame_mem (Pmode,
- gen_rtx_PLUS (Pmode,
- stack_ptr,
- stack_toc_offset));
+ /* Create the call. */
+ call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), flag);
+ if (value != NULL_RTX)
+ call[0] = gen_rtx_SET (VOIDmode, value, call[0]);
+ n_call = 1;
- gcc_assert (cfun);
- gcc_assert (cfun->machine);
+ if (toc_load)
+ call[n_call++] = toc_load;
+ if (toc_restore)
+ call[n_call++] = toc_restore;
- /* Can we optimize saving the TOC in the prologue or do we need to do it at
- every call? */
- if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
- cfun->machine->save_toc_in_prologue = true;
+ call[n_call++] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
- else
- {
- MEM_VOLATILE_P (stack_toc_mem) = 1;
- emit_move_insn (stack_toc_mem, toc_reg);
- }
+ insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (n_call, call));
+ insn = emit_call_insn (insn);
- /* Calculate the address to load the TOC of the called function. We don't
- actually load this until the split after reload. */
- func_toc_mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode,
- func_desc,
- func_toc_offset));
+ /* Mention all registers defined by the ABI to hold information
+ as uses in CALL_INSN_FUNCTION_USAGE. */
+ if (abi_reg)
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg);
+}
- /* If we have a static chain, load it up. */
- if (TARGET_POINTERS_TO_NESTED_FUNCTIONS)
- {
- func_sc_mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode,
- func_desc,
- func_sc_offset));
+/* Expand code to perform a sibling call under the AIX or ELFv2 ABI. */
- sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
- emit_move_insn (sc_reg, func_sc_mem);
- }
+void
+rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
+{
+ rtx call[2];
+ rtx insn;
+
+ gcc_assert (INTVAL (cookie) == 0);
/* Create the call. */
- if (value)
- insn = call_value_func (value, func_addr, flag, func_toc_mem,
- stack_toc_mem);
- else
- insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem);
+ call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_desc), flag);
+ if (value != NULL_RTX)
+ call[0] = gen_rtx_SET (VOIDmode, value, call[0]);
+
+ call[1] = simple_return_rtx;
+
+ insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (2, call));
+ insn = emit_call_insn (insn);
- emit_call_insn (insn);
+ /* Note use of the TOC register. */
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, TOC_REGNUM));
+ /* We need to also mark a use of the link register since the function we
+ sibling-call to will use it to return to our caller. */
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, LR_REGNO));
}
/* Return whether we need to always update the saved TOC pointer when we update
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9b167b7399e..861fa02595d 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1527,21 +1527,14 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0 \
|| (flag_sanitize & SANITIZE_ADDRESS) != 0)
-/* Size of the outgoing register save area */
-#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_DARWIN) \
- ? (TARGET_64BIT ? 64 : 32) \
- : 0)
-
/* Size of the fixed area on the stack */
#define RS6000_SAVE_AREA \
- (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
+ ((DEFAULT_ABI == ABI_V4 ? 8 : DEFAULT_ABI == ABI_ELFv2 ? 16 : 24) \
<< (TARGET_64BIT ? 1 : 0))
-/* MEM representing address to save the TOC register */
-#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
- plus_constant (Pmode, stack_pointer_rtx, \
- (TARGET_32BIT ? 20 : 40)))
+/* Stack offset for toc save slot. */
+#define RS6000_TOC_SAVE_SLOT \
+ ((DEFAULT_ABI == ABI_ELFv2 ? 12 : 20) << (TARGET_64BIT ? 1 : 0))
/* Align an address */
#define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
@@ -1591,7 +1584,7 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
/* Define this if stack space is still allocated for a parameter passed
in a register. The value is the number of bytes allocated to this
area. */
-#define REG_PARM_STACK_SPACE(FNDECL) RS6000_REG_SAVE
+#define REG_PARM_STACK_SPACE(FNDECL) rs6000_reg_parm_stack_space((FNDECL))
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
@@ -1635,9 +1628,8 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
#define FP_ARG_MIN_REG 33
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
-#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_DARWIN) \
- ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
+#define FP_ARG_MAX_REG (DEFAULT_ABI == ABI_V4 \
+ ? FP_ARG_V4_MAX_REG : FP_ARG_AIX_MAX_REG)
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
/* Minimum and maximum AltiVec registers used to hold arguments. */
@@ -1645,10 +1637,17 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
#define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11)
#define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1)
+/* Maximum number of registers per ELFv2 homogeneous aggregate argument. */
+#define AGGR_ARG_NUM_REG 8
+
/* Return registers */
#define GP_ARG_RETURN GP_ARG_MIN_REG
#define FP_ARG_RETURN FP_ARG_MIN_REG
#define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
+#define FP_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? FP_ARG_RETURN \
+ : (FP_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
+#define ALTIVEC_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? ALTIVEC_ARG_RETURN \
+ : (ALTIVEC_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
/* Flags for the call/call_value rtl operations set up by function_arg */
#define CALL_NORMAL 0x00000000 /* no special processing */
@@ -1668,8 +1667,10 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
On RS/6000, this is r3, fp1, and v2 (for AltiVec). */
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == GP_ARG_RETURN \
- || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT && TARGET_FPRS) \
- || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI))
+ || ((N) >= FP_ARG_RETURN && (N) <= FP_ARG_MAX_RETURN \
+ && TARGET_HARD_FLOAT && TARGET_FPRS) \
+ || ((N) >= ALTIVEC_ARG_RETURN && (N) <= ALTIVEC_ARG_MAX_RETURN \
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI))
/* 1 if N is a possible register number for function argument passing.
On RS/6000, these are r3-r10 and fp1-fp13.
@@ -1793,11 +1794,8 @@ typedef struct rs6000_args
/* Number of bytes into the frame return addresses can be found. See
rs6000_stack_info in rs6000.c for more information on how the different
abi's store the return address. */
-#define RETURN_ADDRESS_OFFSET \
- ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_DARWIN) ? (TARGET_32BIT ? 8 : 16) : \
- (DEFAULT_ABI == ABI_V4) ? 4 : \
- (internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0))
+#define RETURN_ADDRESS_OFFSET \
+ ((DEFAULT_ABI == ABI_V4 ? 4 : 8) << (TARGET_64BIT ? 1 : 0))
/* The current return address is in link register (65). The return address
of anything farther back is accessed normally at an offset of 8 from the
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d57168d3bb0..089a229ab4e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -56,18 +56,6 @@
(TFHAR_REGNO 114)
(TFIAR_REGNO 115)
(TEXASR_REGNO 116)
-
- ; ABI defined stack offsets for storing the TOC pointer with AIX calls.
- (TOC_SAVE_OFFSET_32BIT 20)
- (TOC_SAVE_OFFSET_64BIT 40)
-
- ; Function TOC offset in the AIX function descriptor.
- (AIX_FUNC_DESC_TOC_32BIT 4)
- (AIX_FUNC_DESC_TOC_64BIT 8)
-
- ; Static chain offset in the AIX function descriptor.
- (AIX_FUNC_DESC_SC_32BIT 8)
- (AIX_FUNC_DESC_SC_64BIT 16)
])
;;
@@ -5226,7 +5214,7 @@
"TARGET_<MODE>_FPR"
"@
fcmpu %0,%1,%2
- xscmpudp %x0,%x1,%x2"
+ xscmpudp %0,%x1,%x2"
[(set_attr "type" "fpcompare")])
;; Floating point conversions
@@ -5237,8 +5225,8 @@
"")
(define_insn_and_split "*extendsfdf2_fpr"
- [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wy,?wy,wv")
- (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wz,Z")))]
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wv")
+ (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"@
#
@@ -5360,7 +5348,7 @@
"TARGET_<MODE>_FPR && TARGET_CMPB"
"@
fcpsgn %0,%2,%1
- xscpsgn<VSs> %x0,%x2,%x1"
+ xscpsgn<Fvsx> %x0,%x2,%x1"
[(set_attr "type" "fp")])
;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
@@ -10081,8 +10069,8 @@
;; Use of fprs is disparaged slightly otherwise reload prefers to reload
;; a gpr into a fpr instead of reloading an invalid 'Y' address
(define_insn "*movdi_internal32"
- [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r,?wa")
- (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF,O"))]
+ [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
+ (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
"! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
@@ -10093,8 +10081,7 @@
stfd%U0%X0 %1,%0
lfd%U1%X1 %0,%1
fmr %0,%1
- #
- xxlxor %x0,%x0,%x0"
+ #"
[(set_attr_alternative "type"
[(const_string "store")
(const_string "load")
@@ -10114,8 +10101,7 @@
(const_string "fpload_u")
(const_string "fpload")))
(const_string "fp")
- (const_string "*")
- (const_string "vecsimple")])])
+ (const_string "*")])])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -10146,8 +10132,8 @@
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_insn "*movdi_internal64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,?Z,?wv,?wa,r,*h,*h,?wa,r,?*wg,r,?*wm")
- (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,wv,Z,wa,*h,r,0,O,*wg,r,*wm,r"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wm")
+ (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wm,r"))]
"TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
@@ -10161,13 +10147,9 @@
stfd%U0%X0 %1,%0
lfd%U1%X1 %0,%1
fmr %0,%1
- stxsd%U0x %x1,%y0
- lxsd%U1x %x0,%y1
- xxlor %x0,%x1,%x1
mf%1 %0
mt%0 %1
nop
- xxlxor %x0,%x0,%x0
mftgpr %0,%1
mffgpr %0,%1
mfvsrd %0,%x1
@@ -10206,24 +10188,14 @@
(const_string "fpload_u")
(const_string "fpload")))
(const_string "fp")
- (if_then_else
- (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
- (const_string "fpstore_ux")
- (const_string "fpstore"))
- (if_then_else
- (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
- (const_string "fpload_ux")
- (const_string "fpload"))
- (const_string "vecsimple")
(const_string "mfjmpr")
(const_string "mtjmpr")
(const_string "*")
- (const_string "vecsimple")
(const_string "mftgpr")
(const_string "mffgpr")
(const_string "mftgpr")
(const_string "mffgpr")])
- (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4")])
;; Generate all one-bits and clear left or right.
;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
@@ -11213,7 +11185,7 @@
(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
UNSPEC_TLSGD)
(clobber (reg:SI LR_REGNO))]
- "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+ "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
{
if (TARGET_CMODEL != CMODEL_SMALL)
return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
@@ -11322,7 +11294,8 @@
(unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
UNSPEC_TLSGD)
(clobber (reg:SI LR_REGNO))]
- "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+ "HAVE_AS_TLS && TARGET_TLS_MARKERS
+ && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
"bl %z1(%3@tlsgd)\;nop"
[(set_attr "type" "branch")
(set_attr "length" "8")])
@@ -11354,7 +11327,7 @@
(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
UNSPEC_TLSLD)
(clobber (reg:SI LR_REGNO))]
- "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+ "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
{
if (TARGET_CMODEL != CMODEL_SMALL)
return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
@@ -11457,7 +11430,8 @@
(match_operand 2 "" "g")))
(unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
(clobber (reg:SI LR_REGNO))]
- "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+ "HAVE_AS_TLS && TARGET_TLS_MARKERS
+ && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
"bl %z1(%&@tlsld)\;nop"
[(set_attr "type" "branch")
(set_attr "length" "8")])
@@ -11828,7 +11802,7 @@
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_TOC))
(use (reg:SI 2))])]
- "DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
"*
{
char buf[30];
@@ -11843,7 +11817,7 @@
[(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(unspec:DI [(const_int 0)] UNSPEC_TOC))
(use (reg:DI 2))])]
- "DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
"*
{
char buf[30];
@@ -11873,7 +11847,7 @@
[(parallel [(set (reg:SI LR_REGNO)
(match_operand:SI 0 "immediate_operand" "s"))
(use (unspec [(match_dup 0)] UNSPEC_TOC))])]
- "TARGET_ELF && DEFAULT_ABI != ABI_AIX
+ "TARGET_ELF && DEFAULT_ABI == ABI_V4
&& (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
"")
@@ -11881,7 +11855,7 @@
[(set (reg:SI LR_REGNO)
(match_operand:SI 0 "immediate_operand" "s"))
(use (unspec [(match_dup 0)] UNSPEC_TOC))]
- "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX
+ "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
&& (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
"bcl 20,31,%0\\n%0:"
[(set_attr "type" "branch")
@@ -11891,7 +11865,7 @@
[(set (reg:SI LR_REGNO)
(match_operand:SI 0 "immediate_operand" "s"))
(use (unspec [(match_dup 0)] UNSPEC_TOC))]
- "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX
+ "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
&& (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
"*
{
@@ -11911,7 +11885,7 @@
(label_ref (match_operand 1 "" ""))]
UNSPEC_TOCPTR))
(match_dup 1)])]
- "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
+ "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
"")
(define_insn "load_toc_v4_PIC_1b_normal"
@@ -11920,7 +11894,7 @@
(label_ref (match_operand 1 "" ""))]
UNSPEC_TOCPTR))
(match_dup 1)]
- "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
+ "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
"bcl 20,31,$+8\;.long %0-$"
[(set_attr "type" "branch")
(set_attr "length" "8")])
@@ -11931,7 +11905,7 @@
(label_ref (match_operand 1 "" ""))]
UNSPEC_TOCPTR))
(match_dup 1)]
- "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
+ "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
"*
{
char name[32];
@@ -11949,7 +11923,7 @@
(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(minus:SI (match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")))))]
- "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
+ "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
"lwz %0,%2-%3(%1)"
[(set_attr "type" "load")])
@@ -11959,7 +11933,7 @@
(high:SI
(minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
(match_operand:SI 3 "symbol_ref_operand" "s")))))]
- "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
+ "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
"addis %0,%1,%2-%3@ha")
(define_insn "load_toc_v4_PIC_3c"
@@ -11967,7 +11941,7 @@
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
(match_operand:SI 3 "symbol_ref_operand" "s"))))]
- "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
+ "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
"addi %0,%1,%2-%3@l")
;; If the TOC is shared over a translation unit, as happens with all
@@ -12109,8 +12083,13 @@
operands[0] = XEXP (operands[0], 0);
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
+ DONE;
+ }
+
if (GET_CODE (operands[0]) != SYMBOL_REF
- || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
|| (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
{
if (INTVAL (operands[2]) & CALL_LONG)
@@ -12123,12 +12102,6 @@
operands[0] = force_reg (Pmode, operands[0]);
break;
- case ABI_AIX:
- /* AIX function pointers are really pointers to a three word
- area. */
- rs6000_call_indirect_aix (NULL_RTX, operands[0], operands[1]);
- DONE;
-
default:
gcc_unreachable ();
}
@@ -12154,8 +12127,13 @@
operands[1] = XEXP (operands[1], 0);
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
+ DONE;
+ }
+
if (GET_CODE (operands[1]) != SYMBOL_REF
- || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
|| (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
{
if (INTVAL (operands[3]) & CALL_LONG)
@@ -12168,12 +12146,6 @@
operands[1] = force_reg (Pmode, operands[1]);
break;
- case ABI_AIX:
- /* AIX function pointers are really pointers to a three word
- area. */
- rs6000_call_indirect_aix (operands[0], operands[1], operands[2]);
- DONE;
-
default:
gcc_unreachable ();
}
@@ -12265,135 +12237,6 @@
[(set_attr "type" "branch")
(set_attr "length" "4,8")])
-;; Call to indirect functions with the AIX abi using a 3 word descriptor.
-;; Operand0 is the addresss of the function to call
-;; Operand1 is the flag for System V.4 for unprototyped or FP registers
-;; Operand2 is the location in the function descriptor to load r2 from
-;; Operand3 is the stack location to hold the current TOC pointer
-
-(define_insn "call_indirect_aix<ptrsize>"
- [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
- (match_operand 1 "" "g,g"))
- (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
- (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
- (use (reg:P STATIC_CHAIN_REGNUM))
- (clobber (reg:P LR_REGNO))]
- "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS"
- "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
- [(set_attr "type" "jmpreg")
- (set_attr "length" "12")])
-
-;; Like call_indirect_aix<ptrsize>, but no use of the static chain
-;; Operand0 is the addresss of the function to call
-;; Operand1 is the flag for System V.4 for unprototyped or FP registers
-;; Operand2 is the location in the function descriptor to load r2 from
-;; Operand3 is the stack location to hold the current TOC pointer
-
-(define_insn "call_indirect_aix<ptrsize>_nor11"
- [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
- (match_operand 1 "" "g,g"))
- (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
- (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
- (clobber (reg:P LR_REGNO))]
- "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS"
- "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
- [(set_attr "type" "jmpreg")
- (set_attr "length" "12")])
-
-;; Operand0 is the return result of the function
-;; Operand1 is the addresss of the function to call
-;; Operand2 is the flag for System V.4 for unprototyped or FP registers
-;; Operand3 is the location in the function descriptor to load r2 from
-;; Operand4 is the stack location to hold the current TOC pointer
-
-(define_insn "call_value_indirect_aix<ptrsize>"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
- (match_operand 2 "" "g,g")))
- (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
- (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
- (use (reg:P STATIC_CHAIN_REGNUM))
- (clobber (reg:P LR_REGNO))]
- "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS"
- "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
- [(set_attr "type" "jmpreg")
- (set_attr "length" "12")])
-
-;; Like call_value_indirect_aix<ptrsize>, but no use of the static chain
-;; Operand0 is the return result of the function
-;; Operand1 is the addresss of the function to call
-;; Operand2 is the flag for System V.4 for unprototyped or FP registers
-;; Operand3 is the location in the function descriptor to load r2 from
-;; Operand4 is the stack location to hold the current TOC pointer
-
-(define_insn "call_value_indirect_aix<ptrsize>_nor11"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
- (match_operand 2 "" "g,g")))
- (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
- (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
- (clobber (reg:P LR_REGNO))]
- "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS"
- "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
- [(set_attr "type" "jmpreg")
- (set_attr "length" "12")])
-
-;; Call to function which may be in another module. Restore the TOC
-;; pointer (r2) after the call unless this is System V.
-;; Operand2 is nonzero if we are using the V.4 calling sequence and
-;; either the function was not prototyped, or it was prototyped as a
-;; variable argument function. It is > 0 if FP registers were passed
-;; and < 0 if they were not.
-
-(define_insn "*call_nonlocal_aix32"
- [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
- (match_operand 1 "" "g"))
- (use (match_operand:SI 2 "immediate_operand" "O"))
- (clobber (reg:SI LR_REGNO))]
- "TARGET_32BIT
- && DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
- "bl %z0\;nop"
- [(set_attr "type" "branch")
- (set_attr "length" "8")])
-
-(define_insn "*call_nonlocal_aix64"
- [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
- (match_operand 1 "" "g"))
- (use (match_operand:SI 2 "immediate_operand" "O"))
- (clobber (reg:SI LR_REGNO))]
- "TARGET_64BIT
- && DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
- "bl %z0\;nop"
- [(set_attr "type" "branch")
- (set_attr "length" "8")])
-
-(define_insn "*call_value_nonlocal_aix32"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
- (match_operand 2 "" "g")))
- (use (match_operand:SI 3 "immediate_operand" "O"))
- (clobber (reg:SI LR_REGNO))]
- "TARGET_32BIT
- && DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
- "bl %z1\;nop"
- [(set_attr "type" "branch")
- (set_attr "length" "8")])
-
-(define_insn "*call_value_nonlocal_aix64"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
- (match_operand 2 "" "g")))
- (use (match_operand:SI 3 "immediate_operand" "O"))
- (clobber (reg:SI LR_REGNO))]
- "TARGET_64BIT
- && DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
- "bl %z1\;nop"
- [(set_attr "type" "branch")
- (set_attr "length" "8")])
;; A function pointer under System V is just a normal pointer
;; operands[0] is the function pointer
@@ -12576,6 +12419,104 @@
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
+
+;; Call to AIX abi function in the same module.
+
+(define_insn "*call_local_aix<mode>"
+ [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
+ (match_operand 1 "" "g"))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
+ "bl %z0"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
+(define_insn "*call_value_local_aix<mode>"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
+ (match_operand 2 "" "g")))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
+ "bl %z1"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
+;; Call to AIX abi function which may be in another module.
+;; Restore the TOC pointer (r2) after the call.
+
+(define_insn "*call_nonlocal_aix<mode>"
+ [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
+ (match_operand 1 "" "g"))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
+ "bl %z0\;nop"
+ [(set_attr "type" "branch")
+ (set_attr "length" "8")])
+
+(define_insn "*call_value_nonlocal_aix<mode>"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
+ (match_operand 2 "" "g")))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
+ "bl %z1\;nop"
+ [(set_attr "type" "branch")
+ (set_attr "length" "8")])
+
+;; Call to indirect functions with the AIX abi using a 3 word descriptor.
+;; Operand0 is the addresss of the function to call
+;; Operand2 is the location in the function descriptor to load r2 from
+;; Operand3 is the stack location to hold the current TOC pointer
+
+(define_insn "*call_indirect_aix<mode>"
+ [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
+ (match_operand 1 "" "g,g"))
+ (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
+ (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_AIX"
+ "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
+ [(set_attr "type" "jmpreg")
+ (set_attr "length" "12")])
+
+(define_insn "*call_value_indirect_aix<mode>"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
+ (match_operand 2 "" "g,g")))
+ (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
+ (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_AIX"
+ "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
+ [(set_attr "type" "jmpreg")
+ (set_attr "length" "12")])
+
+;; Call to indirect functions with the ELFv2 ABI.
+;; Operand0 is the addresss of the function to call
+;; Operand2 is the stack location to hold the current TOC pointer
+
+(define_insn "*call_indirect_elfv2<mode>"
+ [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
+ (match_operand 1 "" "g,g"))
+ (set (reg:P TOC_REGNUM) (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_ELFv2"
+ "b%T0l\;<ptrload> 2,%2"
+ [(set_attr "type" "jmpreg")
+ (set_attr "length" "8")])
+
+(define_insn "*call_value_indirect_elfv2<mode>"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
+ (match_operand 2 "" "g,g")))
+ (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
+ (clobber (reg:P LR_REGNO))]
+ "DEFAULT_ABI == ABI_ELFv2"
+ "b%T1l\;<ptrload> 2,%3"
+ [(set_attr "type" "jmpreg")
+ (set_attr "length" "8")])
+
+
;; Call subroutine returning any type.
(define_expand "untyped_call"
[(parallel [(call (match_operand 0 "" "")
@@ -12623,6 +12564,39 @@
gcc_assert (GET_CODE (operands[1]) == CONST_INT);
operands[0] = XEXP (operands[0], 0);
+
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
+ DONE;
+ }
+}")
+
+(define_expand "sibcall_value"
+ [(parallel [(set (match_operand 0 "register_operand" "")
+ (call (mem:SI (match_operand 1 "address_operand" ""))
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))
+ (use (reg:SI LR_REGNO))
+ (simple_return)])]
+ ""
+ "
+{
+#if TARGET_MACHO
+ if (MACHOPIC_INDIRECT)
+ operands[1] = machopic_indirect_call_target (operands[1]);
+#endif
+
+ gcc_assert (GET_CODE (operands[1]) == MEM);
+ gcc_assert (GET_CODE (operands[2]) == CONST_INT);
+
+ operands[1] = XEXP (operands[1], 0);
+
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
+ DONE;
+ }
}")
;; this and similar patterns must be marked as using LR, otherwise
@@ -12690,7 +12664,6 @@
[(set_attr "type" "branch")
(set_attr "length" "4,8")])
-
(define_insn "*sibcall_value_local64"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
@@ -12712,35 +12685,6 @@
[(set_attr "type" "branch")
(set_attr "length" "4,8")])
-(define_insn "*sibcall_nonlocal_aix<mode>"
- [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
- (match_operand 1 "" "g,g"))
- (use (match_operand:SI 2 "immediate_operand" "O,O"))
- (use (reg:SI LR_REGNO))
- (simple_return)]
- "DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
- "@
- b %z0
- b%T0"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-(define_insn "*sibcall_value_nonlocal_aix<mode>"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
- (match_operand 2 "" "g,g")))
- (use (match_operand:SI 3 "immediate_operand" "O,O"))
- (use (reg:SI LR_REGNO))
- (simple_return)]
- "DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
- "@
- b %z1
- b%T1"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
(define_insn "*sibcall_nonlocal_sysv<mode>"
[(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
(match_operand 1 "" ""))
@@ -12771,27 +12715,6 @@
[(set_attr "type" "branch")
(set_attr "length" "4,8,4,8")])
-(define_expand "sibcall_value"
- [(parallel [(set (match_operand 0 "register_operand" "")
- (call (mem:SI (match_operand 1 "address_operand" ""))
- (match_operand 2 "" "")))
- (use (match_operand 3 "" ""))
- (use (reg:SI LR_REGNO))
- (simple_return)])]
- ""
- "
-{
-#if TARGET_MACHO
- if (MACHOPIC_INDIRECT)
- operands[1] = machopic_indirect_call_target (operands[1]);
-#endif
-
- gcc_assert (GET_CODE (operands[1]) == MEM);
- gcc_assert (GET_CODE (operands[2]) == CONST_INT);
-
- operands[1] = XEXP (operands[1], 0);
-}")
-
(define_insn "*sibcall_value_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
@@ -12823,6 +12746,31 @@
[(set_attr "type" "branch")
(set_attr "length" "4,8,4,8")])
+;; AIX ABI sibling call patterns.
+
+(define_insn "*sibcall_aix<mode>"
+ [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
+ (match_operand 1 "" "g,g"))
+ (simple_return)]
+ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
+ "@
+ b %z0
+ b%T0"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
+(define_insn "*sibcall_value_aix<mode>"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
+ (match_operand 2 "" "g,g")))
+ (simple_return)]
+ "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
+ "@
+ b %z1
+ b%T1"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
(define_expand "sibcall_epilogue"
[(use (const_int 0))]
""
@@ -15051,6 +14999,14 @@
"mfcr %0"
[(set_attr "type" "mfcr")])
+(define_insn "*crsave"
+ [(match_parallel 0 "crsave_operation"
+ [(set (match_operand:SI 1 "memory_operand" "=m")
+ (match_operand:SI 2 "gpc_reg_operand" "r"))])]
+ ""
+ "stw %2,%1"
+ [(set_attr "type" "store")])
+
(define_insn "*stmw"
[(match_parallel 0 "stmw_operation"
[(set (match_operand:SI 1 "memory_operand" "=m")
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 94e4b3883dc..347f76e207c 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -369,6 +369,14 @@ mabi=no-spe
Target RejectNegative Var(rs6000_spe_abi, 0)
Do not use the SPE ABI extensions
+mabi=elfv1
+Target RejectNegative Var(rs6000_elf_abi, 1) Save
+Use the ELFv1 ABI
+
+mabi=elfv2
+Target RejectNegative Var(rs6000_elf_abi, 2)
+Use the ELFv2 ABI
+
; These are here for testing during development only, do not document
; in the manual please.
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 0cc8ffb8cb3..ba4ceb3ff2e 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -45,7 +45,7 @@
& (OPTION_MASK_RELOCATABLE \
| OPTION_MASK_MINIMAL_TOC)) \
&& flag_pic > 1) \
- || DEFAULT_ABI == ABI_AIX)
+ || DEFAULT_ABI != ABI_V4)
#define TARGET_BITFIELD_TYPE (! TARGET_NO_BITFIELD_TYPE)
#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
@@ -147,7 +147,7 @@ do { \
rs6000_sdata_name); \
} \
\
- else if (flag_pic && DEFAULT_ABI != ABI_AIX \
+ else if (flag_pic && DEFAULT_ABI == ABI_V4 \
&& (rs6000_sdata == SDATA_EABI \
|| rs6000_sdata == SDATA_SYSV)) \
{ \
@@ -173,14 +173,14 @@ do { \
error ("-mrelocatable and -mno-minimal-toc are incompatible"); \
} \
\
- if (TARGET_RELOCATABLE && rs6000_current_abi == ABI_AIX) \
+ if (TARGET_RELOCATABLE && rs6000_current_abi != ABI_V4) \
{ \
rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \
error ("-mrelocatable and -mcall-%s are incompatible", \
rs6000_abi_name); \
} \
\
- if (!TARGET_64BIT && flag_pic > 1 && rs6000_current_abi == ABI_AIX) \
+ if (!TARGET_64BIT && flag_pic > 1 && rs6000_current_abi != ABI_V4) \
{ \
flag_pic = 0; \
error ("-fPIC and -mcall-%s are incompatible", \
@@ -193,7 +193,7 @@ do { \
} \
\
/* Treat -fPIC the same as -mrelocatable. */ \
- if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX) \
+ if (flag_pic > 1 && DEFAULT_ABI == ABI_V4) \
{ \
rs6000_isa_flags |= OPTION_MASK_RELOCATABLE | OPTION_MASK_MINIMAL_TOC; \
TARGET_NO_FP_IN_TOC = 1; \
@@ -317,7 +317,7 @@ do { \
/* Put PC relative got entries in .got2. */
#define MINIMAL_TOC_SECTION_ASM_OP \
- (TARGET_RELOCATABLE || (flag_pic && DEFAULT_ABI != ABI_AIX) \
+ (TARGET_RELOCATABLE || (flag_pic && DEFAULT_ABI == ABI_V4) \
? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
diff --git a/gcc/config/rs6000/sysv4le.h b/gcc/config/rs6000/sysv4le.h
index 3901122a738..ba56004cdfb 100644
--- a/gcc/config/rs6000/sysv4le.h
+++ b/gcc/config/rs6000/sysv4le.h
@@ -34,3 +34,7 @@
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" }
+
+/* Little-endian PowerPC64 Linux uses the ELF v2 ABI by default. */
+#define LINUX64_DEFAULT_ABI_ELFv2
+
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index 68214d91316..10a401813d1 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -966,8 +966,8 @@
operands[2], operands[3]));
else
{
- /* Avoid the "subtract from splat31" workaround for vperm since
- we have changed lvsr to lvsl instead. */
+ /* We have changed lvsr to lvsl, so to complete the transformation
+ of vperm for LE, we must swap the inputs. */
rtx unspec = gen_rtx_UNSPEC (<MODE>mode,
gen_rtvec (3, operands[2],
operands[1], operands[3]),
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 756cd061614..89860927a82 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -344,9 +344,9 @@ rx_mode_dependent_address_p (const_rtx addr, addr_space_t as ATTRIBUTE_UNUSED)
case CONST_INT:
/* REG+INT is only mode independent if INT is a
- multiple of 4, positive and will fit into 8-bits. */
+ multiple of 4, positive and will fit into 16-bits. */
if (((INTVAL (addr) & 3) == 0)
- && IN_RANGE (INTVAL (addr), 4, 252))
+ && IN_RANGE (INTVAL (addr), 4, 0xfffc))
return false;
return true;
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 681e179eccf..39453038fe7 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "optabs.h"
#include "gimple.h"
+#include "gimplify.h"
#include "df.h"
#include "params.h"
#include "cfgloop.h"
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 215d4cec6e5..0be07b86dab 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "ggc.h"
#include "gimple.h"
+#include "gimplify.h"
#include "cfgloop.h"
#include "alloc-pool.h"
#include "tm-constrs.h"
@@ -5774,24 +5775,21 @@ fixup_addr_diff_vecs (rtx first)
int
barrier_align (rtx barrier_or_label)
{
- rtx next = next_active_insn (barrier_or_label), pat, prev;
+ rtx next, pat;
- if (! next)
+ if (! barrier_or_label)
return 0;
- pat = PATTERN (next);
-
- if (GET_CODE (pat) == ADDR_DIFF_VEC)
+ if (LABEL_P (barrier_or_label)
+ && NEXT_INSN (barrier_or_label)
+ && JUMP_TABLE_DATA_P (NEXT_INSN (barrier_or_label)))
return 2;
- if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN)
- /* This is a barrier in front of a constant table. */
- return 0;
-
- prev = prev_active_insn (barrier_or_label);
- if (GET_CODE (PATTERN (prev)) == ADDR_DIFF_VEC)
+ if (BARRIER_P (barrier_or_label)
+ && PREV_INSN (barrier_or_label)
+ && JUMP_TABLE_DATA_P (PREV_INSN (barrier_or_label)))
{
- pat = PATTERN (prev);
+ pat = PATTERN (PREV_INSN (barrier_or_label));
/* If this is a very small table, we want to keep the alignment after
the table to the minimum for proper code alignment. */
return ((optimize_size
@@ -5800,6 +5798,17 @@ barrier_align (rtx barrier_or_label)
? 1 << TARGET_SHMEDIA : align_jumps_log);
}
+ next = next_active_insn (barrier_or_label);
+
+ if (! next)
+ return 0;
+
+ pat = PATTERN (next);
+
+ if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN)
+ /* This is a barrier in front of a constant table. */
+ return 0;
+
if (optimize_size)
return 0;
@@ -5824,13 +5833,12 @@ barrier_align (rtx barrier_or_label)
(fill_eager_delay_slots) and the branch is to the insn after the insn
after the barrier. */
- /* PREV is presumed to be the JUMP_INSN for the barrier under
- investigation. Skip to the insn before it. */
-
int slot, credit;
bool jump_to_next = false;
- prev = prev_real_insn (prev);
+ /* Skip to the insn before the JUMP_INSN before the barrier under
+ investigation. */
+ rtx prev = prev_real_insn (prev_active_insn (barrier_or_label));
for (slot = 2, credit = (1 << (CACHE_LOG - 2)) + 2;
credit >= 0 && prev && NONJUMP_INSN_P (prev);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index f2511961580..f4508021de3 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "common/common-target.h"
#include "gimple.h"
+#include "gimplify.h"
#include "langhooks.h"
#include "reload.h"
#include "params.h"
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 38c441d9a03..e344b73fce6 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -46,6 +46,7 @@
#include "params.h"
#include "machmode.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tm-constrs.h"
#include "ddg.h"
#include "sbitmap.h"
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index 30d6d781576..3a08534be51 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -44,6 +44,7 @@
#include "tm_p.h"
#include "langhooks.h"
#include "gimple.h"
+#include "gimplify.h"
#include "df.h"
#include "reload.h"
#include "ggc.h"
diff --git a/gcc/config/tilegx/tilegx.c b/gcc/config/tilegx/tilegx.c
index dafa44c0674..bf13d11b820 100644
--- a/gcc/config/tilegx/tilegx.c
+++ b/gcc/config/tilegx/tilegx.c
@@ -41,6 +41,7 @@
#include "timevar.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "cfgloop.h"
#include "tilegx-builtins.h"
#include "tilegx-multiply.h"
diff --git a/gcc/config/tilepro/tilepro.c b/gcc/config/tilepro/tilepro.c
index 5e3be831fb1..d497f64125f 100644
--- a/gcc/config/tilepro/tilepro.c
+++ b/gcc/config/tilepro/tilepro.c
@@ -42,6 +42,7 @@
#include "timevar.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "cfgloop.h"
#include "tilepro-builtins.h"
#include "tilepro-multiply.h"
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 7faf7de9968..6385c5df555 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "langhooks.h"
#include "gimple.h"
+#include "gimplify.h"
#include "df.h"
diff --git a/gcc/configure b/gcc/configure
index 759862c00f7..c9bbd653e52 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -915,6 +915,7 @@ with_plugin_ld
enable_gnu_indirect_function
enable_initfini_array
enable_comdat
+with_glibc_version
enable_gnu_unique_object
enable_linker_build_id
with_long_double_128
@@ -1680,6 +1681,8 @@ Optional Packages:
both]
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-plugin-ld=[ARG] specify the plugin linker
+ --with-glibc-version=M.N
+ assume GCC used with glibc version M.N or later
--with-long-double-128 use 128-bit long double by default
--with-gc={page,zone} this option is not supported anymore. It used to
choose the garbage collection mechanism to use with
@@ -4800,9 +4803,6 @@ case "${target}" in
i[34567]86-*-* | x86_64-*-*)
PICFLAG_FOR_TARGET=-fpic
;;
- m68k-*-*)
- PICFLAG_FOR_TARGET=-fpic
- ;;
# FIXME: Override -fPIC default in libgcc only?
sh-*-linux* | sh[2346lbe]*-*-linux*)
PICFLAG_FOR_TARGET=-fpic
@@ -26386,6 +26386,60 @@ $as_echo "#define HAVE_GAS_LCOMM_WITH_ALIGNMENT 1" >>confdefs.h
fi
+if test x$with_sysroot = x && test x$host = x$target \
+ && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" \
+ && test "$prefix" != "NONE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define PREFIX_INCLUDE_DIR "$prefix/include"
+_ACEOF
+
+fi
+
+if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then
+ if test "x$with_headers" != x; then
+ target_header_dir=$with_headers
+ elif test "x$with_sysroot" = x; then
+ target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
+ elif test "x$with_build_sysroot" != "x"; then
+ target_header_dir="${with_build_sysroot}${native_system_header_dir}"
+ elif test "x$with_sysroot" = xyes; then
+ target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
+ else
+ target_header_dir="${with_sysroot}${native_system_header_dir}"
+ fi
+else
+ target_header_dir=${native_system_header_dir}
+fi
+
+# Determine the version of glibc, if any, used on the target.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for target glibc version" >&5
+$as_echo_n "checking for target glibc version... " >&6; }
+
+# Check whether --with-glibc-version was given.
+if test "${with_glibc_version+set}" = set; then :
+ withval=$with_glibc_version;
+if echo "$with_glibc_version" | grep '^[0-9][0-9]*\.[0-9][0-9]*$'; then
+ glibc_version_major=`echo "$with_glibc_version" | sed -e 's/\..*//'`
+ glibc_version_minor=`echo "$with_glibc_version" | sed -e 's/.*\.//'`
+else
+ as_fn_error "option --with-glibc-version requires a version number M.N" "$LINENO" 5
+fi
+else
+
+glibc_version_major=0
+glibc_version_minor=0
+if test -f $target_header_dir/features.h \
+ && glibc_version_major_define=`$EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+[0-9]' $target_header_dir/features.h` \
+ && glibc_version_minor_define=`$EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+[0-9]' $target_header_dir/features.h`; then
+ glibc_version_major=`echo "$glibc_version_major_define" | sed -e 's/.*__GLIBC__[ ]*//'`
+ glibc_version_minor=`echo "$glibc_version_minor_define" | sed -e 's/.*__GLIBC_MINOR__[ ]*//'`
+fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibc_version_major.$glibc_version_minor" >&5
+$as_echo "$glibc_version_major.$glibc_version_minor" >&6; }
+
# Check whether --enable-gnu-unique-object was given.
if test "${enable_gnu_unique_object+set}" = set; then :
enableval=$enable_gnu_unique_object; case $enable_gnu_unique_object in
@@ -26427,16 +26481,12 @@ $as_echo "$gcc_cv_as_gnu_unique_object" >&6; }
if test $gcc_cv_as_gnu_unique_object = yes; then
# We need to unquote above to to use the definition from config.gcc.
# Also check for ld.so support, i.e. glibc 2.11 or higher.
- if test x$host = x$build -a x$host = x$target &&
- ldd --version 2>/dev/null &&
- glibcver=`ldd --version 2>/dev/null | sed 's/.* //;q'`; then
- glibcmajor=`expr "$glibcver" : "\([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "[2-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2011 ; then
- enable_gnu_unique_object=yes
- fi
- fi
+
+if test $glibc_version_major -gt 2 \
+ || ( test $glibc_version_major -eq 2 && test $glibc_version_minor -ge 11 ); then :
+ enable_gnu_unique_object=yes
+fi
+
fi
fi
@@ -27015,32 +27065,6 @@ $as_echo "#define HAVE_LD_SYSROOT 1" >>confdefs.h
fi
-if test x$with_sysroot = x && test x$host = x$target \
- && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" \
- && test "$prefix" != "NONE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define PREFIX_INCLUDE_DIR "$prefix/include"
-_ACEOF
-
-fi
-
-if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then
- if test "x$with_headers" != x; then
- target_header_dir=$with_headers
- elif test "x$with_sysroot" = x; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
- elif test "x$with_build_sysroot" != "x"; then
- target_header_dir="${with_build_sysroot}${native_system_header_dir}"
- elif test "x$with_sysroot" = xyes; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
- else
- target_header_dir="${with_sysroot}${native_system_header_dir}"
- fi
-else
- target_header_dir=${native_system_header_dir}
-fi
-
# Test for stack protector support in target C library.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking __stack_chk_fail in target C library" >&5
$as_echo_n "checking __stack_chk_fail in target C library... " >&6; }
@@ -27052,18 +27076,16 @@ else
*-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu)
# glibc 2.4 and later provides __stack_chk_fail and
# either __stack_chk_guard, or TLS access to stack guard canary.
+
+if test $glibc_version_major -gt 2 \
+ || ( test $glibc_version_major -eq 2 && test $glibc_version_minor -ge 4 ); then :
+ gcc_cv_libc_provides_ssp=yes
+else
+
if test -f $target_header_dir/features.h \
&& $EGREP '^[ ]*#[ ]*define[ ]+__GNU_LIBRARY__[ ]+([1-9][0-9]|[6-9])' \
$target_header_dir/features.h > /dev/null; then
- if $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+([1-9][0-9]|[3-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+2' \
- $target_header_dir/features.h > /dev/null \
- && $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+([1-9][0-9]|[4-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \
+ if $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \
$target_header_dir/features.h > /dev/null && \
test -f $target_header_dir/bits/uClibc_config.h && \
$EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC_HAS_SSP__[ ]+1' \
@@ -27076,6 +27098,7 @@ else
$target_header_dir/sys/cdefs.h > /dev/null; then
gcc_cv_libc_provides_ssp=yes
fi
+fi
;;
*-*-gnu*)
# Avoid complicated tests (see
@@ -27131,12 +27154,19 @@ case "$target" in
if test "${with_long_double_128+set}" = set; then :
withval=$with_long_double_128; gcc_cv_target_ldbl128="$with_long_double_128"
else
- gcc_cv_target_ldbl128=no
+
+if test $glibc_version_major -gt 2 \
+ || ( test $glibc_version_major -eq 2 && test $glibc_version_minor -ge 4 ); then :
+ gcc_cv_target_ldbl128=yes
+else
+
+ gcc_cv_target_ldbl128=no
grep '^[ ]*#[ ]*define[ ][ ]*__LONG_DOUBLE_MATH_OPTIONAL' \
$target_header_dir/bits/wordsize.h > /dev/null 2>&1 \
&& gcc_cv_target_ldbl128=yes
fi
+fi
;;
esac
@@ -27570,8 +27600,8 @@ if test x"$enable_plugin" = x"yes"; then
$as_echo_n "checking for exported symbols... " >&6; }
if test "x$export_sym_check" != x; then
echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
- ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
+ ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
+ if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
: # No need to use a flag
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -27580,8 +27610,8 @@ $as_echo "yes" >&6; }
$as_echo "yes" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -rdynamic" >&5
$as_echo_n "checking for -rdynamic... " >&6; }
- ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
+ ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
+ if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
plugin_rdynamic=yes
pluginlibs="-rdynamic"
else
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 8670c7b7cee..5935a6ede94 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4306,6 +4306,50 @@ gcc_GAS_CHECK_FEATURE([.lcomm with alignment], gcc_cv_as_lcomm_with_alignment,
[AC_DEFINE(HAVE_GAS_LCOMM_WITH_ALIGNMENT, 1,
[Define if your assembler supports .lcomm with an alignment field.])])
+if test x$with_sysroot = x && test x$host = x$target \
+ && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" \
+ && test "$prefix" != "NONE"; then
+ AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
+[Define to PREFIX/include if cpp should also search that directory.])
+fi
+
+if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then
+ if test "x$with_headers" != x; then
+ target_header_dir=$with_headers
+ elif test "x$with_sysroot" = x; then
+ target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
+ elif test "x$with_build_sysroot" != "x"; then
+ target_header_dir="${with_build_sysroot}${native_system_header_dir}"
+ elif test "x$with_sysroot" = xyes; then
+ target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
+ else
+ target_header_dir="${with_sysroot}${native_system_header_dir}"
+ fi
+else
+ target_header_dir=${native_system_header_dir}
+fi
+
+# Determine the version of glibc, if any, used on the target.
+AC_MSG_CHECKING([for target glibc version])
+AC_ARG_WITH([glibc-version],
+ [AS_HELP_STRING([--with-glibc-version=M.N],
+ [assume GCC used with glibc version M.N or later])], [
+if [echo "$with_glibc_version" | grep '^[0-9][0-9]*\.[0-9][0-9]*$']; then
+ glibc_version_major=`echo "$with_glibc_version" | sed -e 's/\..*//'`
+ glibc_version_minor=`echo "$with_glibc_version" | sed -e 's/.*\.//'`
+else
+ AC_MSG_ERROR([option --with-glibc-version requires a version number M.N])
+fi], [
+glibc_version_major=0
+glibc_version_minor=0
+[if test -f $target_header_dir/features.h \
+ && glibc_version_major_define=`$EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+[0-9]' $target_header_dir/features.h` \
+ && glibc_version_minor_define=`$EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+[0-9]' $target_header_dir/features.h`; then
+ glibc_version_major=`echo "$glibc_version_major_define" | sed -e 's/.*__GLIBC__[ ]*//'`
+ glibc_version_minor=`echo "$glibc_version_minor_define" | sed -e 's/.*__GLIBC_MINOR__[ ]*//'`
+fi]])
+AC_MSG_RESULT([$glibc_version_major.$glibc_version_minor])
+
AC_ARG_ENABLE(gnu-unique-object,
[AS_HELP_STRING([--enable-gnu-unique-object],
[enable the use of the @gnu_unique_object ELF extension on glibc systems])],
@@ -4319,16 +4363,8 @@ Valid choices are 'yes' and 'no'.]) ;;
[.type foo, '$target_type_format_char'gnu_unique_object],,
# We need to unquote above to to use the definition from config.gcc.
# Also check for ld.so support, i.e. glibc 2.11 or higher.
- [[if test x$host = x$build -a x$host = x$target &&
- ldd --version 2>/dev/null &&
- glibcver=`ldd --version 2>/dev/null | sed 's/.* //;q'`; then
- glibcmajor=`expr "$glibcver" : "\([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "[2-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2011 ; then
- enable_gnu_unique_object=yes
- fi
- fi]])])
+ [GCC_GLIBC_VERSION_GTE_IFELSE([2], [11], [enable_gnu_unique_object=yes], )]
+ )])
if test x$enable_gnu_unique_object = xyes; then
AC_DEFINE(HAVE_GAS_GNU_UNIQUE_OBJECT, 1,
[Define if your assembler supports @gnu_unique_object.])
@@ -4816,49 +4852,19 @@ if test x"$gcc_cv_ld_sysroot" = xyes; then
[Define if your linker supports --sysroot.])
fi
-if test x$with_sysroot = x && test x$host = x$target \
- && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" \
- && test "$prefix" != "NONE"; then
- AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
-[Define to PREFIX/include if cpp should also search that directory.])
-fi
-
-if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then
- if test "x$with_headers" != x; then
- target_header_dir=$with_headers
- elif test "x$with_sysroot" = x; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
- elif test "x$with_build_sysroot" != "x"; then
- target_header_dir="${with_build_sysroot}${native_system_header_dir}"
- elif test "x$with_sysroot" = xyes; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
- else
- target_header_dir="${with_sysroot}${native_system_header_dir}"
- fi
-else
- target_header_dir=${native_system_header_dir}
-fi
-
# Test for stack protector support in target C library.
AC_CACHE_CHECK(__stack_chk_fail in target C library,
gcc_cv_libc_provides_ssp,
[gcc_cv_libc_provides_ssp=no
case "$target" in
*-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu)
- [# glibc 2.4 and later provides __stack_chk_fail and
+ # glibc 2.4 and later provides __stack_chk_fail and
# either __stack_chk_guard, or TLS access to stack guard canary.
- if test -f $target_header_dir/features.h \
+ GCC_GLIBC_VERSION_GTE_IFELSE([2], [4], [gcc_cv_libc_provides_ssp=yes], [
+ [if test -f $target_header_dir/features.h \
&& $EGREP '^[ ]*#[ ]*define[ ]+__GNU_LIBRARY__[ ]+([1-9][0-9]|[6-9])' \
$target_header_dir/features.h > /dev/null; then
- if $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+([1-9][0-9]|[3-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+2' \
- $target_header_dir/features.h > /dev/null \
- && $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+([1-9][0-9]|[4-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \
+ if $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \
$target_header_dir/features.h > /dev/null && \
test -f $target_header_dir/bits/uClibc_config.h && \
$EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC_HAS_SSP__[ ]+1' \
@@ -4870,7 +4876,7 @@ AC_CACHE_CHECK(__stack_chk_fail in target C library,
&& $EGREP '^[ ]*#[ ]*define[ ]+__BIONIC__[ ]+1' \
$target_header_dir/sys/cdefs.h > /dev/null; then
gcc_cv_libc_provides_ssp=yes
- fi]
+ fi]])
;;
*-*-gnu*)
# Avoid complicated tests (see
@@ -4913,11 +4919,12 @@ case "$target" in
[AS_HELP_STRING([--with-long-double-128],
[use 128-bit long double by default])],
gcc_cv_target_ldbl128="$with_long_double_128",
- [[gcc_cv_target_ldbl128=no
+ [GCC_GLIBC_VERSION_GTE_IFELSE([2], [4], [gcc_cv_target_ldbl128=yes], [
+ [gcc_cv_target_ldbl128=no
grep '^[ ]*#[ ]*define[ ][ ]*__LONG_DOUBLE_MATH_OPTIONAL' \
$target_header_dir/bits/wordsize.h > /dev/null 2>&1 \
&& gcc_cv_target_ldbl128=yes
- ]])
+ ]])])
;;
esac
if test x$gcc_cv_target_ldbl128 = xyes; then
@@ -5334,15 +5341,15 @@ if test x"$enable_plugin" = x"yes"; then
AC_MSG_CHECKING([for exported symbols])
if test "x$export_sym_check" != x; then
echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
- ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
+ ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
+ if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
: # No need to use a flag
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([yes])
AC_MSG_CHECKING([for -rdynamic])
- ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
+ ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
+ if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
plugin_rdynamic=yes
pluginlibs="-rdynamic"
else
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6369f053217..2a16220dda2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,120 @@
+2013-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * Make-lang.in (CXX_AND_OBJCXX_OBJS): Depend on cp/cp-cilkplus.o.
+ * cp-cilkplus.c: New file.
+ * cp-tree.h (cpp_validate_cilk_plus_loop): Protoize.
+ * parser.c (cp_parser_cilk_simd): New.
+ (cp_debug_parser): Add case for IN_CILK_SIMD_FOR.
+ (cp_parser_jump_statement): Same.
+ (cp_parser_omp_for_cond): Add new argument.
+ Add case for NE_EXPR.
+ (cp_parser_omp_for_loop): Pass new argument to
+ cp_parser_omp_for_cond.
+ Handle CILK_SIMD nodes.
+ Abstract initilization code to..
+ (cp_parser_omp_for_loop_init): ...here.
+ (cp_parser_pragma): Add case for PRAGMA_CILK_SIMD.
+ (cp_parser_cilk_simd_vectorlength): New.
+ (cp_parser_cilk_simd_linear): New.
+ (cp_parser_cilk_simd_clause_name): New.
+ (cp_parser_cilk_simd_all_clauses): New.
+ (cp_parser_cilk_simd): New.
+ * parser.h (IN_CILK_SIMD_FOR): New macro.
+ * pt.c (tsubst_expr): Add case for CILK_SIMD.
+ * typeck2.c (cxx_readonly_error): Pass location argument to
+ readonly_error.
+
+2013-11-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57887
+ * parser.c (cp_parser_late_parsing_nsdmi): Call
+ maybe_begin_member_template_processing.
+ * pt.c (maybe_begin_member_template_processing): Handle NSDMIs.
+ (inline_needs_template_parms): Adjust.
+
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * class.c: Include only gimplify.h and gimple.h as needed.
+ * cp-gimplify.c: Likewise.
+ * error.c: Likewise.
+ * init.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * vtable-class-hierarchy.c: Likewise.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * class.c: Include gimplify.h.
+ * cp-gimplify.c: Likewise.
+ * error.c: Likewise.
+ * init.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * vtable-class-hierarchy.c: Likewise.
+ * decl2.c: Don't include gimple.h.
+ * except.c: Likewise.
+ * method.c: Include pointer-set.h instead of gimple.h.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ * pt.c (convert_generic_types_to_packs): New function to transform
+ a range of implicitly introduced non-pack template parms to be parameter
+ packs.
+ * cp-tree.h (convert_generic_types_to_packs): Declare.
+ * parser.c (cp_parser_parameter_declaration_list): If a function
+ parameter pack contains generic types, convert them to packs prior to
+ grokdeclarator.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/58534
+ PR c++/58536
+ PR c++/58548
+ PR c++/58549
+ PR c++/58637
+ * parser.h (struct cp_parser): New members implicit_template_parms,
+ implicit_template_scope and auto_is_implicit_function_template_parm_p.
+ * parser.c (add_implicit_template_parms): Refactor as ...
+ (synthesize_implicit_template_parm): ... this to append a new template
+ type parm to the current template parameter list (introducing a new list
+ if necessary). Removed push_deferring_access_checks.
+ (finish_fully_implicit_template): Removed pop_deferring_access_checks.
+ (cp_parser_new): Initialize new cp_parser members.
+ (cp_parser_parameter_declaration_clause): Consider auto as implicit
+ template parm when parsing a parameter declaration (unless parsing an
+ explicit specialization).
+ (cp_parser_parameter_declaration_list): Remove local
+ implicit_template_parms counter and reset cp_parser implicit template
+ state when complete.
+ (cp_parser_lambda_expression): Reset implicit template cp_parser members
+ whilst generating lambda class.
+ (cp_parser_function_definition_after_declarator): Reset implicit
+ template cp_parser members whilst parsing function definition.
+ (make_generic_type_name): Respell '<autoN>' as 'auto:N' which works
+ better with template diagnostics.
+ (cp_parser_simple_type_specifier): Synthesize implicit template parm on
+ parsing 'auto' if auto_is_implicit_function_template_parm_p and provide
+ diagnostics ...
+ * decl.c (grokdeclarator): ... that were previously done here.
+
+2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57734
+ * pt.c (lookup_template_class_1): Handle alias template declarations
+ of enumeration types.
+
+2013-11-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cvt.c (cp_convert_to_pointer): Call build_ptrmemfunc before
+ maybe_warn_zero_as_null_pointer_constant to avoid duplicate
+ -Wzero-as-null-pointer-constant diagnostics.
+
+ * typeck.c (build_ptrmemfunc): Use cp_build_c_cast.
+
2013-11-06 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/11006
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 9bcea20bd02..424f2e6cdc5 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -76,6 +76,7 @@ CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \
cp/mangle.o cp/cp-objcp-common.o cp/name-lookup.o cp/cxx-pretty-print.o \
+ cp/cp-cilkplus.o \
cp/cp-gimplify.o cp/cp-array-notation.o cp/lambda.o \
cp/vtable-class-hierarchy.o $(CXX_C_OBJS)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index a0c3ab7e72b..9158d8a6665 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -36,6 +36,8 @@ along with GCC; see the file COPYING3. If not see
#include "splay-tree.h"
#include "pointer-set.h"
#include "hash-table.h"
+#include "gimple.h"
+#include "gimplify.h"
#include "wide-int.h"
/* The number of nested classes being processed. If we are not in the
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
new file mode 100644
index 00000000000..5c1090a097f
--- /dev/null
+++ b/gcc/cp/cp-cilkplus.c
@@ -0,0 +1,77 @@
+/* This file is part of the Intel(R) Cilk(TM) Plus support
+ This file contains routines to handle Cilk Plus specific
+ routines for the C++ Compiler.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>.
+
+ 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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "cp-tree.h"
+#include "diagnostic-core.h"
+
+
+/* Callback for cp_walk_tree to validate the body of a pragma simd loop
+ or _cilk_for loop.
+
+ This function is passed in as a function pointer to walk_tree. *TP is
+ the current tree pointer, *WALK_SUBTREES is set to 0 by this function if
+ recursing into TP's subtrees is unnecessary. *DATA is a bool variable that
+ is set to false if an error has occured. */
+
+static tree
+cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
+{
+ bool *valid = (bool *) data;
+ location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) :
+ UNKNOWN_LOCATION;
+
+ if (!tp || !*tp)
+ return NULL_TREE;
+
+ if (TREE_CODE (*tp) == THROW_EXPR)
+ {
+ error_at (loc, "throw expressions are not allowed inside loops "
+ "marked with pragma simd");
+ *walk_subtrees = 0;
+ *valid = false;
+ }
+ else if (TREE_CODE (*tp) == TRY_BLOCK)
+ {
+ error_at (loc, "try statements are not allowed inside loops marked "
+ "with #pragma simd");
+ *valid = false;
+ *walk_subtrees = 0;
+ }
+ return NULL_TREE;
+}
+
+
+/* Walks through all the subtrees of BODY using walk_tree to make sure
+ invalid statements/expressions are not found inside BODY. Returns
+ false if any invalid statements are found. */
+
+bool
+cpp_validate_cilk_plus_loop (tree body)
+{
+ bool valid = true;
+ cp_walk_tree (&body, cpp_validate_cilk_plus_loop_aux,
+ (void *) &valid, NULL);
+ return valid;
+}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 53b0ca8f928..c464719ad42 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-common.h"
#include "tree-iterator.h"
#include "gimple.h"
+#include "gimplify.h"
#include "hashtab.h"
#include "pointer-set.h"
#include "flags.h"
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7a1c900193a..cb782516ee7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5469,6 +5469,7 @@ extern tree type_uses_auto (tree);
extern tree type_uses_auto_or_concept (tree);
extern void append_type_to_template_for_access_check (tree, tree, tree,
location_t);
+extern tree convert_generic_types_to_packs (tree, int, int);
extern tree splice_late_return_type (tree, tree);
extern bool is_auto (const_tree);
extern bool is_auto_or_concept (const_tree);
@@ -6176,6 +6177,9 @@ extern void vtv_save_class_info (tree);
extern void vtv_recover_class_info (void);
extern void vtv_build_vtable_verify_fndecl (void);
+/* In cp-cilkplus.c. */
+extern bool cpp_validate_cilk_plus_loop (tree);
+
/* In cp/cp-array-notations.c */
extern tree expand_array_notation_exprs (tree);
bool cilkplus_an_triplet_types_ok_p (location_t, tree, tree, tree,
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 0efb5548528..c7201d540e1 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -204,13 +204,13 @@ cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain)
if (null_ptr_cst_p (expr))
{
- if (complain & tf_warning)
- maybe_warn_zero_as_null_pointer_constant (expr, loc);
-
if (TYPE_PTRMEMFUNC_P (type))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
/*c_cast_p=*/false, complain);
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (expr, loc);
+
/* A NULL pointer-to-data-member is represented by -1, not by
zero. */
tree val = (TYPE_PTRDATAMEM_P (type)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2040f8df2ca..330c0606308 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10381,33 +10381,11 @@ grokdeclarator (const cp_declarator *declarator,
if (type_uses_auto (type))
{
- if (template_parm_flag)
- {
- error ("template parameter declared %<auto%>");
- type = error_mark_node;
- }
- else if (decl_context == CATCHPARM)
- {
- error ("catch parameter declared %<auto%>");
- type = error_mark_node;
- }
- else if (current_class_type && LAMBDA_TYPE_P (current_class_type))
- {
- if (cxx_dialect < cxx1y)
- pedwarn (location_of (type), 0,
- "use of %<auto%> in lambda parameter declaration "
- "only available with "
- "-std=c++1y or -std=gnu++1y");
- }
- else if (cxx_dialect < cxx1y)
- pedwarn (location_of (type), 0,
- "use of %<auto%> in parameter declaration "
- "only available with "
- "-std=c++1y or -std=gnu++1y");
+ if (cxx_dialect >= cxx1y)
+ error ("%<auto%> parameter not permitted in this context");
else
- pedwarn (location_of (type), OPT_Wpedantic,
- "ISO C++ forbids use of %<auto%> in parameter "
- "declaration");
+ error ("parameter declared %<auto%>");
+ type = error_mark_node;
}
/* A parameter declared as an array of T is really a pointer to T.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a094ff3b546..18456848492 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -45,7 +45,6 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-pragma.h"
#include "dumpfile.h"
#include "intl.h"
-#include "gimple.h"
#include "pointer-set.h"
#include "splay-tree.h"
#include "langhooks.h"
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index daac0fde7e6..ac2128d13b0 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-iterator.h"
#include "target.h"
-#include "gimple.h"
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1bfe7d16e88..32d9f9bf45f 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "cp-tree.h"
#include "flags.h"
#include "target.h"
+#include "gimple.h"
+#include "gimplify.h"
#include "wide-int.h"
static bool begin_init_stmts (tree *, tree *);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index fa3f083542b..d15d0a4d6f6 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "common/common-target.h"
#include "diagnostic.h"
#include "cgraph.h"
-#include "gimple.h"
+#include "pointer-set.h"
/* Various flags to control the mangling process. */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e4f77e8d68c..99d3f917360 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -233,6 +233,8 @@ static void cp_parser_initial_pragma
static tree cp_literal_operator_id
(const char *);
+static void cp_parser_cilk_simd
+ (cp_parser *, cp_token *);
static bool cp_parser_omp_declare_reduction_exprs
(tree, cp_parser *);
@@ -531,6 +533,8 @@ cp_debug_parser (FILE *file, cp_parser *parser)
parser->in_statement & IN_SWITCH_STMT);
cp_debug_print_flag (file, "Parsing a structured OpenMP block",
parser->in_statement & IN_OMP_BLOCK);
+ cp_debug_print_flag (file, "Parsing a Cilk Plus for loop",
+ parser->in_statement & IN_CILK_SIMD_FOR);
cp_debug_print_flag (file, "Parsing a an OpenMP loop",
parser->in_statement & IN_OMP_FOR);
cp_debug_print_flag (file, "Parsing an if statement",
@@ -2107,8 +2111,8 @@ static bool cp_parser_ctor_initializer_opt_and_function_body
static tree cp_parser_late_parsing_omp_declare_simd
(cp_parser *, tree);
-static tree add_implicit_template_parms
- (cp_parser *, size_t, tree);
+static tree synthesize_implicit_template_parm
+ (cp_parser *);
static tree finish_fully_implicit_template
(cp_parser *, tree);
@@ -3443,7 +3447,10 @@ cp_parser_new (void)
parser->num_template_parameter_lists = 0;
/* Not declaring an implicit function template. */
+ parser->auto_is_implicit_function_template_parm_p = false;
parser->fully_implicit_function_template_p = false;
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
return parser;
}
@@ -8660,12 +8667,17 @@ cp_parser_lambda_expression (cp_parser* parser)
= parser->num_template_parameter_lists;
unsigned char in_statement = parser->in_statement;
bool in_switch_statement_p = parser->in_switch_statement_p;
- bool fully_implicit_function_template_p = parser->fully_implicit_function_template_p;
+ bool fully_implicit_function_template_p
+ = parser->fully_implicit_function_template_p;
+ tree implicit_template_parms = parser->implicit_template_parms;
+ cp_binding_level* implicit_template_scope = parser->implicit_template_scope;
parser->num_template_parameter_lists = 0;
parser->in_statement = 0;
parser->in_switch_statement_p = false;
parser->fully_implicit_function_template_p = false;
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
/* By virtue of defining a local class, a lambda expression has access to
the private variables of enclosing classes. */
@@ -8689,7 +8701,10 @@ cp_parser_lambda_expression (cp_parser* parser)
parser->num_template_parameter_lists = saved_num_template_parameter_lists;
parser->in_statement = in_statement;
parser->in_switch_statement_p = in_switch_statement_p;
- parser->fully_implicit_function_template_p = fully_implicit_function_template_p;
+ parser->fully_implicit_function_template_p
+ = fully_implicit_function_template_p;
+ parser->implicit_template_parms = implicit_template_parms;
+ parser->implicit_template_scope = implicit_template_scope;
}
pop_deferring_access_checks ();
@@ -10547,6 +10562,9 @@ cp_parser_jump_statement (cp_parser* parser)
case IN_OMP_FOR:
error_at (token->location, "break statement used with OpenMP for loop");
break;
+ case IN_CILK_SIMD_FOR:
+ error_at (token->location, "break statement used with Cilk Plus for loop");
+ break;
}
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
break;
@@ -10557,6 +10575,10 @@ cp_parser_jump_statement (cp_parser* parser)
case 0:
error_at (token->location, "continue statement not within a loop");
break;
+ case IN_CILK_SIMD_FOR:
+ error_at (token->location,
+ "continue statement within %<#pragma simd%> loop body");
+ /* Fall through. */
case IN_ITERATION_STMT:
case IN_OMP_FOR:
statement = finish_continue_stmt ();
@@ -14096,7 +14118,7 @@ cp_parser_explicit_specialization (cp_parser* parser)
cp_parser_single_declaration (parser,
/*checks=*/NULL,
/*member_p=*/false,
- /*explicit_specialization_p=*/true,
+ /*explicit_specialization_p=*/true,
/*friend_p=*/NULL);
/* We're done with the specialization. */
end_specialization ();
@@ -14398,10 +14420,33 @@ cp_parser_simple_type_specifier (cp_parser* parser,
case RID_VOID:
type = void_type_node;
break;
-
+
case RID_AUTO:
maybe_warn_cpp0x (CPP0X_AUTO);
- type = make_auto ();
+ if (parser->auto_is_implicit_function_template_parm_p)
+ {
+ type = synthesize_implicit_template_parm (parser);
+
+ if (current_class_type && LAMBDA_TYPE_P (current_class_type))
+ {
+ if (cxx_dialect < cxx1y)
+ pedwarn (location_of (type), 0,
+ "use of %<auto%> in lambda parameter declaration "
+ "only available with "
+ "-std=c++1y or -std=gnu++1y");
+ }
+ else if (cxx_dialect < cxx1y)
+ pedwarn (location_of (type), 0,
+ "use of %<auto%> in parameter declaration "
+ "only available with "
+ "-std=c++1y or -std=gnu++1y");
+ else
+ pedwarn (location_of (type), OPT_Wpedantic,
+ "ISO C++ forbids use of %<auto%> in parameter "
+ "declaration");
+ }
+ else
+ type = make_auto ();
break;
case RID_DECLTYPE:
@@ -17980,6 +18025,20 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
bool ellipsis_p;
bool is_error;
+ struct cleanup {
+ cp_parser* parser;
+ int auto_is_implicit_function_template_parm_p;
+ ~cleanup() {
+ parser->auto_is_implicit_function_template_parm_p
+ = auto_is_implicit_function_template_parm_p;
+ }
+ } cleanup = { parser, parser->auto_is_implicit_function_template_parm_p };
+
+ (void) cleanup;
+
+ if (!processing_specialization)
+ parser->auto_is_implicit_function_template_parm_p = true;
+
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* Check for trivial parameter-declaration-clauses. */
@@ -18064,17 +18123,16 @@ static tree
cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
{
tree parameters = NULL_TREE;
- tree *tail = &parameters;
+ tree *tail = &parameters;
bool saved_in_unbraced_linkage_specification_p;
int index = 0;
- int implicit_template_parms = 0;
/* Assume all will go well. */
*is_error = false;
/* The special considerations that apply to a function within an
unbraced linkage specifications do not apply to the parameters
to the function. */
- saved_in_unbraced_linkage_specification_p
+ saved_in_unbraced_linkage_specification_p
= parser->in_unbraced_linkage_specification_p;
parser->in_unbraced_linkage_specification_p = false;
@@ -18084,6 +18142,10 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
cp_parameter_declarator *parameter;
tree decl = error_mark_node;
bool parenthesized_p = false;
+ int template_parm_idx = (parser->num_template_parameter_lists?
+ TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
+ (current_template_parms)) : 0);
+
/* Parse the parameter. */
parameter
= cp_parser_parameter_declaration (parser,
@@ -18096,16 +18158,27 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
if (parameter)
{
+ /* If a function parameter pack was specified and an implicit template
+ parameter was introduced during cp_parser_parameter_declaration,
+ change any implicit parameters introduced into packs. */
+ if (parser->implicit_template_parms
+ && parameter->declarator
+ && parameter->declarator->parameter_pack_p)
+ {
+ int latest_template_parm_idx = TREE_VEC_LENGTH
+ (INNERMOST_TEMPLATE_PARMS (current_template_parms));
+
+ if (latest_template_parm_idx != template_parm_idx)
+ parameter->decl_specifiers.type = convert_generic_types_to_packs
+ (parameter->decl_specifiers.type,
+ template_parm_idx, latest_template_parm_idx);
+ }
+
decl = grokdeclarator (parameter->declarator,
&parameter->decl_specifiers,
PARM,
parameter->default_argument != NULL_TREE,
&parameter->decl_specifiers.attributes);
-
- if (TREE_TYPE (decl) != error_mark_node
- && parameter->decl_specifiers.type
- && is_auto_or_concept (parameter->decl_specifiers.type))
- ++implicit_template_parms;
}
deprecated_state = DEPRECATED_NORMAL;
@@ -18194,10 +18267,12 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
parser->in_unbraced_linkage_specification_p
= saved_in_unbraced_linkage_specification_p;
- if (parameters != error_mark_node && implicit_template_parms)
- parameters = add_implicit_template_parms (parser,
- implicit_template_parms,
- parameters);
+ if (cp_binding_level *its = parser->implicit_template_scope)
+ if (current_binding_level->level_chain == its)
+ {
+ parser->implicit_template_parms = 0;
+ parser->implicit_template_scope = 0;
+ }
return parameters;
}
@@ -22461,6 +22536,15 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
bool saved_in_function_body;
unsigned saved_num_template_parameter_lists;
cp_token *token;
+ bool fully_implicit_function_template_p
+ = parser->fully_implicit_function_template_p;
+ parser->fully_implicit_function_template_p = false;
+ tree implicit_template_parms
+ = parser->implicit_template_parms;
+ parser->implicit_template_parms = 0;
+ cp_binding_level* implicit_template_scope
+ = parser->implicit_template_scope;
+ parser->implicit_template_scope = 0;
saved_in_function_body = parser->in_function_body;
parser->in_function_body = true;
@@ -22533,6 +22617,13 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
= saved_num_template_parameter_lists;
parser->in_function_body = saved_in_function_body;
+ parser->fully_implicit_function_template_p
+ = fully_implicit_function_template_p;
+ parser->implicit_template_parms
+ = implicit_template_parms;
+ parser->implicit_template_scope
+ = implicit_template_scope;
+
if (parser->fully_implicit_function_template_p)
finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
@@ -23298,12 +23389,16 @@ cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
{
tree def;
+ maybe_begin_member_template_processing (field);
+
push_unparsed_function_queues (parser);
def = cp_parser_late_parse_one_default_arg (parser, field,
DECL_INITIAL (field),
NULL_TREE);
pop_unparsed_function_queues (parser);
+ maybe_end_member_template_processing ();
+
DECL_INITIAL (field) = def;
}
@@ -28507,7 +28602,7 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
/* Helper function, to parse omp for increment expression. */
static tree
-cp_parser_omp_for_cond (cp_parser *parser, tree decl)
+cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
{
tree cond = cp_parser_binary_expression (parser, false, true,
PREC_NOT_OPERATOR, NULL);
@@ -28525,6 +28620,10 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl)
case LT_EXPR:
case LE_EXPR:
break;
+ case NE_EXPR:
+ if (code == CILK_SIMD)
+ break;
+ /* Fall through: OpenMP disallows NE_EXPR. */
default:
return error_mark_node;
}
@@ -28634,6 +28733,186 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
}
+/* Parse the initialization statement of either an OpenMP for loop or
+ a Cilk Plus for loop.
+
+ PARSING_OPENMP is true if parsing OpenMP, or false if parsing Cilk
+ Plus.
+
+ Return true if the resulting construct should have an
+ OMP_CLAUSE_PRIVATE added to it. */
+
+static bool
+cp_parser_omp_for_loop_init (cp_parser *parser,
+ bool parsing_openmp,
+ tree &this_pre_body,
+ vec<tree, va_gc> *for_block,
+ tree &init,
+ tree &decl,
+ tree &real_decl)
+{
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ return false;
+
+ bool add_private_clause = false;
+
+ /* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):
+
+ init-expr:
+ var = lb
+ integer-type var = lb
+ random-access-iterator-type var = lb
+ pointer-type var = lb
+ */
+ cp_decl_specifier_seq type_specifiers;
+
+ /* First, try to parse as an initialized declaration. See
+ cp_parser_condition, from whence the bulk of this is copied. */
+
+ cp_parser_parse_tentatively (parser);
+ cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+ /*is_trailing_return=*/false,
+ &type_specifiers);
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* If parsing a type specifier seq succeeded, then this
+ MUST be a initialized declaration. */
+ tree asm_specification, attributes;
+ cp_declarator *declarator;
+
+ declarator = cp_parser_declarator (parser,
+ CP_PARSER_DECLARATOR_NAMED,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL,
+ /*member_p=*/false);
+ attributes = cp_parser_attributes_opt (parser);
+ asm_specification = cp_parser_asm_specification_opt (parser);
+
+ if (declarator == cp_error_declarator)
+ cp_parser_skip_to_end_of_statement (parser);
+
+ else
+ {
+ tree pushed_scope, auto_node;
+
+ decl = start_decl (declarator, &type_specifiers,
+ SD_INITIALIZED, attributes,
+ /*prefix_attributes=*/NULL_TREE,
+ &pushed_scope);
+
+ auto_node = type_uses_auto (TREE_TYPE (decl));
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
+ {
+ if (cp_lexer_next_token_is (parser->lexer,
+ CPP_OPEN_PAREN))
+ {
+ if (parsing_openmp)
+ error ("parenthesized initialization is not allowed in "
+ "OpenMP %<for%> loop");
+ else
+ error ("parenthesized initialization is "
+ "not allowed in for-loop");
+ }
+ else
+ /* Trigger an error. */
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+ init = error_mark_node;
+ cp_parser_skip_to_end_of_statement (parser);
+ }
+ else if (CLASS_TYPE_P (TREE_TYPE (decl))
+ || type_dependent_expression_p (decl)
+ || auto_node)
+ {
+ bool is_direct_init, is_non_constant_init;
+
+ init = cp_parser_initializer (parser,
+ &is_direct_init,
+ &is_non_constant_init);
+
+ if (auto_node)
+ {
+ TREE_TYPE (decl)
+ = do_auto_deduction (TREE_TYPE (decl), init,
+ auto_node);
+
+ if (!CLASS_TYPE_P (TREE_TYPE (decl))
+ && !type_dependent_expression_p (decl))
+ goto non_class;
+ }
+
+ cp_finish_decl (decl, init, !is_non_constant_init,
+ asm_specification,
+ LOOKUP_ONLYCONVERTING);
+ if (CLASS_TYPE_P (TREE_TYPE (decl)))
+ {
+ vec_safe_push (for_block, this_pre_body);
+ init = NULL_TREE;
+ }
+ else
+ init = pop_stmt_list (this_pre_body);
+ this_pre_body = NULL_TREE;
+ }
+ else
+ {
+ /* Consume '='. */
+ cp_lexer_consume_token (parser->lexer);
+ init = cp_parser_assignment_expression (parser, false, NULL);
+
+ non_class:
+ if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+ init = error_mark_node;
+ else
+ cp_finish_decl (decl, NULL_TREE,
+ /*init_const_expr_p=*/false,
+ asm_specification,
+ LOOKUP_ONLYCONVERTING);
+ }
+
+ if (pushed_scope)
+ pop_scope (pushed_scope);
+ }
+ }
+ else
+ {
+ cp_id_kind idk;
+ /* If parsing a type specifier sequence failed, then
+ this MUST be a simple expression. */
+ cp_parser_parse_tentatively (parser);
+ decl = cp_parser_primary_expression (parser, false, false,
+ false, &idk);
+ if (!cp_parser_error_occurred (parser)
+ && decl
+ && DECL_P (decl)
+ && CLASS_TYPE_P (TREE_TYPE (decl)))
+ {
+ tree rhs;
+
+ cp_parser_parse_definitely (parser);
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+ rhs = cp_parser_assignment_expression (parser, false, NULL);
+ finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
+ decl, NOP_EXPR,
+ rhs,
+ tf_warning_or_error));
+ add_private_clause = true;
+ }
+ else
+ {
+ decl = NULL;
+ cp_parser_abort_tentative_parse (parser);
+ init = cp_parser_expression (parser, false, NULL);
+ if (init)
+ {
+ if (TREE_CODE (init) == MODIFY_EXPR
+ || TREE_CODE (init) == MODOP_EXPR)
+ real_decl = TREE_OPERAND (init, 0);
+ }
+ }
+ }
+ return add_private_clause;
+}
+
/* Parse the restricted form of the for statement allowed by OpenMP. */
static tree
@@ -28679,157 +28958,13 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
init = decl = real_decl = NULL;
this_pre_body = push_stmt_list ();
- if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- {
- /* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):
-
- init-expr:
- var = lb
- integer-type var = lb
- random-access-iterator-type var = lb
- pointer-type var = lb
- */
- cp_decl_specifier_seq type_specifiers;
- /* First, try to parse as an initialized declaration. See
- cp_parser_condition, from whence the bulk of this is copied. */
+ add_private_clause
+ |= cp_parser_omp_for_loop_init (parser,
+ /*parsing_openmp=*/code != CILK_SIMD,
+ this_pre_body, for_block,
+ init, decl, real_decl);
- cp_parser_parse_tentatively (parser);
- cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
- /*is_trailing_return=*/false,
- &type_specifiers);
- if (cp_parser_parse_definitely (parser))
- {
- /* If parsing a type specifier seq succeeded, then this
- MUST be a initialized declaration. */
- tree asm_specification, attributes;
- cp_declarator *declarator;
-
- declarator = cp_parser_declarator (parser,
- CP_PARSER_DECLARATOR_NAMED,
- /*ctor_dtor_or_conv_p=*/NULL,
- /*parenthesized_p=*/NULL,
- /*member_p=*/false);
- attributes = cp_parser_attributes_opt (parser);
- asm_specification = cp_parser_asm_specification_opt (parser);
-
- if (declarator == cp_error_declarator)
- cp_parser_skip_to_end_of_statement (parser);
-
- else
- {
- tree pushed_scope, auto_node;
-
- decl = start_decl (declarator, &type_specifiers,
- SD_INITIALIZED, attributes,
- /*prefix_attributes=*/NULL_TREE,
- &pushed_scope);
-
- auto_node = type_uses_auto (TREE_TYPE (decl));
- if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
- {
- if (cp_lexer_next_token_is (parser->lexer,
- CPP_OPEN_PAREN))
- error ("parenthesized initialization is not allowed in "
- "OpenMP %<for%> loop");
- else
- /* Trigger an error. */
- cp_parser_require (parser, CPP_EQ, RT_EQ);
-
- init = error_mark_node;
- cp_parser_skip_to_end_of_statement (parser);
- }
- else if (CLASS_TYPE_P (TREE_TYPE (decl))
- || type_dependent_expression_p (decl)
- || auto_node)
- {
- bool is_direct_init, is_non_constant_init;
-
- init = cp_parser_initializer (parser,
- &is_direct_init,
- &is_non_constant_init);
-
- if (auto_node)
- {
- TREE_TYPE (decl)
- = do_auto_deduction (TREE_TYPE (decl), init,
- auto_node);
-
- if (!CLASS_TYPE_P (TREE_TYPE (decl))
- && !type_dependent_expression_p (decl))
- goto non_class;
- }
-
- cp_finish_decl (decl, init, !is_non_constant_init,
- asm_specification,
- LOOKUP_ONLYCONVERTING);
- if (CLASS_TYPE_P (TREE_TYPE (decl)))
- {
- vec_safe_push (for_block, this_pre_body);
- init = NULL_TREE;
- }
- else
- init = pop_stmt_list (this_pre_body);
- this_pre_body = NULL_TREE;
- }
- else
- {
- /* Consume '='. */
- cp_lexer_consume_token (parser->lexer);
- init = cp_parser_assignment_expression (parser, false, NULL);
-
- non_class:
- if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
- init = error_mark_node;
- else
- cp_finish_decl (decl, NULL_TREE,
- /*init_const_expr_p=*/false,
- asm_specification,
- LOOKUP_ONLYCONVERTING);
- }
-
- if (pushed_scope)
- pop_scope (pushed_scope);
- }
- }
- else
- {
- cp_id_kind idk;
- /* If parsing a type specifier sequence failed, then
- this MUST be a simple expression. */
- cp_parser_parse_tentatively (parser);
- decl = cp_parser_primary_expression (parser, false, false,
- false, &idk);
- if (!cp_parser_error_occurred (parser)
- && decl
- && DECL_P (decl)
- && CLASS_TYPE_P (TREE_TYPE (decl)))
- {
- tree rhs;
-
- cp_parser_parse_definitely (parser);
- cp_parser_require (parser, CPP_EQ, RT_EQ);
- rhs = cp_parser_assignment_expression (parser, false, NULL);
- finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
- decl, NOP_EXPR,
- rhs,
- tf_warning_or_error));
- add_private_clause = true;
- }
- else
- {
- decl = NULL;
- cp_parser_abort_tentative_parse (parser);
- init = cp_parser_expression (parser, false, NULL);
- if (init)
- {
- if (TREE_CODE (init) == MODIFY_EXPR
- || TREE_CODE (init) == MODOP_EXPR)
- real_decl = TREE_OPERAND (init, 0);
- }
- }
- }
- }
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
if (this_pre_body)
{
@@ -28918,7 +29053,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
cond = NULL;
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- cond = cp_parser_omp_for_cond (parser, decl);
+ cond = cp_parser_omp_for_cond (parser, decl, code);
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
incr = NULL;
@@ -28988,7 +29123,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
/* Note that we saved the original contents of this flag when we entered
the structured block, and so we don't need to re-save it here. */
- parser->in_statement = IN_OMP_FOR;
+ if (code == CILK_SIMD)
+ parser->in_statement = IN_CILK_SIMD_FOR;
+ else
+ parser->in_statement = IN_OMP_FOR;
/* Note that the grammar doesn't call for a structured block here,
though the loop as a whole is a structured block. */
@@ -31043,6 +31181,16 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
return true;
}
+ case PRAGMA_CILK_SIMD:
+ if (context == pragma_external)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma simd%> must be inside a function");
+ break;
+ }
+ cp_parser_cilk_simd (parser, pragma_tok);
+ return true;
+
default:
gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
c_invoke_pragma_handler (id);
@@ -31108,6 +31256,257 @@ c_parse_file (void)
the_parser = NULL;
}
+/* Parses the Cilk Plus #pragma simd vectorlength clause:
+ Syntax:
+ vectorlength ( constant-expression ) */
+
+static tree
+cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses)
+{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ tree expr;
+ /* The vectorlength clause behaves exactly like OpenMP's safelen
+ clause. Thus, vectorlength is represented as OMP 4.0
+ safelen. */
+ check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength", loc);
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return error_mark_node;
+
+ expr = cp_parser_constant_expression (parser, false, NULL);
+ expr = maybe_constant_value (expr);
+
+ if (TREE_CONSTANT (expr)
+ && exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
+ error_at (loc, "vectorlength must be a power of 2");
+ else if (expr != error_mark_node)
+ {
+ tree c = build_omp_clause (loc, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (c) = expr;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ return error_mark_node;
+ return clauses;
+}
+
+/* Handles the Cilk Plus #pragma simd linear clause.
+ Syntax:
+ linear ( simd-linear-variable-list )
+
+ simd-linear-variable-list:
+ simd-linear-variable
+ simd-linear-variable-list , simd-linear-variable
+
+ simd-linear-variable:
+ id-expression
+ id-expression : simd-linear-step
+
+ simd-linear-step:
+ conditional-expression */
+
+static tree
+cp_parser_cilk_simd_linear (cp_parser *parser, tree clauses)
+{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return clauses;
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected identifier");
+ cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
+ return error_mark_node;
+ }
+
+ bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
+ while (1)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected variable-name");
+ clauses = error_mark_node;
+ break;
+ }
+
+ tree var_name = cp_parser_id_expression (parser, false, true, NULL,
+ false, false);
+ tree decl = cp_parser_lookup_name_simple (parser, var_name,
+ token->location);
+ if (decl == error_mark_node)
+ {
+ cp_parser_name_lookup_error (parser, var_name, decl, NLE_NULL,
+ token->location);
+ clauses = error_mark_node;
+ }
+ else
+ {
+ tree e = NULL_TREE;
+ tree step_size = integer_one_node;
+
+ /* If present, parse the linear step. Otherwise, assume the default
+ value of 1. */
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ e = cp_parser_assignment_expression (parser, false, NULL);
+ e = maybe_constant_value (e);
+
+ if (e == error_mark_node)
+ {
+ /* If an error has occurred, then the whole pragma is
+ considered ill-formed. Thus, no reason to keep
+ parsing. */
+ clauses = error_mark_node;
+ break;
+ }
+ else if (type_dependent_expression_p (e)
+ || value_dependent_expression_p (e)
+ || (TREE_TYPE (e)
+ && INTEGRAL_TYPE_P (TREE_TYPE (e))
+ && (TREE_CONSTANT (e)
+ || DECL_P (e))))
+ step_size = e;
+ else
+ cp_parser_error (parser,
+ "step size must be an integer constant "
+ "expression or an integer variable");
+ }
+
+ /* Use the OMP_CLAUSE_LINEAR, which has the same semantics. */
+ tree l = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_DECL (l) = decl;
+ OMP_CLAUSE_LINEAR_STEP (l) = step_size;
+ OMP_CLAUSE_CHAIN (l) = clauses;
+ clauses = l;
+ }
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ break;
+ else
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "expected %<,%> or %<)%> after %qE", decl);
+ clauses = error_mark_node;
+ break;
+ }
+ }
+ parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+ cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
+ return clauses;
+}
+
+/* Returns the name of the next clause. If the clause is not
+ recognized, then PRAGMA_CILK_CLAUSE_NONE is returned and the next
+ token is not consumed. Otherwise, the appropriate enum from the
+ pragma_simd_clause is returned and the token is consumed. */
+
+static pragma_cilk_clause
+cp_parser_cilk_simd_clause_name (cp_parser *parser)
+{
+ pragma_cilk_clause clause_type;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->keyword == RID_PRIVATE)
+ clause_type = PRAGMA_CILK_CLAUSE_PRIVATE;
+ else if (!token->u.value || token->type != CPP_NAME)
+ return PRAGMA_CILK_CLAUSE_NONE;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "vectorlength"))
+ clause_type = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "linear"))
+ clause_type = PRAGMA_CILK_CLAUSE_LINEAR;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "firstprivate"))
+ clause_type = PRAGMA_CILK_CLAUSE_FIRSTPRIVATE;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "lastprivate"))
+ clause_type = PRAGMA_CILK_CLAUSE_LASTPRIVATE;
+ else if (!strcmp (IDENTIFIER_POINTER (token->u.value), "reduction"))
+ clause_type = PRAGMA_CILK_CLAUSE_REDUCTION;
+ else
+ return PRAGMA_CILK_CLAUSE_NONE;
+
+ cp_lexer_consume_token (parser->lexer);
+ return clause_type;
+}
+
+/* Parses all the #pragma simd clauses. Returns a list of clauses found. */
+
+static tree
+cp_parser_cilk_simd_all_clauses (cp_parser *parser, cp_token *pragma_token)
+{
+ tree clauses = NULL_TREE;
+
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
+ && clauses != error_mark_node)
+ {
+ pragma_cilk_clause c_kind;
+ c_kind = cp_parser_cilk_simd_clause_name (parser);
+ if (c_kind == PRAGMA_CILK_CLAUSE_VECTORLENGTH)
+ clauses = cp_parser_cilk_simd_vectorlength (parser, clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_LINEAR)
+ clauses = cp_parser_cilk_simd_linear (parser, clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_PRIVATE)
+ /* Use the OpenMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE, clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_FIRSTPRIVATE)
+ /* Use the OpenMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
+ clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_LASTPRIVATE)
+ /* Use the OMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LASTPRIVATE,
+ clauses);
+ else if (c_kind == PRAGMA_CILK_CLAUSE_REDUCTION)
+ /* Use the OMP 4.0 equivalent function. */
+ clauses = cp_parser_omp_clause_reduction (parser, clauses);
+ else
+ {
+ clauses = error_mark_node;
+ cp_parser_error (parser, "expected %<#pragma simd%> clause");
+ break;
+ }
+ }
+
+ cp_parser_skip_to_pragma_eol (parser, pragma_token);
+
+ if (clauses == error_mark_node)
+ return error_mark_node;
+ else
+ return c_finish_cilk_clauses (clauses);
+}
+
+/* Main entry-point for parsing Cilk Plus <#pragma simd> for loops. */
+
+static void
+cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
+{
+ tree clauses = cp_parser_cilk_simd_all_clauses (parser, pragma_token);
+
+ if (clauses == error_mark_node)
+ return;
+
+ if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_FOR))
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "for statement expected");
+ return;
+ }
+
+ tree sb = begin_omp_structured_block ();
+ int save = cp_parser_begin_omp_structured_block (parser);
+ tree ret = cp_parser_omp_for_loop (parser, CILK_SIMD, clauses, NULL);
+ if (ret)
+ cpp_validate_cilk_plus_loop (OMP_FOR_BODY (ret));
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+ return;
+}
+
/* Create an identifier for a generic parameter type (a synthesized
template parameter implied by `auto' or a concept identifier). */
@@ -31116,7 +31515,7 @@ static tree
make_generic_type_name ()
{
char buf[32];
- sprintf (buf, "<auto%d>", ++generic_parm_count);
+ sprintf (buf, "auto:%d", ++generic_parm_count);
return get_identifier (buf);
}
@@ -31130,110 +31529,138 @@ tree_type_is_auto_or_concept (const_tree t)
return TREE_TYPE (t) && is_auto_or_concept (TREE_TYPE (t));
}
-/* Add EXPECT_COUNT implicit template parameters gleaned from the generic
- type parameters in PARAMETERS to the CURRENT_TEMPLATE_PARMS (creating a new
- template parameter list if necessary). Returns PARAMETERS suitably rewritten
- to reference the newly created types or ERROR_MARK_NODE on failure. */
+/* Add an implicit template type parameter to the CURRENT_TEMPLATE_PARMS
+ (creating a new template parameter list if necessary). Returns the newly
+ created template type parm. */
tree
-add_implicit_template_parms (cp_parser *parser, size_t expect_count,
- tree parameters)
+synthesize_implicit_template_parm (cp_parser *parser)
{
gcc_assert (current_binding_level->kind == sk_function_parms);
- cp_binding_level *fn_parms_scope = current_binding_level;
-
- bool become_template =
- fn_parms_scope->level_chain->kind != sk_template_parms;
-
- size_t synth_count = 0;
+ /* We are either continuing a function template that already contains implicit
+ template parameters, creating a new fully-implicit function template, or
+ extending an existing explicit function template with implicit template
+ parameters. */
- /* Roll back a scope level and either introduce a new template parameter list
- or update an existing one. The function scope is added back after template
- parameter synthesis below. */
- current_binding_level = fn_parms_scope->level_chain;
+ cp_binding_level *const entry_scope = current_binding_level;
- /* TPARMS tracks the function's template parameter list. This is either a new
- chain in the case of a fully implicit function template or an extension of
- the function's explicitly specified template parameter list. */
- tree tparms = NULL_TREE;
+ bool become_template = false;
+ cp_binding_level *parent_scope = 0;
- if (become_template)
+ if (parser->implicit_template_scope)
{
- push_deferring_access_checks (dk_deferred);
- begin_template_parm_list ();
+ gcc_assert (parser->implicit_template_parms);
- parser->fully_implicit_function_template_p = true;
- ++parser->num_template_parameter_lists;
+ current_binding_level = parser->implicit_template_scope;
}
else
{
- /* Roll back the innermost template parameter list such that it may be
- extended in the loop below as if it were being explicitly declared. */
-
- gcc_assert (current_template_parms);
+ /* Roll back to the existing template parameter scope (in the case of
+ extending an explicit function template) or introduce a new template
+ parameter scope ahead of the function parameter scope (or class scope
+ in the case of out-of-line member definitions). The function scope is
+ added back after template parameter synthesis below. */
- /* Pop the innermost template parms into TPARMS. */
- tree inner_vec = INNERMOST_TEMPLATE_PARMS (current_template_parms);
- current_template_parms = TREE_CHAIN (current_template_parms);
+ cp_binding_level *scope = entry_scope;
- size_t inner_vec_len = TREE_VEC_LENGTH (inner_vec);
- if (inner_vec_len != 0)
+ while (scope->kind == sk_function_parms)
{
- tree t = tparms = TREE_VEC_ELT (inner_vec, 0);
- for (size_t n = 1; n < inner_vec_len; ++n)
- t = TREE_CHAIN (t) = TREE_VEC_ELT (inner_vec, n);
+ parent_scope = scope;
+ scope = scope->level_chain;
}
+ if (current_class_type && !LAMBDA_TYPE_P (current_class_type)
+ && parser->num_classes_being_defined == 0)
+ while (scope->kind == sk_class)
+ {
+ parent_scope = scope;
+ scope = scope->level_chain;
+ }
- ++processing_template_parmlist;
- }
+ current_binding_level = scope;
- for (tree p = parameters; p && synth_count < expect_count; p = TREE_CHAIN (p))
- {
- tree generic_type_ptr
- = find_type_usage (TREE_VALUE (p), tree_type_is_auto_or_concept);
+ if (scope->kind != sk_template_parms)
+ {
+ /* Introduce a new template parameter list for implicit template
+ parameters. */
- if (!generic_type_ptr)
- continue;
+ become_template = true;
+
+ parser->implicit_template_scope
+ = begin_scope (sk_template_parms, NULL);
- ++synth_count;
+ ++processing_template_decl;
- tree synth_id = make_generic_type_name ();
- tree synth_tmpl_parm = finish_template_type_parm (class_type_node,
- synth_id);
- tparms = process_template_parm (tparms, DECL_SOURCE_LOCATION (TREE_VALUE
- (p)),
- build_tree_list (NULL_TREE,
- synth_tmpl_parm),
- /*non_type=*/false,
- /*param_pack=*/false);
+ parser->fully_implicit_function_template_p = true;
+ ++parser->num_template_parameter_lists;
+ }
+ else
+ {
+ /* Synthesize implicit template parameters at the end of the explicit
+ template parameter list. */
- /* Rewrite the type of P to be the template_parm added above (getdecls is
- used to retrieve it since it is the most recent declaration in this
- scope). Qualifiers need to be preserved also. */
+ gcc_assert (current_template_parms);
- tree& cur_type = TREE_TYPE (generic_type_ptr);
- tree new_type = TREE_TYPE (getdecls ());
+ parser->implicit_template_scope = scope;
- if (TYPE_QUALS (cur_type))
- cur_type = cp_build_qualified_type (new_type, TYPE_QUALS (cur_type));
- else
- cur_type = new_type;
+ tree v = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+ parser->implicit_template_parms
+ = TREE_VEC_ELT (v, TREE_VEC_LENGTH (v) - 1);
+ }
}
- gcc_assert (synth_count == expect_count);
+ /* Synthesize a new template parameter and track the current template
+ parameter chain with implicit_template_parms. */
- push_binding_level (fn_parms_scope);
+ tree synth_id = make_generic_type_name ();
+ tree synth_tmpl_parm = finish_template_type_parm (class_type_node,
+ synth_id);
+ tree new_parm
+ = process_template_parm (parser->implicit_template_parms,
+ input_location,
+ build_tree_list (NULL_TREE, synth_tmpl_parm),
+ /*non_type=*/false,
+ /*param_pack=*/false);
- end_template_parm_list (tparms);
- return parameters;
+ if (parser->implicit_template_parms)
+ parser->implicit_template_parms
+ = TREE_CHAIN (parser->implicit_template_parms);
+ else
+ parser->implicit_template_parms = new_parm;
+
+ tree new_type = TREE_TYPE (getdecls ());
+
+ /* If creating a fully implicit function template, start the new implicit
+ template parameter list with this synthesized type, otherwise grow the
+ current template parameter list. */
+
+ if (become_template)
+ {
+ parent_scope->level_chain = current_binding_level;
+
+ tree new_parms = make_tree_vec (1);
+ TREE_VEC_ELT (new_parms, 0) = parser->implicit_template_parms;
+ current_template_parms = tree_cons (size_int (processing_template_decl),
+ new_parms, current_template_parms);
+ }
+ else
+ {
+ tree& new_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+ int new_parm_idx = TREE_VEC_LENGTH (new_parms);
+ new_parms = grow_tree_vec_stat (new_parms, new_parm_idx + 1);
+ TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms;
+ }
+
+ current_binding_level = entry_scope;
+
+ return new_type;
}
/* Finish the declaration of a fully implicit function template. Such a
template has no explicit template parameter list so has not been through the
- normal template head and tail processing. add_implicit_template_parms tries
- to do the head; this tries to do the tail. MEMBER_DECL_OPT should be
+ normal template head and tail processing. synthesize_implicit_template_parm
+ tries to do the head; this tries to do the tail. MEMBER_DECL_OPT should be
provided if the declaration is a class member such that its template
declaration can be completed. If MEMBER_DECL_OPT is provided the finished
form is returned. Otherwise NULL_TREE is returned. */
@@ -31251,7 +31678,6 @@ finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
DECL_VIRTUAL_P (member_decl_opt) = false;
}
- pop_deferring_access_checks ();
if (member_decl_opt)
member_decl_opt = finish_member_template_decl (member_decl_opt);
end_template_decl ();
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index 75f327b1d8b..edd4e6e8b98 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -300,6 +300,7 @@ typedef struct GTY(()) cp_parser {
#define IN_OMP_BLOCK 4
#define IN_OMP_FOR 8
#define IN_IF_STMT 16
+#define IN_CILK_SIMD_FOR 32
unsigned char in_statement;
/* TRUE if we are presently parsing the body of a switch statement.
@@ -360,11 +361,30 @@ typedef struct GTY(()) cp_parser {
data structure with everything needed for parsing the clauses. */
cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd;
+ /* Nonzero if parsing a parameter list where 'auto' should trigger an implicit
+ template parameter. */
+ bool auto_is_implicit_function_template_parm_p;
+
/* TRUE if the function being declared was made a template due to its
parameter list containing generic type specifiers (`auto' or concept
identifiers) rather than an explicit template parameter list. */
bool fully_implicit_function_template_p;
+ /* Tracks the function's template parameter list when declaring a function
+ using generic type parameters. This is either a new chain in the case of a
+ fully implicit function template or an extension of the function's existing
+ template parameter list. This is tracked to optimize calls subsequent
+ calls to synthesize_implicit_template_parm during
+ cp_parser_parameter_declaration. */
+ tree implicit_template_parms;
+
+ /* The scope into which an implicit template parameter list has been
+ introduced or an existing template parameter list is being extended with
+ implicit template paramaters. In most cases this is the sk_function_parms
+ scope containing the use of a generic type. In the case of an out-of-line
+ member definition using a generic type, it is the sk_class scope. */
+ cp_binding_level* implicit_template_scope;
+
} cp_parser;
/* In parser.c */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8c1553feca2..3bc8ccb0ee3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -42,6 +42,8 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "tree-iterator.h"
#include "type-utils.h"
+#include "gimple.h"
+#include "gimplify.h"
/* The type of functions taking a tree, and some additional data, and
returning an int. */
@@ -150,7 +152,7 @@ static int for_each_template_parm (tree, tree_fn_t, void*,
struct pointer_set_t*, bool);
static tree expand_template_argument_pack (tree);
static tree build_template_parm_index (int, int, int, tree, tree);
-static bool inline_needs_template_parms (tree);
+static bool inline_needs_template_parms (tree, bool);
static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree);
static void register_local_specialization (tree, tree);
@@ -376,9 +378,9 @@ template_class_depth (tree type)
Returns true if processing DECL needs us to push template parms. */
static bool
-inline_needs_template_parms (tree decl)
+inline_needs_template_parms (tree decl, bool nsdmi)
{
- if (! DECL_TEMPLATE_INFO (decl))
+ if (!decl || (!nsdmi && ! DECL_TEMPLATE_INFO (decl)))
return false;
return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl)))
@@ -447,16 +449,23 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
}
}
-/* Restore the template parameter context for a member template or
- a friend template defined in a class definition. */
+/* Restore the template parameter context for a member template, a
+ friend template defined in a class definition, or a non-template
+ member of template class. */
void
maybe_begin_member_template_processing (tree decl)
{
tree parms;
int levels = 0;
+ bool nsdmi = TREE_CODE (decl) == FIELD_DECL;
- if (inline_needs_template_parms (decl))
+ if (nsdmi)
+ decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+ ? CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (decl))
+ : NULL_TREE);
+
+ if (inline_needs_template_parms (decl, nsdmi))
{
parms = DECL_TEMPLATE_PARMS (most_general_template (decl));
levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl;
@@ -7458,30 +7467,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
context = global_namespace;
/* Create the type. */
- if (TREE_CODE (template_type) == ENUMERAL_TYPE)
- {
- if (!is_dependent_type)
- {
- set_current_access_from_decl (TYPE_NAME (template_type));
- t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE,
- tsubst (ENUM_UNDERLYING_TYPE (template_type),
- arglist, complain, in_decl),
- SCOPED_ENUM_P (template_type), NULL);
- }
- else
- {
- /* We don't want to call start_enum for this type, since
- the values for the enumeration constants may involve
- template parameters. And, no one should be interested
- in the enumeration constants for such a type. */
- t = cxx_make_type (ENUMERAL_TYPE);
- SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
- }
- SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type));
- ENUM_FIXED_UNDERLYING_TYPE_P (t)
- = ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
- }
- else if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
+ if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
{
/* The user referred to a specialization of an alias
template represented by GEN_TMPL.
@@ -7505,6 +7491,29 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
if (t == error_mark_node)
return t;
}
+ else if (TREE_CODE (template_type) == ENUMERAL_TYPE)
+ {
+ if (!is_dependent_type)
+ {
+ set_current_access_from_decl (TYPE_NAME (template_type));
+ t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE,
+ tsubst (ENUM_UNDERLYING_TYPE (template_type),
+ arglist, complain, in_decl),
+ SCOPED_ENUM_P (template_type), NULL);
+ }
+ else
+ {
+ /* We don't want to call start_enum for this type, since
+ the values for the enumeration constants may involve
+ template parameters. And, no one should be interested
+ in the enumeration constants for such a type. */
+ t = cxx_make_type (ENUMERAL_TYPE);
+ SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
+ }
+ SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type));
+ ENUM_FIXED_UNDERLYING_TYPE_P (t)
+ = ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
+ }
else if (CLASS_TYPE_P (template_type))
{
t = make_class_type (TREE_CODE (template_type));
@@ -7661,7 +7670,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
= tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (templ));
- if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type)
+ if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
+ && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
/* Now that the type has been registered on the instantiations
list, we set up the enumerators. Because the enumeration
constants may involve the enumeration type itself, we make
@@ -13556,6 +13566,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_FOR:
case OMP_SIMD:
+ case CILK_SIMD:
case OMP_DISTRIBUTE:
{
tree clauses, body, pre_body;
@@ -21629,6 +21640,58 @@ append_type_to_template_for_access_check (tree templ,
scope, location);
}
+/* Convert the generic type parameters in PARM that match the types given in the
+ range [START_IDX, END_IDX) from the current_template_parms into generic type
+ packs. */
+
+tree
+convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
+{
+ tree current = current_template_parms;
+ int depth = TMPL_PARMS_DEPTH (current);
+ current = INNERMOST_TEMPLATE_PARMS (current);
+ tree replacement = make_tree_vec (TREE_VEC_LENGTH (current));
+
+ for (int i = 0; i < start_idx; ++i)
+ TREE_VEC_ELT (replacement, i)
+ = TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i)));
+
+ for (int i = start_idx; i < end_idx; ++i)
+ {
+ /* Create a distinct parameter pack type from the current parm and add it
+ to the replacement args to tsubst below into the generic function
+ parameter. */
+
+ tree o = TREE_TYPE (TREE_VALUE
+ (TREE_VEC_ELT (current, i)));
+ tree t = copy_type (o);
+ TEMPLATE_TYPE_PARM_INDEX (t)
+ = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (o),
+ o, 0, 0, tf_none);
+ TREE_TYPE (TEMPLATE_TYPE_DECL (t)) = t;
+ TYPE_STUB_DECL (t) = TYPE_NAME (t) = TEMPLATE_TYPE_DECL (t);
+ TYPE_MAIN_VARIANT (t) = t;
+ TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
+ TYPE_CANONICAL (t) = canonical_type_parameter (t);
+ TREE_VEC_ELT (replacement, i) = t;
+ TREE_VALUE (TREE_VEC_ELT (current, i)) = TREE_CHAIN (t);
+ }
+
+ for (int i = end_idx, e = TREE_VEC_LENGTH (current); i < e; ++i)
+ TREE_VEC_ELT (replacement, i)
+ = TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i)));
+
+ /* If there are more levels then build up the replacement with the outer
+ template parms. */
+ if (depth > 1)
+ replacement = add_to_template_args (template_parms_to_args
+ (TREE_CHAIN (current_template_parms)),
+ replacement);
+
+ return tsubst (parm, replacement, tf_none, NULL_TREE);
+}
+
+
/* Set up the hash tables for template instantiations. */
void
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2ebc00d243a..f212514a757 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "vec.h"
#include "target.h"
#include "gimple.h"
+#include "gimplify.h"
#include "bitmap.h"
#include "hash-table.h"
#include "omp-low.h"
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 14b69921a51..9a102b98214 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -30,7 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "convert.h"
#include "cgraph.h"
#include "splay-tree.h"
-#include "gimple.h" /* gimple_has_body_p */
+#include "gimple.h"
+#include "gimplify.h"
#include "hash-table.h"
#include "wide-int.h"
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index bcb87825a1e..bff7f17780f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -7779,7 +7779,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
/* Handle null pointer to member function conversions. */
if (null_ptr_cst_p (pfn))
{
- pfn = build_c_cast (input_location, type, pfn);
+ pfn = cp_build_c_cast (type, pfn, complain);
return build_ptrmemfunc1 (to_type,
integer_zero_node,
pfn);
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index cb5f715f650..484805da5dd 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -126,7 +126,7 @@ cxx_readonly_error (tree arg, enum lvalue_use errstring)
"read-only reference %qD"),
TREE_OPERAND (arg, 0));
else
- readonly_error (arg, errstring);
+ readonly_error (input_location, arg, errstring);
}
diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c
index 38ea8beeb89..2b343f1993e 100644
--- a/gcc/cp/vtable-class-hierarchy.c
+++ b/gcc/cp/vtable-class-hierarchy.c
@@ -119,6 +119,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "vtable-verify.h"
#include "gimple.h"
+#include "gimplify.h"
static int num_calls_to_regset = 0;
static int num_calls_to_regpair = 0;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 2132b1e5602..599dee3c3bf 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -153,7 +153,7 @@ the value of an enumeration constant, the width of a bit-field, or
the initial value of a static variable.
If you don't know the type of the operand, you can still do this, but you
-must use @code{typeof} (@pxref{Typeof}).
+must use @code{typeof} or @code{__auto_type} (@pxref{Typeof}).
In G++, the result value of a statement expression undergoes array and
function pointer decay, and is returned by value to the enclosing
@@ -755,6 +755,35 @@ Thus, @code{array (pointer (char), 4)} is the type of arrays of 4
pointers to @code{char}.
@end itemize
+In GNU C, but not GNU C++, you may also declare the type of a variable
+as @code{__auto_type}. In that case, the declaration must declare
+only one variable, whose declarator must just be an identifier, the
+declaration must be initialized, and the type of the variable is
+determined by the initializer; the name of the variable is not in
+scope until after the initializer. (In C++, you should use C++11
+@code{auto} for this purpose.) Using @code{__auto_type}, the
+``maximum'' macro above could be written as:
+
+@smallexample
+#define max(a,b) \
+ (@{ __auto_type _a = (a); \
+ __auto_type _b = (b); \
+ _a > _b ? _a : _b; @})
+@end smallexample
+
+Using @code{__auto_type} instead of @code{typeof} has two advantages:
+
+@itemize @bullet
+@item Each argument to the macro appears only once in the expansion of
+the macro. This prevents the size of the macro expansion growing
+exponentially when calls to such macros are nested inside arguments of
+such macros.
+
+@item If the argument to the macro has variably modified type, it is
+evaluated only once when using @code{__auto_type}, but twice if
+@code{typeof} is used.
+@end itemize
+
@emph{Compatibility Note:} In addition to @code{typeof}, GCC 2 supported
a more limited extension that permitted one to write
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
index 238a9cead89..ea5e81ad87f 100644
--- a/gcc/doc/generic.texi
+++ b/gcc/doc/generic.texi
@@ -1602,29 +1602,31 @@ of temporaries during the evaluation of that expression should be
performed immediately after the expression is evaluated.
@item CONSTRUCTOR
-These nodes represent the brace-enclosed initializers for a structure or
-array. The first operand is reserved for use by the back end. The
-second operand is a @code{TREE_LIST}. If the @code{TREE_TYPE} of the
-@code{CONSTRUCTOR} is a @code{RECORD_TYPE} or @code{UNION_TYPE}, then
-the @code{TREE_PURPOSE} of each node in the @code{TREE_LIST} will be a
-@code{FIELD_DECL} and the @code{TREE_VALUE} of each node will be the
-expression used to initialize that field.
-
-If the @code{TREE_TYPE} of the @code{CONSTRUCTOR} is an
-@code{ARRAY_TYPE}, then the @code{TREE_PURPOSE} of each element in the
-@code{TREE_LIST} will be an @code{INTEGER_CST} or a @code{RANGE_EXPR} of
-two @code{INTEGER_CST}s. A single @code{INTEGER_CST} indicates which
-element of the array (indexed from zero) is being assigned to. A
-@code{RANGE_EXPR} indicates an inclusive range of elements to
-initialize. In both cases the @code{TREE_VALUE} is the corresponding
+These nodes represent the brace-enclosed initializers for a structure or an
+array. They contain a sequence of component values made out of a vector of
+constructor_elt, which is a (@code{INDEX}, @code{VALUE}) pair.
+
+If the @code{TREE_TYPE} of the @code{CONSTRUCTOR} is a @code{RECORD_TYPE},
+@code{UNION_TYPE} or @code{QUAL_UNION_TYPE} then the @code{INDEX} of each
+node in the sequence will be a @code{FIELD_DECL} and the @code{VALUE} will
+be the expression used to initialize that field.
+
+If the @code{TREE_TYPE} of the @code{CONSTRUCTOR} is an @code{ARRAY_TYPE},
+then the @code{INDEX} of each node in the sequence will be an
+@code{INTEGER_CST} or a @code{RANGE_EXPR} of two @code{INTEGER_CST}s.
+A single @code{INTEGER_CST} indicates which element of the array is being
+assigned to. A @code{RANGE_EXPR} indicates an inclusive range of elements
+to initialize. In both cases the @code{VALUE} is the corresponding
initializer. It is re-evaluated for each element of a
-@code{RANGE_EXPR}. If the @code{TREE_PURPOSE} is @code{NULL_TREE}, then
+@code{RANGE_EXPR}. If the @code{INDEX} is @code{NULL_TREE}, then
the initializer is for the next available array element.
In the front end, you should not depend on the fields appearing in any
particular order. However, in the middle end, fields must appear in
declaration order. You should not assume that all fields will be
-represented. Unrepresented fields will be set to zero.
+represented. Unrepresented fields will be cleared (zeroed), unless the
+CONSTRUCTOR_NO_CLEARING flag is set, in which case their value becomes
+undefined.
@item COMPOUND_LITERAL_EXPR
@findex COMPOUND_LITERAL_EXPR_DECL_EXPR
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index fa5d6e5a611..a8f9f8a7980 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1751,7 +1751,7 @@ linker for all final links. @var{choice} can be one of
@itemx --disable-gnu-unique-object
Tells GCC to use the gnu_unique_object relocation for C++ template
static data members and inline function local statics. Enabled by
-default for a native toolchain with an assembler that accepts it and
+default for a toolchain with an assembler that accepts it and
GLIBC 2.11 or above, otherwise disabled.
@item --enable-lto
@@ -1773,6 +1773,18 @@ produce shorter header file paths in diagnostics and dependency output
files, but these changed header paths may conflict with some compilation
environments. Enabled by default, and may be disabled using
@option{--disable-canonical-system-headers}.
+
+@item --with-glibc-version=@var{major}.@var{minor}
+Tell GCC that when the GNU C Library (glibc) is used on the target it
+will be version @var{major}.@var{minor} or later. Normally this can
+be detected from the C library's header files, but this option may be
+needed when bootstrapping a cross toolchain without the header files
+available for building the initial bootstrap compiler.
+
+If GCC is configured with some multilibs that use glibc and some that
+do not, this option applies only to the multilibs that use glibc.
+However, such configurations may not work well as not all the relevant
+configuration in GCC is on a per-multilib basis.
@end table
@subheading Cross-Compiler-Specific Options
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 25e3eb59e6f..ff4c2eeba9f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11169,9 +11169,9 @@ instead of the @option{-mcpu=} option.
Specify the name of the target processor, optionally suffixed by one or more
feature modifiers. This option has the form
@option{-mcpu=@var{cpu}@r{@{}+@r{[}no@r{]}@var{feature}@r{@}*}}, where the
-possible values for @var{cpu} are @samp{generic}, @samp{large}. The
-possible values for @var{feature} are documented in the sub-section
-below.
+possible values for @var{cpu} are @samp{generic}, @samp{cortex-a53},
+@samp{cortex-a57}. The possible values for @var{feature} are documented
+in the sub-section below.
Where conflicting feature modifiers are specified, the right-most feature is
used.
@@ -11184,8 +11184,12 @@ generating assembly code.
Specify the name of the processor to tune the performance for. The code will
be tuned as if the target processor were of the type specified in this option,
but still using instructions compatible with the target processor specified
-by a @option{-mcpu=} option. This option cannot be suffixed by feature
-modifiers.
+by a @option{-mcpu=} option. Where no @option{-mtune=} option is
+specified, the code will be tuned to perform well on the target processor
+given by @option{-mcpu=} or @option{-march=}. Where none of
+@option{-mtune=}, @option{-mcpu=} or @option{-march=} are specified,
+the code will be tuned to perform well across a range of target
+processors. This option cannot be suffixed by feature modifiers.
@end table
@@ -18842,7 +18846,8 @@ SVR4 ABI)@.
@opindex mabi
Extend the current ABI with a particular extension, or remove such extension.
Valid values are @var{altivec}, @var{no-altivec}, @var{spe},
-@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble}@.
+@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble},
+@var{elfv1}, @var{elfv2}@.
@item -mabi=spe
@opindex mabi=spe
@@ -18864,6 +18869,20 @@ This is a PowerPC 32-bit SYSV ABI option.
Change the current ABI to use IEEE extended-precision long double.
This is a PowerPC 32-bit Linux ABI option.
+@item -mabi=elfv1
+@opindex mabi=elfv1
+Change the current ABI to use the ELFv1 ABI.
+This is the default ABI for big-endian PowerPC 64-bit Linux.
+Overriding the default ABI requires special system support and is
+likely to fail in spectacular ways.
+
+@item -mabi=elfv2
+@opindex mabi=elfv2
+Change the current ABI to use the ELFv2 ABI.
+This is the default ABI for little-endian PowerPC 64-bit Linux.
+Overriding the default ABI requires special system support and is
+likely to fail in spectacular ways.
+
@item -mprototype
@itemx -mno-prototype
@opindex mprototype
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index ab8852f4c43..5de2916f728 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -87,7 +87,6 @@ along with GCC; see the file COPYING3. If not see
#include "hash-table.h"
#include "cgraph.h"
#include "input.h"
-#include "gimple.h"
#include "ira.h"
#include "lra.h"
#include "dumpfile.h"
@@ -16493,11 +16492,13 @@ add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
}
}
+/* Add a DW_AT_byte_size attribute to DIE with TREE_NODE's size. */
+
static void
add_byte_size_attribute (dw_die_ref die, tree tree_node)
{
dw_die_ref decl_die;
- unsigned size;
+ HOST_WIDE_INT size;
switch (TREE_CODE (tree_node))
{
@@ -16521,7 +16522,7 @@ add_byte_size_attribute (dw_die_ref die, tree tree_node)
generally given as the number of bytes normally allocated for an
object of the *declared* type of the member itself. This is true
even for bit-fields. */
- size = simple_type_size_in_bits (field_type (tree_node)) / BITS_PER_UNIT;
+ size = int_size_in_bytes (field_type (tree_node));
break;
default:
gcc_unreachable ();
@@ -16530,8 +16531,9 @@ add_byte_size_attribute (dw_die_ref die, tree tree_node)
/* Note that `size' might be -1 when we get to this point. If it is, that
indicates that the byte size of the entity in question is variable. We
have no good way of expressing this fact in Dwarf at the present time,
- so just let the -1 pass on through. */
- add_AT_unsigned (die, DW_AT_byte_size, size);
+ when location description was not used by the caller code instead. */
+ if (size >= 0)
+ add_AT_unsigned (die, DW_AT_byte_size, size);
}
/* For a FIELD_DECL node which represents a bit-field, output an attribute
@@ -17493,9 +17495,8 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
if (TREE_CODE (value) == CONST_DECL)
value = DECL_INITIAL (value);
- if (tree_fits_hwi_p (value)
- && (simple_type_size_in_bits (TREE_TYPE (value))
- <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value)))
+ if (simple_type_size_in_bits (TREE_TYPE (value))
+ <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value)))
/* DWARF2 does not provide a way of indicating whether or
not enumeration constants are signed or unsigned. GDB
always assumes the values are signed, so we output all
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 089a0b5c0e1..f66b087a6a9 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -5345,6 +5345,13 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
rtx subtarget;
rtx tem, last, trueval;
+ /* If we compare constants, we shouldn't use a store-flag operation,
+ but a constant load. We can get there via the vanilla route that
+ usually generates a compare-branch sequence, but will in this case
+ fold the comparison to a constant, and thus elide the branch. */
+ if (CONSTANT_P (op0) && CONSTANT_P (op1))
+ return NULL_RTX;
+
tem = emit_store_flag_1 (target, code, op0, op1, mode, unsignedp, normalizep,
target_mode);
if (tem)
diff --git a/gcc/expr.h b/gcc/expr.h
index ca93058e5e1..23acd86d181 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -521,8 +521,8 @@ extern rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx,
rtx, int);
#endif
-extern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
- struct args_size *,
+extern void locate_and_pad_parm (enum machine_mode, tree, int, int, int,
+ tree, struct args_size *,
struct locate_and_pad_arg_data *);
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
diff --git a/gcc/final.c b/gcc/final.c
index f7425429b81..74898a31ade 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -831,7 +831,7 @@ void
update_alignments (vec<rtx> &label_pairs)
{
unsigned int i = 0;
- rtx iter, label;
+ rtx iter, label = NULL_RTX;
if (max_labelno != max_label_num ())
grow_label_align ();
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 8e113b85aba..1b979303825 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "md5.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-dfa.h"
/* Nonzero if we are folding constants inside an initializer; zero
@@ -11943,16 +11944,15 @@ fold_binary_loc (location_t loc,
if the new mask might be further optimized. */
if ((TREE_CODE (arg0) == LSHIFT_EXPR
|| TREE_CODE (arg0) == RSHIFT_EXPR)
- && tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
- && tree_fits_hwi_p (arg1)
- && tree_to_uhwi (TREE_OPERAND (arg0, 1))
- < TYPE_PRECISION (TREE_TYPE (arg0))
&& TYPE_PRECISION (TREE_TYPE (arg0)) <= HOST_BITS_PER_WIDE_INT
- && tree_to_uhwi (TREE_OPERAND (arg0, 1)) > 0)
+ && TREE_CODE (arg1) == INTEGER_CST
+ && tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
+ && tree_to_uhwi (TREE_OPERAND (arg0, 1)) > 0
+ && (tree_to_uhwi (TREE_OPERAND (arg0, 1))
+ < TYPE_PRECISION (TREE_TYPE (arg0))))
{
unsigned int shiftc = tree_to_uhwi (TREE_OPERAND (arg0, 1));
- unsigned HOST_WIDE_INT mask
- = tree_to_hwi (arg1, TYPE_SIGN (TREE_TYPE (arg1)));
+ unsigned HOST_WIDE_INT mask = tree_to_hwi (arg1);
unsigned HOST_WIDE_INT newmask, zerobits = 0;
tree shift_type = TREE_TYPE (arg0);
@@ -13668,8 +13668,7 @@ fold_binary_loc (location_t loc,
and X >= signed_max+1 because previous transformations. */
if (code == LE_EXPR || code == GT_EXPR)
{
- tree st;
- st = signed_type_for (TREE_TYPE (arg1));
+ tree st = signed_type_for (arg1_type);
return fold_build2_loc (loc,
code == LE_EXPR ? GE_EXPR : LT_EXPR,
type, fold_convert_loc (loc, st, arg0),
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 8e2e10c8539..e6c6244e745 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,17 @@
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * trans-expr.c: Include only gimplify.h and gimple.h as needed.
+ * trans-openmp.c: Likewise.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * f95-lang.c: Don't include gimple.h.
+ * trans-array.c: Include gimple-expr.h instead of gimple.h.
+ * trans.c: Likewise.
+ * trans-decl.c: Likewise.
+ * trans-expr.c: Include gimplify.h.
+ * trans-openmp.c: Likewise.
+
2013-11-07 Janus Weil <janus@gcc.gnu.org>
PR fortran/58471
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index a70d60d6882..4da5e6913d2 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h"
#include "flags.h"
#include "langhooks.h"
#include "langhooks-def.h"
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 4f778b913a0..5aef944c880 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -79,7 +79,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h" /* For create_tmp_var_name. */
+#include "gimple-expr.h"
#include "diagnostic-core.h" /* For internal_error/fatal_error. */
#include "flags.h"
#include "gfortran.h"
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index eea05814504..7ee947c1204 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "tree-dump.h"
-#include "gimple.h" /* For create_tmp_var_raw. */
+#include "gimple-expr.h" /* For create_tmp_var_raw. */
#include "ggc.h"
#include "diagnostic-core.h" /* For internal_error. */
#include "toplev.h" /* For announce_function. */
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 59434bdb1b2..a1afbf26a0b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see
/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
#include "trans-stmt.h"
#include "dependency.h"
+#include "gimple.h"
+#include "gimplify.h"
#include "wide-int.h"
/* Convert a scalar to an array descriptor. To be used for assumed-rank
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index bf282498eab..13c87058ddd 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -23,7 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h" /* For create_tmp_var_raw. */
+#include "gimple.h"
+#include "gimplify.h" /* For create_tmp_var_raw. */
#include "diagnostic-core.h" /* For internal_error. */
#include "gfortran.h"
#include "trans.h"
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index b7863b2d511..ef20a20f018 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h" /* For create_tmp_var_raw. */
+#include "gimple-expr.h" /* For create_tmp_var_raw. */
#include "tree-iterator.h"
#include "diagnostic-core.h" /* For internal_error. */
#include "flags.h"
diff --git a/gcc/function.c b/gcc/function.c
index ab3e495aace..7fdf67639a4 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "common/common-target.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-pass.h"
#include "predict.h"
#include "df.h"
@@ -71,14 +72,6 @@ along with GCC; see the file COPYING3. If not see
#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
-/* Some systems use __main in a way incompatible with its use in gcc, in these
- cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
- give the same symbol without quotes for an alternative entry point. You
- must define both, or neither. */
-#ifndef NAME__MAIN
-#define NAME__MAIN "__main"
-#endif
-
/* Round a value to the lowest integer less than it that is a multiple of
the required alignment. Avoid using division in case the value is
negative. Assume the alignment is a power of two. */
@@ -2523,6 +2516,7 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
}
locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs,
+ all->reg_parm_stack_space,
entry_parm ? data->partial : 0, current_function_decl,
&all->stack_args_size, &data->locate);
@@ -3511,11 +3505,7 @@ assign_parms (tree fndecl)
/* Adjust function incoming argument size for alignment and
minimum length. */
-#ifdef REG_PARM_STACK_SPACE
- crtl->args.size = MAX (crtl->args.size,
- REG_PARM_STACK_SPACE (fndecl));
-#endif
-
+ crtl->args.size = MAX (crtl->args.size, all.reg_parm_stack_space);
crtl->args.size = CEIL_ROUND (crtl->args.size,
PARM_BOUNDARY / BITS_PER_UNIT);
@@ -3719,6 +3709,9 @@ gimplify_parameters (void)
IN_REGS is nonzero if the argument will be passed in registers. It will
never be set if REG_PARM_STACK_SPACE is not defined.
+ REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
+ for arguments which are passed in registers.
+
FNDECL is the function in which the argument was defined.
There are two types of rounding that are done. The first, controlled by
@@ -3739,19 +3732,16 @@ gimplify_parameters (void)
void
locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
- int partial, tree fndecl ATTRIBUTE_UNUSED,
+ int reg_parm_stack_space, int partial,
+ tree fndecl ATTRIBUTE_UNUSED,
struct args_size *initial_offset_ptr,
struct locate_and_pad_arg_data *locate)
{
tree sizetree;
enum direction where_pad;
unsigned int boundary, round_boundary;
- int reg_parm_stack_space = 0;
int part_size_in_regs;
-#ifdef REG_PARM_STACK_SPACE
- reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-
/* If we have found a stack parm before we reach the end of the
area reserved for registers, skip that area. */
if (! in_regs)
@@ -3769,7 +3759,6 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
initial_offset_ptr->constant = reg_parm_stack_space;
}
}
-#endif /* REG_PARM_STACK_SPACE */
part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0);
@@ -3832,11 +3821,7 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
locate->slot_offset.constant += part_size_in_regs;
- if (!in_regs
-#ifdef REG_PARM_STACK_SPACE
- || REG_PARM_STACK_SPACE (fndecl) > 0
-#endif
- )
+ if (!in_regs || reg_parm_stack_space > 0)
pad_to_arg_alignment (&locate->slot_offset, boundary,
&locate->alignment_pad);
@@ -3856,11 +3841,7 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
pad_below (&locate->offset, passed_mode, sizetree);
#else /* !ARGS_GROW_DOWNWARD */
- if (!in_regs
-#ifdef REG_PARM_STACK_SPACE
- || REG_PARM_STACK_SPACE (fndecl) > 0
-#endif
- )
+ if (!in_regs || reg_parm_stack_space > 0)
pad_to_arg_alignment (initial_offset_ptr, boundary,
&locate->alignment_pad);
locate->slot_offset = *initial_offset_ptr;
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index ea8d9a7b769..fb3857d1808 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -342,9 +342,10 @@ typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
counter. */
#define GCOV_COUNTER_IOR 7 /* IOR of the all values passed to
counter. */
-#define GCOV_LAST_VALUE_COUNTER 7 /* The last of counters used for value
+#define GCOV_TIME_PROFILER 8 /* Time profile collecting first run of a function */
+#define GCOV_LAST_VALUE_COUNTER 8 /* The last of counters used for value
profiling. */
-#define GCOV_COUNTERS 8
+#define GCOV_COUNTERS 9
/* Number of counters used for value profiling. */
#define GCOV_N_VALUE_COUNTERS \
@@ -352,7 +353,7 @@ typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
/* A list of human readable names of the counters */
#define GCOV_COUNTER_NAMES {"arcs", "interval", "pow2", "single", \
- "delta", "indirect_call", "average", "ior"}
+ "delta", "indirect_call", "average", "ior", "time_profiler"}
/* Names of merge functions for counters. */
#define GCOV_MERGE_FUNCTIONS {"__gcov_merge_add", \
@@ -362,7 +363,8 @@ typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
"__gcov_merge_delta", \
"__gcov_merge_single", \
"__gcov_merge_add", \
- "__gcov_merge_ior"}
+ "__gcov_merge_ior", \
+ "__gcov_merge_time_profile" }
/* Convert a counter index to a tag. */
#define GCOV_TAG_FOR_COUNTER(COUNT) \
@@ -511,13 +513,18 @@ extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The merge function that just ors the counters together. */
extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+extern void __gcov_merge_time_profile (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+
/* The profiler functions. */
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
+extern void __gcov_indirect_call_profiler (gcov_type*, gcov_type,
+ void*, void*);
extern void __gcov_indirect_call_profiler_v2 (gcov_type, void *);
extern void __gcov_average_profiler (gcov_type *, gcov_type);
extern void __gcov_ior_profiler (gcov_type *, gcov_type);
+extern void __gcov_time_profiler (gcov_type *);
#ifndef inhibit_libc
/* The wrappers around some library functions.. */
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index c82536df206..ab2f336851d 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1768,9 +1768,9 @@ open_base_files (void)
"tree.h", "rtl.h", "wide-int.h", "function.h", "insn-config.h", "expr.h",
"hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
- "gimple.h", "gimple-ssa.h", "tree-cfg.h", "tree-phinodes.h",
- "ssa-iterators.h", "tree-ssanames.h", "tree-ssa-loop.h",
- "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h",
+ "gimple.h", "gimple-iterator.h", "gimple-ssa.h", "tree-cfg.h",
+ "tree-phinodes.h", "ssa-iterators.h", "tree-ssanames.h",
+ "tree-ssa-loop.h", "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h",
"tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h",
"tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
"except.h", "output.h", "cfgloop.h",
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index c74d9295d1d..9156f952784 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -25,7 +25,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "demangle.h"
+#include "gimple-ssa.h"
/* ----- Type related ----- */
@@ -406,6 +408,116 @@ gimple_can_coalesce_p (tree name1, tree name2)
return false;
}
+/* Strip off a legitimate source ending from the input string NAME of
+ length LEN. Rather than having to know the names used by all of
+ our front ends, we strip off an ending of a period followed by
+ up to five characters. (Java uses ".class".) */
+
+static inline void
+remove_suffix (char *name, int len)
+{
+ int i;
+
+ for (i = 2; i < 8 && len > i; i++)
+ {
+ if (name[len - i] == '.')
+ {
+ name[len - i] = '\0';
+ break;
+ }
+ }
+}
+
+/* Create a new temporary name with PREFIX. Return an identifier. */
+
+static GTY(()) unsigned int tmp_var_id_num;
+
+tree
+create_tmp_var_name (const char *prefix)
+{
+ char *tmp_name;
+
+ if (prefix)
+ {
+ char *preftmp = ASTRDUP (prefix);
+
+ remove_suffix (preftmp, strlen (preftmp));
+ clean_symbol_name (preftmp);
+
+ prefix = preftmp;
+ }
+
+ ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
+ return get_identifier (tmp_name);
+}
+
+/* Create a new temporary variable declaration of type TYPE.
+ Do NOT push it into the current binding. */
+
+tree
+create_tmp_var_raw (tree type, const char *prefix)
+{
+ tree tmp_var;
+
+ tmp_var = build_decl (input_location,
+ VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
+ type);
+
+ /* The variable was declared by the compiler. */
+ DECL_ARTIFICIAL (tmp_var) = 1;
+ /* And we don't want debug info for it. */
+ DECL_IGNORED_P (tmp_var) = 1;
+
+ /* Make the variable writable. */
+ TREE_READONLY (tmp_var) = 0;
+
+ DECL_EXTERNAL (tmp_var) = 0;
+ TREE_STATIC (tmp_var) = 0;
+ TREE_USED (tmp_var) = 1;
+
+ return tmp_var;
+}
+
+/* Create a new temporary variable declaration of type TYPE. DO push the
+ variable into the current binding. Further, assume that this is called
+ only from gimplification or optimization, at which point the creation of
+ certain types are bugs. */
+
+tree
+create_tmp_var (tree type, const char *prefix)
+{
+ tree tmp_var;
+
+ /* We don't allow types that are addressable (meaning we can't make copies),
+ or incomplete. We also used to reject every variable size objects here,
+ but now support those for which a constant upper bound can be obtained.
+ The processing for variable sizes is performed in gimple_add_tmp_var,
+ point at which it really matters and possibly reached via paths not going
+ through this function, e.g. after direct calls to create_tmp_var_raw. */
+ gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
+
+ tmp_var = create_tmp_var_raw (type, prefix);
+ gimple_add_tmp_var (tmp_var);
+ return tmp_var;
+}
+
+/* Create a new temporary variable declaration of type TYPE by calling
+ create_tmp_var and if TYPE is a vector or a complex number, mark the new
+ temporary as gimple register. */
+
+tree
+create_tmp_reg (tree type, const char *prefix)
+{
+ tree tmp;
+
+ tmp = create_tmp_var (type, prefix);
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
+ DECL_GIMPLE_REG_P (tmp) = 1;
+
+ return tmp;
+}
+
/* ----- Expression related ----- */
@@ -719,3 +831,45 @@ is_gimple_mem_ref_addr (tree t)
&& (CONSTANT_CLASS_P (TREE_OPERAND (t, 0))
|| decl_address_invariant_p (TREE_OPERAND (t, 0)))));
}
+
+/* Mark X addressable. Unlike the langhook we expect X to be in gimple
+ form and we don't do any syntax checking. */
+
+void
+mark_addressable (tree x)
+{
+ while (handled_component_p (x))
+ x = TREE_OPERAND (x, 0);
+ if (TREE_CODE (x) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
+ x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
+ if (TREE_CODE (x) != VAR_DECL
+ && TREE_CODE (x) != PARM_DECL
+ && 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;
+ }
+}
+
+/* Returns true iff T is a valid RHS for an assignment to a renamed
+ user -- or front-end generated artificial -- variable. */
+
+bool
+is_gimple_reg_rhs (tree t)
+{
+ return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
+}
+
+#include "gt-gimple-expr.h"
diff --git a/gcc/gimple-expr.h b/gcc/gimple-expr.h
index aad558cebb7..e74be2249df 100644
--- a/gcc/gimple-expr.h
+++ b/gcc/gimple-expr.h
@@ -22,12 +22,18 @@ along with GCC; see the file COPYING3. If not see
extern bool useless_type_conversion_p (tree, tree);
+
extern void gimple_set_body (tree, gimple_seq);
extern gimple_seq gimple_body (tree);
extern bool gimple_has_body_p (tree);
extern const char *gimple_decl_printable_name (tree, int);
extern tree copy_var_decl (tree, tree, tree);
extern bool gimple_can_coalesce_p (tree, tree);
+extern tree create_tmp_var_name (const char *);
+extern tree create_tmp_var_raw (tree, const char *);
+extern tree create_tmp_var (tree, const char *);
+extern tree create_tmp_reg (tree, const char *);
+
extern void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *,
tree *);
@@ -46,6 +52,8 @@ extern bool is_gimple_asm_val (tree);
extern bool is_gimple_min_lval (tree);
extern bool is_gimple_call_addr (tree);
extern bool is_gimple_mem_ref_addr (tree);
+extern void mark_addressable (tree);
+extern bool is_gimple_reg_rhs (tree);
/* Return true if a conversion from either type of TYPE1 and TYPE2
to the other is not required. Otherwise return false. */
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 16ab93b1850..ffaa765aa5e 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-into-ssa.h"
@@ -196,7 +198,7 @@ canonicalize_constructor_val (tree cval, tree from_decl)
/* Make sure we create a cgraph node for functions we'll reference.
They can be non-existent if the reference comes from an entry
of an external vtable for example. */
- cgraph_get_create_real_symbol_node (base);
+ cgraph_get_create_node (base);
}
/* Fixup types in global initializers. */
if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
index e430050fcf7..b9453892891 100644
--- a/gcc/gimple-iterator.c
+++ b/gcc/gimple-iterator.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
new file mode 100644
index 00000000000..24045f52487
--- /dev/null
+++ b/gcc/gimple-iterator.h
@@ -0,0 +1,298 @@
+/* Header file for gimple iterators.
+ Copyright (C) 2013 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/>. */
+
+#ifndef GCC_GIMPLE_ITERATOR_H
+#define GCC_GIMPLE_ITERATOR_H
+
+/* Iterator object for GIMPLE statement sequences. */
+
+typedef struct gimple_stmt_iterator_d
+{
+ /* Sequence node holding the current statement. */
+ gimple_seq_node ptr;
+
+ /* Sequence and basic block holding the statement. These fields
+ are necessary to handle edge cases such as when statement is
+ added to an empty basic block or when the last statement of a
+ block/sequence is removed. */
+ gimple_seq *seq;
+ basic_block bb;
+} gimple_stmt_iterator;
+
+enum gsi_iterator_update
+{
+ GSI_NEW_STMT, /* Only valid when single statement is added, move
+ iterator to it. */
+ GSI_SAME_STMT, /* Leave the iterator at the same statement. */
+ GSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable
+ for linking other statements in the same
+ direction. */
+};
+
+extern void gsi_insert_seq_before_without_update (gimple_stmt_iterator *,
+ gimple_seq,
+ enum gsi_iterator_update);
+extern void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq,
+ enum gsi_iterator_update);
+extern void gsi_insert_seq_after_without_update (gimple_stmt_iterator *,
+ gimple_seq,
+ enum gsi_iterator_update);
+extern void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq,
+ enum gsi_iterator_update);
+extern gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
+extern void gsi_set_stmt (gimple_stmt_iterator *, gimple);
+extern void gsi_split_seq_before (gimple_stmt_iterator *, gimple_seq *);
+extern void gsi_replace (gimple_stmt_iterator *, gimple, bool);
+extern void gsi_replace_with_seq (gimple_stmt_iterator *, gimple_seq, bool);
+extern void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+extern void gsi_insert_before (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+extern void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+extern void gsi_insert_after (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+extern bool gsi_remove (gimple_stmt_iterator *, bool);
+extern gimple_stmt_iterator gsi_for_stmt (gimple);
+extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
+extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
+extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
+extern void gsi_insert_on_edge (edge, gimple);
+extern void gsi_insert_seq_on_edge (edge, gimple_seq);
+extern basic_block gsi_insert_on_edge_immediate (edge, gimple);
+extern basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
+extern void gsi_commit_edge_inserts (void);
+extern void gsi_commit_one_edge_insert (edge, basic_block *);
+extern gimple_stmt_iterator gsi_start_phis (basic_block);
+
+/* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
+
+static inline gimple_stmt_iterator
+gsi_start_1 (gimple_seq *seq)
+{
+ gimple_stmt_iterator i;
+
+ i.ptr = gimple_seq_first (*seq);
+ i.seq = seq;
+ i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
+
+ return i;
+}
+
+#define gsi_start(x) gsi_start_1 (&(x))
+
+static inline gimple_stmt_iterator
+gsi_none (void)
+{
+ gimple_stmt_iterator i;
+ i.ptr = NULL;
+ i.seq = NULL;
+ i.bb = NULL;
+ return i;
+}
+
+/* Return a new iterator pointing to the first statement in basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_start_bb (basic_block bb)
+{
+ gimple_stmt_iterator i;
+ gimple_seq *seq;
+
+ seq = bb_seq_addr (bb);
+ i.ptr = gimple_seq_first (*seq);
+ i.seq = seq;
+ i.bb = bb;
+
+ return i;
+}
+
+/* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */
+
+static inline gimple_stmt_iterator
+gsi_last_1 (gimple_seq *seq)
+{
+ gimple_stmt_iterator i;
+
+ i.ptr = gimple_seq_last (*seq);
+ i.seq = seq;
+ i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
+
+ return i;
+}
+
+#define gsi_last(x) gsi_last_1 (&(x))
+
+/* Return a new iterator pointing to the last statement in basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_last_bb (basic_block bb)
+{
+ gimple_stmt_iterator i;
+ gimple_seq *seq;
+
+ seq = bb_seq_addr (bb);
+ i.ptr = gimple_seq_last (*seq);
+ i.seq = seq;
+ i.bb = bb;
+
+ return i;
+}
+
+/* Return true if I is at the end of its sequence. */
+
+static inline bool
+gsi_end_p (gimple_stmt_iterator i)
+{
+ return i.ptr == NULL;
+}
+
+/* Return true if I is one statement before the end of its sequence. */
+
+static inline bool
+gsi_one_before_end_p (gimple_stmt_iterator i)
+{
+ return i.ptr != NULL && i.ptr->gsbase.next == NULL;
+}
+
+/* Advance the iterator to the next gimple statement. */
+
+static inline void
+gsi_next (gimple_stmt_iterator *i)
+{
+ i->ptr = i->ptr->gsbase.next;
+}
+
+/* Advance the iterator to the previous gimple statement. */
+
+static inline void
+gsi_prev (gimple_stmt_iterator *i)
+{
+ gimple prev = i->ptr->gsbase.prev;
+ if (prev->gsbase.next)
+ i->ptr = prev;
+ else
+ i->ptr = NULL;
+}
+
+/* Return the current stmt. */
+
+static inline gimple
+gsi_stmt (gimple_stmt_iterator i)
+{
+ return i.ptr;
+}
+
+/* Return a block statement iterator that points to the first non-label
+ statement in block BB. */
+
+static inline gimple_stmt_iterator
+gsi_after_labels (basic_block bb)
+{
+ gimple_stmt_iterator gsi = gsi_start_bb (bb);
+
+ while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
+ gsi_next (&gsi);
+
+ return gsi;
+}
+
+/* Advance the iterator to the next non-debug gimple statement. */
+
+static inline void
+gsi_next_nondebug (gimple_stmt_iterator *i)
+{
+ do
+ {
+ gsi_next (i);
+ }
+ while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
+}
+
+/* Advance the iterator to the next non-debug gimple statement. */
+
+static inline void
+gsi_prev_nondebug (gimple_stmt_iterator *i)
+{
+ do
+ {
+ gsi_prev (i);
+ }
+ while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
+}
+
+/* Return a new iterator pointing to the first non-debug statement in
+ basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_start_nondebug_bb (basic_block bb)
+{
+ gimple_stmt_iterator i = gsi_start_bb (bb);
+
+ if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
+ gsi_next_nondebug (&i);
+
+ return i;
+}
+
+/* Return a new iterator pointing to the first non-debug non-label statement in
+ basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_start_nondebug_after_labels_bb (basic_block bb)
+{
+ gimple_stmt_iterator i = gsi_after_labels (bb);
+
+ if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
+ gsi_next_nondebug (&i);
+
+ return i;
+}
+
+/* Return a new iterator pointing to the last non-debug statement in
+ basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_last_nondebug_bb (basic_block bb)
+{
+ gimple_stmt_iterator i = gsi_last_bb (bb);
+
+ if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
+ gsi_prev_nondebug (&i);
+
+ return i;
+}
+
+/* Return the basic block associated with this iterator. */
+
+static inline basic_block
+gsi_bb (gimple_stmt_iterator i)
+{
+ return i.bb;
+}
+
+/* Return the sequence associated with this iterator. */
+
+static inline gimple_seq
+gsi_seq (gimple_stmt_iterator i)
+{
+ return *i.seq;
+}
+
+#endif /* GCC_GIMPLE_ITERATOR_H */
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index d527d86ab22..519e984da28 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-iterator.h"
#include "tree-inline.h"
#include "flags.h"
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index c95b9c46357..8bf90f23aa2 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -621,8 +622,18 @@ pp_points_to_solution (pretty_printer *buffer, struct pt_solution *pt)
pp_space (buffer);
}
pp_right_brace (buffer);
- if (pt->vars_contains_global)
- pp_string (buffer, " (glob)");
+ if (pt->vars_contains_nonlocal
+ && pt->vars_contains_escaped_heap)
+ pp_string (buffer, " (nonlocal, escaped heap)");
+ else if (pt->vars_contains_nonlocal
+ && pt->vars_contains_escaped)
+ pp_string (buffer, " (nonlocal, escaped)");
+ else if (pt->vars_contains_nonlocal)
+ pp_string (buffer, " (nonlocal)");
+ else if (pt->vars_contains_escaped_heap)
+ pp_string (buffer, " (escaped heap)");
+ else if (pt->vars_contains_escaped)
+ pp_string (buffer, " (escaped)");
}
}
@@ -1107,6 +1118,8 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GF_OMP_FOR_KIND_SIMD:
kind = " simd";
break;
+ case GF_OMP_FOR_KIND_CILKSIMD:
+ kind = " cilksimd";
case GF_OMP_FOR_KIND_DISTRIBUTE:
kind = " distribute";
break;
@@ -1138,6 +1151,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GF_OMP_FOR_KIND_SIMD:
pp_string (buffer, "#pragma omp simd");
break;
+ case GF_OMP_FOR_KIND_CILKSIMD:
+ pp_string (buffer, "#pragma simd");
+ break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
break;
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index 983ed4d7602..c42f112da8b 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "tree-ssa.h"
#include "tree-ssanames.h"
#include "gimple-ssa.h"
@@ -35,26 +37,84 @@ along with GCC; see the file COPYING3. If not see
#include "ssa-iterators.h"
#include "cfgloop.h"
#include "tree-pass.h"
+#include "tree-cfg.h"
static bool cfg_altered;
-/* Insert a trap before SI and remove SI and all statements after SI. */
+/* Callback for walk_stmt_load_store_ops.
+
+ Return TRUE if OP will dereference the tree stored in DATA, FALSE
+ otherwise.
+
+ This routine only makes a superficial check for a dereference. Thus,
+ it must only be used if it is safe to return a false negative. */
+static bool
+check_loadstore (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+{
+ if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
+ && operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0))
+ {
+ TREE_THIS_VOLATILE (op) = 1;
+ TREE_SIDE_EFFECTS (op) = 1;
+ update_stmt (stmt);
+ return true;
+ }
+ return false;
+}
+
+/* Insert a trap after SI and remove SI and all statements after the trap. */
static void
-insert_trap_and_remove_trailing_statements (gimple_stmt_iterator *si_p)
+insert_trap_and_remove_trailing_statements (gimple_stmt_iterator *si_p, tree op)
{
- gimple_seq seq = NULL;
- gimple stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
- gimple_seq_add_stmt (&seq, stmt);
- gsi_insert_before (si_p, seq, GSI_SAME_STMT);
+ /* We want the NULL pointer dereference to actually occur so that
+ code that wishes to catch the signal can do so.
+
+ If the dereference is a load, then there's nothing to do as the
+ LHS will be a throw-away SSA_NAME and the RHS is the NULL dereference.
+
+ If the dereference is a store and we can easily transform the RHS,
+ then simplify the RHS to enable more DCE. Note that we require the
+ statement to be a GIMPLE_ASSIGN which filters out calls on the RHS. */
+ gimple stmt = gsi_stmt (*si_p);
+ if (walk_stmt_load_store_ops (stmt, (void *)op, NULL, check_loadstore)
+ && is_gimple_assign (stmt)
+ && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
+ {
+ /* We just need to turn the RHS into zero converted to the proper
+ type. */
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+ gimple_assign_set_rhs_code (stmt, INTEGER_CST);
+ gimple_assign_set_rhs1 (stmt, fold_convert (type, integer_zero_node));
+ update_stmt (stmt);
+ }
- /* Now delete all remaining statements in this block. */
- for (; !gsi_end_p (*si_p);)
+ gimple new_stmt
+ = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
+ gimple_seq seq = NULL;
+ gimple_seq_add_stmt (&seq, new_stmt);
+
+ /* If we had a NULL pointer dereference, then we want to insert the
+ __builtin_trap after the statement, for the other cases we want
+ to insert before the statement. */
+ if (walk_stmt_load_store_ops (stmt, (void *)op,
+ check_loadstore,
+ check_loadstore))
+ gsi_insert_after (si_p, seq, GSI_NEW_STMT);
+ else
+ gsi_insert_before (si_p, seq, GSI_NEW_STMT);
+
+ /* We must remove statements from the end of the block so that we
+ never reference a released SSA_NAME. */
+ basic_block bb = gimple_bb (gsi_stmt (*si_p));
+ for (gimple_stmt_iterator si = gsi_last_bb (bb);
+ gsi_stmt (si) != gsi_stmt (*si_p);
+ si = gsi_last_bb (bb))
{
- stmt = gsi_stmt (*si_p);
+ stmt = gsi_stmt (si);
unlink_stmt_vdef (stmt);
- gsi_remove (si_p, true);
+ gsi_remove (&si, true);
release_defs (stmt);
}
}
@@ -73,7 +133,8 @@ insert_trap_and_remove_trailing_statements (gimple_stmt_iterator *si_p)
Return BB'. */
basic_block
-isolate_path (basic_block bb, basic_block duplicate, edge e, gimple stmt)
+isolate_path (basic_block bb, basic_block duplicate,
+ edge e, gimple stmt, tree op)
{
gimple_stmt_iterator si, si2;
edge_iterator ei;
@@ -133,49 +194,39 @@ isolate_path (basic_block bb, basic_block duplicate, edge e, gimple stmt)
SI2 points to the duplicate of STMT in DUPLICATE. Insert a trap
before SI2 and remove SI2 and all trailing statements. */
if (!gsi_end_p (si2))
- insert_trap_and_remove_trailing_statements (&si2);
+ insert_trap_and_remove_trailing_statements (&si2, op);
return duplicate;
}
-/* Search the function for statements which, if executed, would cause
- the program to fault such as a dereference of a NULL pointer.
-
- Such a program can't be valid if such a statement was to execute
- according to ISO standards.
-
- We detect explicit NULL pointer dereferences as well as those implied
- by a PHI argument having a NULL value which unconditionally flows into
- a dereference in the same block as the PHI.
+/* Look for PHI nodes which feed statements in the same block where
+ the value of the PHI node implies the statement is erroneous.
- In the former case we replace the offending statement with an
- unconditional trap and eliminate the outgoing edges from the statement's
- basic block. This may expose secondary optimization opportunities.
+ For example, a NULL PHI arg value which then feeds a pointer
+ dereference.
- In the latter case, we isolate the path(s) with the NULL PHI
- feeding the dereference. We can then replace the offending statement
- and eliminate the outgoing edges in the duplicate. Again, this may
- expose secondary optimization opportunities.
-
- A warning for both cases may be advisable as well.
-
- Other statically detectable violations of the ISO standard could be
- handled in a similar way, such as out-of-bounds array indexing. */
-
-static unsigned int
-gimple_ssa_isolate_erroneous_paths (void)
+ When found isolate and optimize the path associated with the PHI
+ argument feeding the erroneous statement. */
+static void
+find_implicit_erroneous_behaviour (void)
{
basic_block bb;
- initialize_original_copy_tables ();
-
- /* Search all the blocks for edges which, if traversed, will
- result in undefined behaviour. */
- cfg_altered = false;
FOR_EACH_BB (bb)
{
gimple_stmt_iterator si;
+ /* Out of an abundance of caution, do not isolate paths to a
+ block where the block has any abnormal outgoing edges.
+
+ We might be able to relax this in the future. We have to detect
+ when we have to split the block with the NULL dereference and
+ the trap we insert. We have to preserve abnormal edges out
+ of the isolated block which in turn means updating PHIs at
+ the targets of those abnormal outgoing edges. */
+ if (has_abnormal_or_eh_outgoing_edge_p (bb))
+ continue;
+
/* First look for a PHI which sets a pointer to NULL and which
is then dereferenced within BB. This is somewhat overly
conservative, but probably catches most of the interesting
@@ -217,14 +268,14 @@ gimple_ssa_isolate_erroneous_paths (void)
{
/* We only care about uses in BB. Catching cases in
in other blocks would require more complex path
- isolation code. */
+ isolation code. */
if (gimple_bb (use_stmt) != bb)
continue;
if (infer_nonnull_range (use_stmt, lhs))
{
duplicate = isolate_path (bb, duplicate,
- e, use_stmt);
+ e, use_stmt, lhs);
/* When we remove an incoming edge, we need to
reprocess the Ith element. */
@@ -234,6 +285,32 @@ gimple_ssa_isolate_erroneous_paths (void)
}
}
}
+ }
+}
+
+/* Look for statements which exhibit erroneous behaviour. For example
+ a NULL pointer dereference.
+
+ When found, optimize the block containing the erroneous behaviour. */
+static void
+find_explicit_erroneous_behaviour (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator si;
+
+ /* Out of an abundance of caution, do not isolate paths to a
+ block where the block has any abnormal outgoing edges.
+
+ We might be able to relax this in the future. We have to detect
+ when we have to split the block with the NULL dereference and
+ the trap we insert. We have to preserve abnormal edges out
+ of the isolated block which in turn means updating PHIs at
+ the targets of those abnormal outgoing edges. */
+ if (has_abnormal_or_eh_outgoing_edge_p (bb))
+ continue;
/* Now look at the statements in the block and see if any of
them explicitly dereference a NULL pointer. This happens
@@ -247,7 +324,8 @@ gimple_ssa_isolate_erroneous_paths (void)
where a non-NULL value is required. */
if (infer_nonnull_range (stmt, null_pointer_node))
{
- insert_trap_and_remove_trailing_statements (&si);
+ insert_trap_and_remove_trailing_statements (&si,
+ null_pointer_node);
/* And finally, remove all outgoing edges from BB. */
edge e;
@@ -263,6 +341,56 @@ gimple_ssa_isolate_erroneous_paths (void)
}
}
}
+}
+/* Search the function for statements which, if executed, would cause
+ the program to fault such as a dereference of a NULL pointer.
+
+ Such a program can't be valid if such a statement was to execute
+ according to ISO standards.
+
+ We detect explicit NULL pointer dereferences as well as those implied
+ by a PHI argument having a NULL value which unconditionally flows into
+ a dereference in the same block as the PHI.
+
+ In the former case we replace the offending statement with an
+ unconditional trap and eliminate the outgoing edges from the statement's
+ basic block. This may expose secondary optimization opportunities.
+
+ In the latter case, we isolate the path(s) with the NULL PHI
+ feeding the dereference. We can then replace the offending statement
+ and eliminate the outgoing edges in the duplicate. Again, this may
+ expose secondary optimization opportunities.
+
+ A warning for both cases may be advisable as well.
+
+ Other statically detectable violations of the ISO standard could be
+ handled in a similar way, such as out-of-bounds array indexing. */
+
+static unsigned int
+gimple_ssa_isolate_erroneous_paths (void)
+{
+ initialize_original_copy_tables ();
+
+ /* Search all the blocks for edges which, if traversed, will
+ result in undefined behaviour. */
+ cfg_altered = false;
+
+ /* First handle cases where traversal of a particular edge
+ triggers undefined behaviour. These cases require creating
+ duplicate blocks and thus new SSA_NAMEs.
+
+ We want that process complete prior to the phase where we start
+ removing edges from the CFG. Edge removal may ultimately result in
+ removal of PHI nodes and thus releasing SSA_NAMEs back to the
+ name manager.
+
+ If the two processes run in parallel we could release an SSA_NAME
+ back to the manager but we could still have dangling references
+ to the released SSA_NAME in unreachable blocks.
+ that any released names not have dangling references in the IL. */
+ find_implicit_erroneous_behaviour ();
+ find_explicit_erroneous_behaviour ();
+
free_original_copy_tables ();
/* We scramble the CFG and loop structures a bit, clean up
@@ -314,7 +442,7 @@ public:
bool gate () { return gate_isolate_erroneous_paths (); }
unsigned int execute () { return gimple_ssa_isolate_erroneous_paths (); }
-}; // class pass_uncprop
+}; // class pass_isolate_erroneous_paths
}
gimple_opt_pass *
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 69680b28585..639e037fea5 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "basic-block.h"
#include "tree-pass.h"
#include "cfgloop.h"
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index 2a19aab44fe..6f8f51a18ce 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "tree-ssanames.h"
@@ -158,85 +159,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
if (TREE_CODE (*opp) == ADDR_EXPR)
opp = &TREE_OPERAND (*opp, 0);
while (handled_component_p (*opp))
- {
- if (TREE_CODE (*opp) == COMPONENT_REF)
- {
- /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
- by decl merging. */
- tree field, type, tem;
- tree closest_match = NULL_TREE;
- field = TREE_OPERAND (*opp, 1);
- type = DECL_CONTEXT (field);
- for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
- {
- if (TREE_CODE (tem) != FIELD_DECL)
- continue;
- if (tem == field)
- break;
- if (DECL_NONADDRESSABLE_P (tem)
- == DECL_NONADDRESSABLE_P (field)
- && gimple_compare_field_offset (tem, field))
- {
- if (types_compatible_p (TREE_TYPE (tem),
- TREE_TYPE (field)))
- break;
- else
- closest_match = tem;
- }
- }
- /* In case of type mismatches across units we can fail
- to unify some types and thus not find a proper
- field-decl here. */
- if (tem == NULL_TREE)
- {
- /* Thus, emit a ODR violation warning. */
- if (warning_at (gimple_location (stmt), 0,
- "use of type %<%E%> with two mismatching "
- "declarations at field %<%E%>",
- type, TREE_OPERAND (*opp, 1)))
- {
- if (TYPE_FIELDS (type))
- inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
- "original type declared here");
- inform (DECL_SOURCE_LOCATION (TREE_OPERAND (*opp, 1)),
- "field in mismatching type declared here");
- if (TYPE_NAME (TREE_TYPE (field))
- && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
- == TYPE_DECL))
- inform (DECL_SOURCE_LOCATION
- (TYPE_NAME (TREE_TYPE (field))),
- "type of field declared here");
- if (closest_match
- && TYPE_NAME (TREE_TYPE (closest_match))
- && (TREE_CODE (TYPE_NAME
- (TREE_TYPE (closest_match))) == TYPE_DECL))
- inform (DECL_SOURCE_LOCATION
- (TYPE_NAME (TREE_TYPE (closest_match))),
- "type of mismatching field declared here");
- }
- /* And finally fixup the types. */
- TREE_OPERAND (*opp, 0)
- = build1 (VIEW_CONVERT_EXPR, type,
- TREE_OPERAND (*opp, 0));
- }
- else
- TREE_OPERAND (*opp, 1) = tem;
- }
- else if ((TREE_CODE (*opp) == ARRAY_REF
- || TREE_CODE (*opp) == ARRAY_RANGE_REF)
- && (TREE_CODE (TREE_TYPE (TREE_OPERAND (*opp, 0)))
- != ARRAY_TYPE))
- {
- /* And ARRAY_REFs to objects that had mismatched types
- during symbol merging to avoid ICEs. */
- TREE_OPERAND (*opp, 0)
- = build1 (VIEW_CONVERT_EXPR,
- build_array_type (TREE_TYPE (*opp), NULL_TREE),
- TREE_OPERAND (*opp, 0));
- }
-
- opp = &TREE_OPERAND (*opp, 0);
- }
+ opp = &TREE_OPERAND (*opp, 0);
/* At LTO output time we wrap all global decls in MEM_REFs to
allow seamless replacement with prevailing decls. Undo this
here if the prevailing decl allows for this.
diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c
index 976f57ecef4..4d0664f3d98 100644
--- a/gcc/gimple-streamer-out.c
+++ b/gcc/gimple-streamer-out.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "data-streamer.h"
#include "gimple-streamer.h"
@@ -129,6 +130,8 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
if (op && (i || !is_gimple_debug (stmt)))
{
basep = &op;
+ if (TREE_CODE (*basep) == ADDR_EXPR)
+ basep = &TREE_OPERAND (*basep, 0);
while (handled_component_p (*basep))
basep = &TREE_OPERAND (*basep, 0);
if (TREE_CODE (*basep) == VAR_DECL
@@ -136,10 +139,10 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
&& !DECL_REGISTER (*basep))
{
bool volatilep = TREE_THIS_VOLATILE (*basep);
+ tree ptrtype = build_pointer_type (TREE_TYPE (*basep));
*basep = build2 (MEM_REF, TREE_TYPE (*basep),
- build_fold_addr_expr (*basep),
- build_int_cst (build_pointer_type
- (TREE_TYPE (*basep)), 0));
+ build1 (ADDR_EXPR, ptrtype, *basep),
+ build_int_cst (ptrtype, 0));
TREE_THIS_VOLATILE (*basep) = volatilep;
}
else
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
new file mode 100644
index 00000000000..deb4673354a
--- /dev/null
+++ b/gcc/gimple-walk.c
@@ -0,0 +1,871 @@
+/* Gimple walk support.
+
+ Copyright (C) 2007-2013 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>
+
+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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+#include "gimple-walk.h"
+#include "demangle.h"
+
+/* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
+ on each one. WI is as in walk_gimple_stmt.
+
+ If walk_gimple_stmt returns non-NULL, the walk is stopped, and the
+ value is stored in WI->CALLBACK_RESULT. Also, the statement that
+ produced the value is returned if this statement has not been
+ removed by a callback (wi->removed_stmt). If the statement has
+ been removed, NULL is returned.
+
+ Otherwise, all the statements are walked and NULL returned. */
+
+gimple
+walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
+{
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); )
+ {
+ tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
+ if (ret)
+ {
+ /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist
+ to hold it. */
+ gcc_assert (wi);
+ wi->callback_result = ret;
+
+ return wi->removed_stmt ? NULL : gsi_stmt (gsi);
+ }
+
+ if (!wi->removed_stmt)
+ gsi_next (&gsi);
+ }
+
+ if (wi)
+ wi->callback_result = NULL_TREE;
+
+ return NULL;
+}
+
+
+/* Like walk_gimple_seq_mod, but ensure that the head of SEQ isn't
+ changed by the callbacks. */
+
+gimple
+walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
+{
+ gimple_seq seq2 = seq;
+ gimple ret = walk_gimple_seq_mod (&seq2, callback_stmt, callback_op, wi);
+ gcc_assert (seq2 == seq);
+ return ret;
+}
+
+
+/* Helper function for walk_gimple_stmt. Walk operands of a GIMPLE_ASM. */
+
+static tree
+walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
+ struct walk_stmt_info *wi)
+{
+ tree ret, op;
+ unsigned noutputs;
+ const char **oconstraints;
+ unsigned i, n;
+ const char *constraint;
+ bool allows_mem, allows_reg, is_inout;
+
+ noutputs = gimple_asm_noutputs (stmt);
+ oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
+
+ if (wi)
+ wi->is_lhs = true;
+
+ for (i = 0; i < noutputs; i++)
+ {
+ op = gimple_asm_output_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ oconstraints[i] = constraint;
+ parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg,
+ &is_inout);
+ if (wi)
+ wi->val_only = (allows_reg || !allows_mem);
+ ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
+ if (ret)
+ return ret;
+ }
+
+ n = gimple_asm_ninputs (stmt);
+ for (i = 0; i < n; i++)
+ {
+ op = gimple_asm_input_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+ if (wi)
+ {
+ wi->val_only = (allows_reg || !allows_mem);
+ /* Although input "m" is not really a LHS, we need a lvalue. */
+ wi->is_lhs = !wi->val_only;
+ }
+ ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
+ if (ret)
+ return ret;
+ }
+
+ if (wi)
+ {
+ wi->is_lhs = false;
+ wi->val_only = true;
+ }
+
+ n = gimple_asm_nlabels (stmt);
+ for (i = 0; i < n; i++)
+ {
+ op = gimple_asm_label_op (stmt, i);
+ ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
+ if (ret)
+ return ret;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Helper function of WALK_GIMPLE_STMT. Walk every tree operand in
+ STMT. CALLBACK_OP and WI are as in WALK_GIMPLE_STMT.
+
+ CALLBACK_OP is called on each operand of STMT via walk_tree.
+ Additional parameters to walk_tree must be stored in WI. For each operand
+ OP, walk_tree is called as:
+
+ walk_tree (&OP, CALLBACK_OP, WI, WI->PSET)
+
+ If CALLBACK_OP returns non-NULL for an operand, the remaining
+ operands are not scanned.
+
+ The return value is that returned by the last call to walk_tree, or
+ NULL_TREE if no CALLBACK_OP is specified. */
+
+tree
+walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
+ struct walk_stmt_info *wi)
+{
+ struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
+ unsigned i;
+ tree ret = NULL_TREE;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ /* Walk the RHS operands. If the LHS is of a non-renamable type or
+ is a register variable, we may use a COMPONENT_REF on the RHS. */
+ if (wi)
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ wi->val_only
+ = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs))
+ || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
+ }
+
+ for (i = 1; i < gimple_num_ops (stmt); i++)
+ {
+ ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ }
+
+ /* Walk the LHS. If the RHS is appropriate for a memory, we
+ may use a COMPONENT_REF on the LHS. */
+ if (wi)
+ {
+ /* If the RHS is of a non-renamable type or is a register variable,
+ we may use a COMPONENT_REF on the LHS. */
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ wi->val_only
+ = (is_gimple_reg_type (TREE_TYPE (rhs1)) && !is_gimple_reg (rhs1))
+ || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
+ wi->is_lhs = true;
+ }
+
+ ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ if (wi)
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ }
+ break;
+
+ case GIMPLE_CALL:
+ if (wi)
+ {
+ wi->is_lhs = false;
+ wi->val_only = true;
+ }
+
+ ret = walk_tree (gimple_call_chain_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ {
+ if (wi)
+ wi->val_only
+ = is_gimple_reg_type (TREE_TYPE (gimple_call_arg (stmt, i)));
+ ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ }
+
+ if (gimple_call_lhs (stmt))
+ {
+ if (wi)
+ {
+ wi->is_lhs = true;
+ wi->val_only
+ = is_gimple_reg_type (TREE_TYPE (gimple_call_lhs (stmt)));
+ }
+
+ ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+ }
+
+ if (wi)
+ {
+ wi->is_lhs = false;
+ wi->val_only = true;
+ }
+ break;
+
+ case GIMPLE_CATCH:
+ ret = walk_tree (gimple_catch_types_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_EH_FILTER:
+ ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_ASM:
+ ret = walk_gimple_asm (stmt, callback_op, wi);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_CONTINUE:
+ ret = walk_tree (gimple_omp_continue_control_def_ptr (stmt),
+ callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_omp_continue_control_use_ptr (stmt),
+ callback_op, wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_CRITICAL:
+ ret = walk_tree (gimple_omp_critical_name_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_FOR:
+ ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
+ {
+ ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op,
+ wi, pset);
+ }
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_PARALLEL:
+ ret = walk_tree (gimple_omp_parallel_clauses_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_parallel_child_fn_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_parallel_data_arg_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_TASK:
+ ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+
+ break;
+
+ case GIMPLE_OMP_SINGLE:
+ ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_TARGET:
+ ret = walk_tree (gimple_omp_target_clauses_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_TEAMS:
+ ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_ATOMIC_STORE:
+ ret = walk_tree (gimple_omp_atomic_store_val_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_TRANSACTION:
+ ret = walk_tree (gimple_transaction_label_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_RETURN:
+ ret = walk_tree (gimple_omp_return_lhs_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ /* Tuples that do not have operands. */
+ case GIMPLE_NOP:
+ case GIMPLE_RESX:
+ case GIMPLE_PREDICT:
+ break;
+
+ default:
+ {
+ enum gimple_statement_structure_enum gss;
+ gss = gimple_statement_structure (stmt);
+ if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ {
+ ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset);
+ if (ret)
+ return ret;
+ }
+ }
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Walk the current statement in GSI (optionally using traversal state
+ stored in WI). If WI is NULL, no state is kept during traversal.
+ The callback CALLBACK_STMT is called. If CALLBACK_STMT indicates
+ that it has handled all the operands of the statement, its return
+ value is returned. Otherwise, the return value from CALLBACK_STMT
+ is discarded and its operands are scanned.
+
+ If CALLBACK_STMT is NULL or it didn't handle the operands,
+ CALLBACK_OP is called on each operand of the statement via
+ walk_gimple_op. If walk_gimple_op returns non-NULL for any
+ operand, the remaining operands are not scanned. In this case, the
+ return value from CALLBACK_OP is returned.
+
+ In any other case, NULL_TREE is returned. */
+
+tree
+walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
+{
+ gimple ret;
+ tree tree_ret;
+ gimple stmt = gsi_stmt (*gsi);
+
+ if (wi)
+ {
+ wi->gsi = *gsi;
+ wi->removed_stmt = false;
+
+ if (wi->want_locations && gimple_has_location (stmt))
+ input_location = gimple_location (stmt);
+ }
+
+ ret = NULL;
+
+ /* Invoke the statement callback. Return if the callback handled
+ all of STMT operands by itself. */
+ if (callback_stmt)
+ {
+ bool handled_ops = false;
+ tree_ret = callback_stmt (gsi, &handled_ops, wi);
+ if (handled_ops)
+ return tree_ret;
+
+ /* If CALLBACK_STMT did not handle operands, it should not have
+ a value to return. */
+ gcc_assert (tree_ret == NULL);
+
+ if (wi && wi->removed_stmt)
+ return NULL;
+
+ /* Re-read stmt in case the callback changed it. */
+ stmt = gsi_stmt (*gsi);
+ }
+
+ /* If CALLBACK_OP is defined, invoke it on every operand of STMT. */
+ if (callback_op)
+ {
+ tree_ret = walk_gimple_op (stmt, callback_op, wi);
+ if (tree_ret)
+ return tree_ret;
+ }
+
+ /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them. */
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_BIND:
+ ret = walk_gimple_seq_mod (gimple_bind_body_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_CATCH:
+ ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_EH_FILTER:
+ ret = walk_gimple_seq_mod (gimple_eh_filter_failure_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_EH_ELSE:
+ ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (stmt),
+ callback_stmt, callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (stmt),
+ callback_stmt, callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_TRY:
+ ret = walk_gimple_seq_mod (gimple_try_eval_ptr (stmt), callback_stmt, callback_op,
+ wi);
+ if (ret)
+ return wi->callback_result;
+
+ ret = walk_gimple_seq_mod (gimple_try_cleanup_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_OMP_FOR:
+ ret = walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+
+ /* FALL THROUGH. */
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_TARGET:
+ case GIMPLE_OMP_TEAMS:
+ ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_WITH_CLEANUP_EXPR:
+ ret = walk_gimple_seq_mod (gimple_wce_cleanup_ptr (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_TRANSACTION:
+ ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
+ callback_stmt, callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ default:
+ gcc_assert (!gimple_has_substatements (stmt));
+ break;
+ }
+
+ return NULL;
+}
+
+/* From a tree operand OP return the base of a load or store operation
+ or NULL_TREE if OP is not a load or a store. */
+
+static tree
+get_base_loadstore (tree op)
+{
+ while (handled_component_p (op))
+ op = TREE_OPERAND (op, 0);
+ if (DECL_P (op)
+ || INDIRECT_REF_P (op)
+ || TREE_CODE (op) == MEM_REF
+ || TREE_CODE (op) == TARGET_MEM_REF)
+ return op;
+ return NULL_TREE;
+}
+
+
+/* For the statement STMT call the callbacks VISIT_LOAD, VISIT_STORE and
+ VISIT_ADDR if non-NULL on loads, store and address-taken operands
+ passing the STMT, the base of the operand and DATA to it. The base
+ will be either a decl, an indirect reference (including TARGET_MEM_REF)
+ or the argument of an address expression.
+ Returns the results of these callbacks or'ed. */
+
+bool
+walk_stmt_load_store_addr_ops (gimple stmt, void *data,
+ bool (*visit_load)(gimple, tree, void *),
+ bool (*visit_store)(gimple, tree, void *),
+ bool (*visit_addr)(gimple, tree, void *))
+{
+ bool ret = false;
+ unsigned i;
+ if (gimple_assign_single_p (stmt))
+ {
+ tree lhs, rhs;
+ if (visit_store)
+ {
+ lhs = get_base_loadstore (gimple_assign_lhs (stmt));
+ if (lhs)
+ ret |= visit_store (stmt, lhs, data);
+ }
+ rhs = gimple_assign_rhs1 (stmt);
+ while (handled_component_p (rhs))
+ rhs = TREE_OPERAND (rhs, 0);
+ if (visit_addr)
+ {
+ if (TREE_CODE (rhs) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
+ else if (TREE_CODE (rhs) == TARGET_MEM_REF
+ && TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
+ else if (TREE_CODE (rhs) == OBJ_TYPE_REF
+ && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs),
+ 0), data);
+ else if (TREE_CODE (rhs) == CONSTRUCTOR)
+ {
+ unsigned int ix;
+ tree val;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), ix, val)
+ if (TREE_CODE (val) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (val, 0), data);
+ else if (TREE_CODE (val) == OBJ_TYPE_REF
+ && TREE_CODE (OBJ_TYPE_REF_OBJECT (val)) == ADDR_EXPR)
+ ret |= visit_addr (stmt,
+ TREE_OPERAND (OBJ_TYPE_REF_OBJECT (val),
+ 0), data);
+ }
+ lhs = gimple_assign_lhs (stmt);
+ if (TREE_CODE (lhs) == TARGET_MEM_REF
+ && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
+ }
+ if (visit_load)
+ {
+ rhs = get_base_loadstore (rhs);
+ if (rhs)
+ ret |= visit_load (stmt, rhs, data);
+ }
+ }
+ else if (visit_addr
+ && (is_gimple_assign (stmt)
+ || gimple_code (stmt) == GIMPLE_COND))
+ {
+ for (i = 0; i < gimple_num_ops (stmt); ++i)
+ {
+ tree op = gimple_op (stmt, i);
+ if (op == NULL_TREE)
+ ;
+ else if (TREE_CODE (op) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+ /* COND_EXPR and VCOND_EXPR rhs1 argument is a comparison
+ tree with two operands. */
+ else if (i == 1 && COMPARISON_CLASS_P (op))
+ {
+ if (TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 0),
+ 0), data);
+ if (TREE_CODE (TREE_OPERAND (op, 1)) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 1),
+ 0), data);
+ }
+ }
+ }
+ else if (is_gimple_call (stmt))
+ {
+ if (visit_store)
+ {
+ tree lhs = gimple_call_lhs (stmt);
+ if (lhs)
+ {
+ lhs = get_base_loadstore (lhs);
+ if (lhs)
+ ret |= visit_store (stmt, lhs, data);
+ }
+ }
+ if (visit_load || visit_addr)
+ for (i = 0; i < gimple_call_num_args (stmt); ++i)
+ {
+ tree rhs = gimple_call_arg (stmt, i);
+ if (visit_addr
+ && TREE_CODE (rhs) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
+ else if (visit_load)
+ {
+ rhs = get_base_loadstore (rhs);
+ if (rhs)
+ ret |= visit_load (stmt, rhs, data);
+ }
+ }
+ if (visit_addr
+ && gimple_call_chain (stmt)
+ && TREE_CODE (gimple_call_chain (stmt)) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (stmt), 0),
+ data);
+ if (visit_addr
+ && gimple_call_return_slot_opt_p (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE
+ && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
+ ret |= visit_addr (stmt, gimple_call_lhs (stmt), data);
+ }
+ else if (gimple_code (stmt) == GIMPLE_ASM)
+ {
+ unsigned noutputs;
+ const char *constraint;
+ const char **oconstraints;
+ bool allows_mem, allows_reg, is_inout;
+ noutputs = gimple_asm_noutputs (stmt);
+ oconstraints = XALLOCAVEC (const char *, noutputs);
+ if (visit_store || visit_addr)
+ for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+ {
+ tree link = gimple_asm_output_op (stmt, i);
+ tree op = get_base_loadstore (TREE_VALUE (link));
+ if (op && visit_store)
+ ret |= visit_store (stmt, op, data);
+ if (visit_addr)
+ {
+ constraint = TREE_STRING_POINTER
+ (TREE_VALUE (TREE_PURPOSE (link)));
+ oconstraints[i] = constraint;
+ parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
+ &allows_reg, &is_inout);
+ if (op && !allows_reg && allows_mem)
+ ret |= visit_addr (stmt, op, data);
+ }
+ }
+ if (visit_load || visit_addr)
+ for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+ {
+ tree link = gimple_asm_input_op (stmt, i);
+ tree op = TREE_VALUE (link);
+ if (visit_addr
+ && TREE_CODE (op) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+ else if (visit_load || visit_addr)
+ {
+ op = get_base_loadstore (op);
+ if (op)
+ {
+ if (visit_load)
+ ret |= visit_load (stmt, op, data);
+ if (visit_addr)
+ {
+ constraint = TREE_STRING_POINTER
+ (TREE_VALUE (TREE_PURPOSE (link)));
+ parse_input_constraint (&constraint, 0, 0, noutputs,
+ 0, oconstraints,
+ &allows_mem, &allows_reg);
+ if (!allows_reg && allows_mem)
+ ret |= visit_addr (stmt, op, data);
+ }
+ }
+ }
+ }
+ }
+ else if (gimple_code (stmt) == GIMPLE_RETURN)
+ {
+ tree op = gimple_return_retval (stmt);
+ if (op)
+ {
+ if (visit_addr
+ && TREE_CODE (op) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+ else if (visit_load)
+ {
+ op = get_base_loadstore (op);
+ if (op)
+ ret |= visit_load (stmt, op, data);
+ }
+ }
+ }
+ else if (visit_addr
+ && gimple_code (stmt) == GIMPLE_PHI)
+ {
+ for (i = 0; i < gimple_phi_num_args (stmt); ++i)
+ {
+ tree op = gimple_phi_arg_def (stmt, i);
+ if (TREE_CODE (op) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+ }
+ }
+ else if (visit_addr
+ && gimple_code (stmt) == GIMPLE_GOTO)
+ {
+ tree op = gimple_goto_dest (stmt);
+ if (TREE_CODE (op) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+ }
+
+ return ret;
+}
+
+/* Like walk_stmt_load_store_addr_ops but with NULL visit_addr. IPA-CP
+ should make a faster clone for this case. */
+
+bool
+walk_stmt_load_store_ops (gimple stmt, void *data,
+ bool (*visit_load)(gimple, tree, void *),
+ bool (*visit_store)(gimple, tree, void *))
+{
+ return walk_stmt_load_store_addr_ops (stmt, data,
+ visit_load, visit_store, NULL);
+}
diff --git a/gcc/gimple-walk.h b/gcc/gimple-walk.h
new file mode 100644
index 00000000000..0b9968a522d
--- /dev/null
+++ b/gcc/gimple-walk.h
@@ -0,0 +1,99 @@
+/* Header file for gimple statement walk support.
+ Copyright (C) 2013 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/>. */
+
+#ifndef GCC_GIMPLE_WALK_H
+#define GCC_GIMPLE_WALK_H
+
+/* Convenience routines to walk all statements of a gimple function.
+ Note that this is useful exclusively before the code is converted
+ into SSA form. Once the program is in SSA form, the standard
+ operand interface should be used to analyze/modify statements. */
+struct walk_stmt_info
+{
+ /* Points to the current statement being walked. */
+ gimple_stmt_iterator gsi;
+
+ /* Additional data that the callback functions may want to carry
+ through the recursion. */
+ void *info;
+
+ /* Pointer map used to mark visited tree nodes when calling
+ walk_tree on each operand. If set to NULL, duplicate tree nodes
+ will be visited more than once. */
+ struct pointer_set_t *pset;
+
+ /* Operand returned by the callbacks. This is set when calling
+ walk_gimple_seq. If the walk_stmt_fn or walk_tree_fn callback
+ returns non-NULL, this field will contain the tree returned by
+ the last callback. */
+ tree callback_result;
+
+ /* Indicates whether the operand being examined may be replaced
+ with something that matches is_gimple_val (if true) or something
+ slightly more complicated (if false). "Something" technically
+ means the common subset of is_gimple_lvalue and is_gimple_rhs,
+ but we never try to form anything more complicated than that, so
+ we don't bother checking.
+
+ Also note that CALLBACK should update this flag while walking the
+ sub-expressions of a statement. For instance, when walking the
+ statement 'foo (&var)', the flag VAL_ONLY will initially be set
+ to true, however, when walking &var, the operand of that
+ ADDR_EXPR does not need to be a GIMPLE value. */
+ BOOL_BITFIELD val_only : 1;
+
+ /* True if we are currently walking the LHS of an assignment. */
+ BOOL_BITFIELD is_lhs : 1;
+
+ /* Optional. Set to true by the callback functions if they made any
+ changes. */
+ BOOL_BITFIELD changed : 1;
+
+ /* True if we're interested in location information. */
+ BOOL_BITFIELD want_locations : 1;
+
+ /* True if we've removed the statement that was processed. */
+ BOOL_BITFIELD removed_stmt : 1;
+};
+
+/* Callback for walk_gimple_stmt. Called for every statement found
+ during traversal. The first argument points to the statement to
+ walk. The second argument is a flag that the callback sets to
+ 'true' if it the callback handled all the operands and
+ sub-statements of the statement (the default value of this flag is
+ 'false'). The third argument is an anonymous pointer to data
+ to be used by the callback. */
+typedef tree (*walk_stmt_fn) (gimple_stmt_iterator *, bool *,
+ struct walk_stmt_info *);
+
+extern gimple walk_gimple_seq_mod (gimple_seq *, walk_stmt_fn, walk_tree_fn,
+ struct walk_stmt_info *);
+extern gimple walk_gimple_seq (gimple_seq, walk_stmt_fn, walk_tree_fn,
+ struct walk_stmt_info *);
+extern tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *);
+extern tree walk_gimple_stmt (gimple_stmt_iterator *, walk_stmt_fn,
+ walk_tree_fn, struct walk_stmt_info *);
+extern bool walk_stmt_load_store_addr_ops (gimple, void *,
+ bool (*)(gimple, tree, void *),
+ bool (*)(gimple, tree, void *),
+ bool (*)(gimple, tree, void *));
+extern bool walk_stmt_load_store_ops (gimple, void *,
+ bool (*)(gimple, tree, void *),
+ bool (*)(gimple, tree, void *));
+#endif /* GCC_GIMPLE_WALK_H */
diff --git a/gcc/gimple.c b/gcc/gimple.c
index b041292e952..278135c18d8 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -29,6 +29,10 @@ along with GCC; see the file COPYING3. If not see
#include "hard-reg-set.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+#include "gimple.h"
+#include "gimplify.h"
#include "diagnostic.h"
#include "value-prof.h"
#include "flags.h"
@@ -446,24 +450,6 @@ gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1,
}
-/* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
-
- DST/SRC are the destination and source respectively. You can pass
- ungimplified trees in DST or SRC, in which case they will be
- converted to a gimple operand if necessary.
-
- This function returns the newly created GIMPLE_ASSIGN tuple. */
-
-gimple
-gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
-{
- tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
- gimplify_and_add (t, seq_p);
- ggc_free (t);
- return gimple_seq_last_stmt (*seq_p);
-}
-
-
/* Build a GIMPLE_COND statement.
PRED is the condition used to compare LHS and the RHS.
@@ -1172,6 +1158,23 @@ gimple_seq_add_stmt (gimple_seq *seq_p, gimple gs)
gsi_insert_after (&si, gs, GSI_NEW_STMT);
}
+/* Link gimple statement GS to the end of the sequence *SEQ_P. If
+ *SEQ_P is NULL, a new sequence is allocated. This function is
+ similar to gimple_seq_add_stmt, but does not scan the operands.
+ During gimplification, we need to manipulate statement sequences
+ before the def/use vectors have been constructed. */
+
+void
+gimple_seq_add_stmt_without_update (gimple_seq *seq_p, gimple gs)
+{
+ gimple_stmt_iterator si;
+
+ if (gs == NULL)
+ return;
+
+ si = gsi_last (*seq_p);
+ gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
+}
/* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
NULL, a new sequence is allocated. */
@@ -1187,6 +1190,64 @@ gimple_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
gsi_insert_seq_after (&si, src, GSI_NEW_STMT);
}
+/* Determine whether to assign a location to the statement GS. */
+
+static bool
+should_carry_location_p (gimple gs)
+{
+ /* Don't emit a line note for a label. We particularly don't want to
+ emit one for the break label, since it doesn't actually correspond
+ to the beginning of the loop/switch. */
+ if (gimple_code (gs) == GIMPLE_LABEL)
+ return false;
+
+ return true;
+}
+
+/* Set the location for gimple statement GS to LOCATION. */
+
+static void
+annotate_one_with_location (gimple gs, location_t location)
+{
+ if (!gimple_has_location (gs)
+ && !gimple_do_not_emit_location_p (gs)
+ && should_carry_location_p (gs))
+ gimple_set_location (gs, location);
+}
+
+/* Set LOCATION for all the statements after iterator GSI in sequence
+ SEQ. If GSI is pointing to the end of the sequence, start with the
+ first statement in SEQ. */
+
+void
+annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi,
+ location_t location)
+{
+ if (gsi_end_p (gsi))
+ gsi = gsi_start (seq);
+ else
+ gsi_next (&gsi);
+
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ annotate_one_with_location (gsi_stmt (gsi), location);
+}
+
+/* Set the location for all the statements in a sequence STMT_P to LOCATION. */
+
+void
+annotate_all_with_location (gimple_seq stmt_p, location_t location)
+{
+ gimple_stmt_iterator i;
+
+ if (gimple_seq_empty_p (stmt_p))
+ return;
+
+ for (i = gsi_start (stmt_p); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple gs = gsi_stmt (i);
+ annotate_one_with_location (gs, location);
+ }
+}
/* Helper function of empty_body_p. Return true if STMT is an empty
statement. */
@@ -1239,600 +1300,6 @@ gimple_seq_copy (gimple_seq src)
}
-/* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
- on each one. WI is as in walk_gimple_stmt.
-
- If walk_gimple_stmt returns non-NULL, the walk is stopped, and the
- value is stored in WI->CALLBACK_RESULT. Also, the statement that
- produced the value is returned if this statement has not been
- removed by a callback (wi->removed_stmt). If the statement has
- been removed, NULL is returned.
-
- Otherwise, all the statements are walked and NULL returned. */
-
-gimple
-walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
- walk_tree_fn callback_op, struct walk_stmt_info *wi)
-{
- gimple_stmt_iterator gsi;
-
- for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); )
- {
- tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
- if (ret)
- {
- /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist
- to hold it. */
- gcc_assert (wi);
- wi->callback_result = ret;
-
- return wi->removed_stmt ? NULL : gsi_stmt (gsi);
- }
-
- if (!wi->removed_stmt)
- gsi_next (&gsi);
- }
-
- if (wi)
- wi->callback_result = NULL_TREE;
-
- return NULL;
-}
-
-
-/* Like walk_gimple_seq_mod, but ensure that the head of SEQ isn't
- changed by the callbacks. */
-
-gimple
-walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
- walk_tree_fn callback_op, struct walk_stmt_info *wi)
-{
- gimple_seq seq2 = seq;
- gimple ret = walk_gimple_seq_mod (&seq2, callback_stmt, callback_op, wi);
- gcc_assert (seq2 == seq);
- return ret;
-}
-
-
-/* Helper function for walk_gimple_stmt. Walk operands of a GIMPLE_ASM. */
-
-static tree
-walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
- struct walk_stmt_info *wi)
-{
- tree ret, op;
- unsigned noutputs;
- const char **oconstraints;
- unsigned i, n;
- const char *constraint;
- bool allows_mem, allows_reg, is_inout;
-
- noutputs = gimple_asm_noutputs (stmt);
- oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
-
- if (wi)
- wi->is_lhs = true;
-
- for (i = 0; i < noutputs; i++)
- {
- op = gimple_asm_output_op (stmt, i);
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
- oconstraints[i] = constraint;
- parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg,
- &is_inout);
- if (wi)
- wi->val_only = (allows_reg || !allows_mem);
- ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
- if (ret)
- return ret;
- }
-
- n = gimple_asm_ninputs (stmt);
- for (i = 0; i < n; i++)
- {
- op = gimple_asm_input_op (stmt, i);
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
- parse_input_constraint (&constraint, 0, 0, noutputs, 0,
- oconstraints, &allows_mem, &allows_reg);
- if (wi)
- {
- wi->val_only = (allows_reg || !allows_mem);
- /* Although input "m" is not really a LHS, we need a lvalue. */
- wi->is_lhs = !wi->val_only;
- }
- ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
- if (ret)
- return ret;
- }
-
- if (wi)
- {
- wi->is_lhs = false;
- wi->val_only = true;
- }
-
- n = gimple_asm_nlabels (stmt);
- for (i = 0; i < n; i++)
- {
- op = gimple_asm_label_op (stmt, i);
- ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
- if (ret)
- return ret;
- }
-
- return NULL_TREE;
-}
-
-
-/* Helper function of WALK_GIMPLE_STMT. Walk every tree operand in
- STMT. CALLBACK_OP and WI are as in WALK_GIMPLE_STMT.
-
- CALLBACK_OP is called on each operand of STMT via walk_tree.
- Additional parameters to walk_tree must be stored in WI. For each operand
- OP, walk_tree is called as:
-
- walk_tree (&OP, CALLBACK_OP, WI, WI->PSET)
-
- If CALLBACK_OP returns non-NULL for an operand, the remaining
- operands are not scanned.
-
- The return value is that returned by the last call to walk_tree, or
- NULL_TREE if no CALLBACK_OP is specified. */
-
-tree
-walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
- struct walk_stmt_info *wi)
-{
- struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
- unsigned i;
- tree ret = NULL_TREE;
-
- switch (gimple_code (stmt))
- {
- case GIMPLE_ASSIGN:
- /* Walk the RHS operands. If the LHS is of a non-renamable type or
- is a register variable, we may use a COMPONENT_REF on the RHS. */
- if (wi)
- {
- tree lhs = gimple_assign_lhs (stmt);
- wi->val_only
- = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs))
- || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
- }
-
- for (i = 1; i < gimple_num_ops (stmt); i++)
- {
- ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi,
- pset);
- if (ret)
- return ret;
- }
-
- /* Walk the LHS. If the RHS is appropriate for a memory, we
- may use a COMPONENT_REF on the LHS. */
- if (wi)
- {
- /* If the RHS is of a non-renamable type or is a register variable,
- we may use a COMPONENT_REF on the LHS. */
- tree rhs1 = gimple_assign_rhs1 (stmt);
- wi->val_only
- = (is_gimple_reg_type (TREE_TYPE (rhs1)) && !is_gimple_reg (rhs1))
- || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
- wi->is_lhs = true;
- }
-
- ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset);
- if (ret)
- return ret;
-
- if (wi)
- {
- wi->val_only = true;
- wi->is_lhs = false;
- }
- break;
-
- case GIMPLE_CALL:
- if (wi)
- {
- wi->is_lhs = false;
- wi->val_only = true;
- }
-
- ret = walk_tree (gimple_call_chain_ptr (stmt), callback_op, wi, pset);
- if (ret)
- return ret;
-
- ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset);
- if (ret)
- return ret;
-
- for (i = 0; i < gimple_call_num_args (stmt); i++)
- {
- if (wi)
- wi->val_only
- = is_gimple_reg_type (TREE_TYPE (gimple_call_arg (stmt, i)));
- ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
- pset);
- if (ret)
- return ret;
- }
-
- if (gimple_call_lhs (stmt))
- {
- if (wi)
- {
- wi->is_lhs = true;
- wi->val_only
- = is_gimple_reg_type (TREE_TYPE (gimple_call_lhs (stmt)));
- }
-
- ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
- if (ret)
- return ret;
- }
-
- if (wi)
- {
- wi->is_lhs = false;
- wi->val_only = true;
- }
- break;
-
- case GIMPLE_CATCH:
- ret = walk_tree (gimple_catch_types_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_EH_FILTER:
- ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_ASM:
- ret = walk_gimple_asm (stmt, callback_op, wi);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_CONTINUE:
- ret = walk_tree (gimple_omp_continue_control_def_ptr (stmt),
- callback_op, wi, pset);
- if (ret)
- return ret;
-
- ret = walk_tree (gimple_omp_continue_control_use_ptr (stmt),
- callback_op, wi, pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_CRITICAL:
- ret = walk_tree (gimple_omp_critical_name_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_FOR:
- ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
- {
- ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op,
- wi, pset);
- }
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_PARALLEL:
- ret = walk_tree (gimple_omp_parallel_clauses_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_parallel_child_fn_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_parallel_data_arg_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_TASK:
- ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_SECTIONS:
- ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
-
- ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
-
- break;
-
- case GIMPLE_OMP_SINGLE:
- ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_TARGET:
- ret = walk_tree (gimple_omp_target_clauses_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_TEAMS:
- ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_ATOMIC_LOAD:
- ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
-
- ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_ATOMIC_STORE:
- ret = walk_tree (gimple_omp_atomic_store_val_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_TRANSACTION:
- ret = walk_tree (gimple_transaction_label_ptr (stmt), callback_op,
- wi, pset);
- if (ret)
- return ret;
- break;
-
- case GIMPLE_OMP_RETURN:
- ret = walk_tree (gimple_omp_return_lhs_ptr (stmt), callback_op, wi,
- pset);
- if (ret)
- return ret;
- break;
-
- /* Tuples that do not have operands. */
- case GIMPLE_NOP:
- case GIMPLE_RESX:
- case GIMPLE_PREDICT:
- break;
-
- default:
- {
- enum gimple_statement_structure_enum gss;
- gss = gimple_statement_structure (stmt);
- if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
- for (i = 0; i < gimple_num_ops (stmt); i++)
- {
- ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset);
- if (ret)
- return ret;
- }
- }
- break;
- }
-
- return NULL_TREE;
-}
-
-
-/* Walk the current statement in GSI (optionally using traversal state
- stored in WI). If WI is NULL, no state is kept during traversal.
- The callback CALLBACK_STMT is called. If CALLBACK_STMT indicates
- that it has handled all the operands of the statement, its return
- value is returned. Otherwise, the return value from CALLBACK_STMT
- is discarded and its operands are scanned.
-
- If CALLBACK_STMT is NULL or it didn't handle the operands,
- CALLBACK_OP is called on each operand of the statement via
- walk_gimple_op. If walk_gimple_op returns non-NULL for any
- operand, the remaining operands are not scanned. In this case, the
- return value from CALLBACK_OP is returned.
-
- In any other case, NULL_TREE is returned. */
-
-tree
-walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
- walk_tree_fn callback_op, struct walk_stmt_info *wi)
-{
- gimple ret;
- tree tree_ret;
- gimple stmt = gsi_stmt (*gsi);
-
- if (wi)
- {
- wi->gsi = *gsi;
- wi->removed_stmt = false;
-
- if (wi->want_locations && gimple_has_location (stmt))
- input_location = gimple_location (stmt);
- }
-
- ret = NULL;
-
- /* Invoke the statement callback. Return if the callback handled
- all of STMT operands by itself. */
- if (callback_stmt)
- {
- bool handled_ops = false;
- tree_ret = callback_stmt (gsi, &handled_ops, wi);
- if (handled_ops)
- return tree_ret;
-
- /* If CALLBACK_STMT did not handle operands, it should not have
- a value to return. */
- gcc_assert (tree_ret == NULL);
-
- if (wi && wi->removed_stmt)
- return NULL;
-
- /* Re-read stmt in case the callback changed it. */
- stmt = gsi_stmt (*gsi);
- }
-
- /* If CALLBACK_OP is defined, invoke it on every operand of STMT. */
- if (callback_op)
- {
- tree_ret = walk_gimple_op (stmt, callback_op, wi);
- if (tree_ret)
- return tree_ret;
- }
-
- /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them. */
- switch (gimple_code (stmt))
- {
- case GIMPLE_BIND:
- ret = walk_gimple_seq_mod (gimple_bind_body_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_CATCH:
- ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_EH_FILTER:
- ret = walk_gimple_seq_mod (gimple_eh_filter_failure_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_EH_ELSE:
- ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (stmt),
- callback_stmt, callback_op, wi);
- if (ret)
- return wi->callback_result;
- ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (stmt),
- callback_stmt, callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_TRY:
- ret = walk_gimple_seq_mod (gimple_try_eval_ptr (stmt), callback_stmt, callback_op,
- wi);
- if (ret)
- return wi->callback_result;
-
- ret = walk_gimple_seq_mod (gimple_try_cleanup_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_OMP_FOR:
- ret = walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
-
- /* FALL THROUGH. */
- case GIMPLE_OMP_CRITICAL:
- case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_TASKGROUP:
- case GIMPLE_OMP_ORDERED:
- case GIMPLE_OMP_SECTION:
- case GIMPLE_OMP_PARALLEL:
- case GIMPLE_OMP_TASK:
- case GIMPLE_OMP_SECTIONS:
- case GIMPLE_OMP_SINGLE:
- case GIMPLE_OMP_TARGET:
- case GIMPLE_OMP_TEAMS:
- ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_WITH_CLEANUP_EXPR:
- ret = walk_gimple_seq_mod (gimple_wce_cleanup_ptr (stmt), callback_stmt,
- callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- case GIMPLE_TRANSACTION:
- ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
- callback_stmt, callback_op, wi);
- if (ret)
- return wi->callback_result;
- break;
-
- default:
- gcc_assert (!gimple_has_substatements (stmt));
- break;
- }
-
- return NULL;
-}
-
/* Return true if calls C1 and C2 are known to go to the same function. */
@@ -2938,251 +2405,6 @@ gimple_get_alias_set (tree t)
}
-/* From a tree operand OP return the base of a load or store operation
- or NULL_TREE if OP is not a load or a store. */
-
-static tree
-get_base_loadstore (tree op)
-{
- while (handled_component_p (op))
- op = TREE_OPERAND (op, 0);
- if (DECL_P (op)
- || INDIRECT_REF_P (op)
- || TREE_CODE (op) == MEM_REF
- || TREE_CODE (op) == TARGET_MEM_REF)
- return op;
- return NULL_TREE;
-}
-
-/* For the statement STMT call the callbacks VISIT_LOAD, VISIT_STORE and
- VISIT_ADDR if non-NULL on loads, store and address-taken operands
- passing the STMT, the base of the operand and DATA to it. The base
- will be either a decl, an indirect reference (including TARGET_MEM_REF)
- or the argument of an address expression.
- Returns the results of these callbacks or'ed. */
-
-bool
-walk_stmt_load_store_addr_ops (gimple stmt, void *data,
- bool (*visit_load)(gimple, tree, void *),
- bool (*visit_store)(gimple, tree, void *),
- bool (*visit_addr)(gimple, tree, void *))
-{
- bool ret = false;
- unsigned i;
- if (gimple_assign_single_p (stmt))
- {
- tree lhs, rhs;
- if (visit_store)
- {
- lhs = get_base_loadstore (gimple_assign_lhs (stmt));
- if (lhs)
- ret |= visit_store (stmt, lhs, data);
- }
- rhs = gimple_assign_rhs1 (stmt);
- while (handled_component_p (rhs))
- rhs = TREE_OPERAND (rhs, 0);
- if (visit_addr)
- {
- if (TREE_CODE (rhs) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
- else if (TREE_CODE (rhs) == TARGET_MEM_REF
- && TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
- else if (TREE_CODE (rhs) == OBJ_TYPE_REF
- && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs),
- 0), data);
- else if (TREE_CODE (rhs) == CONSTRUCTOR)
- {
- unsigned int ix;
- tree val;
-
- FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), ix, val)
- if (TREE_CODE (val) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (val, 0), data);
- else if (TREE_CODE (val) == OBJ_TYPE_REF
- && TREE_CODE (OBJ_TYPE_REF_OBJECT (val)) == ADDR_EXPR)
- ret |= visit_addr (stmt,
- TREE_OPERAND (OBJ_TYPE_REF_OBJECT (val),
- 0), data);
- }
- lhs = gimple_assign_lhs (stmt);
- if (TREE_CODE (lhs) == TARGET_MEM_REF
- && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
- }
- if (visit_load)
- {
- rhs = get_base_loadstore (rhs);
- if (rhs)
- ret |= visit_load (stmt, rhs, data);
- }
- }
- else if (visit_addr
- && (is_gimple_assign (stmt)
- || gimple_code (stmt) == GIMPLE_COND))
- {
- for (i = 0; i < gimple_num_ops (stmt); ++i)
- {
- tree op = gimple_op (stmt, i);
- if (op == NULL_TREE)
- ;
- else if (TREE_CODE (op) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
- /* COND_EXPR and VCOND_EXPR rhs1 argument is a comparison
- tree with two operands. */
- else if (i == 1 && COMPARISON_CLASS_P (op))
- {
- if (TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 0),
- 0), data);
- if (TREE_CODE (TREE_OPERAND (op, 1)) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 1),
- 0), data);
- }
- }
- }
- else if (is_gimple_call (stmt))
- {
- if (visit_store)
- {
- tree lhs = gimple_call_lhs (stmt);
- if (lhs)
- {
- lhs = get_base_loadstore (lhs);
- if (lhs)
- ret |= visit_store (stmt, lhs, data);
- }
- }
- if (visit_load || visit_addr)
- for (i = 0; i < gimple_call_num_args (stmt); ++i)
- {
- tree rhs = gimple_call_arg (stmt, i);
- if (visit_addr
- && TREE_CODE (rhs) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
- else if (visit_load)
- {
- rhs = get_base_loadstore (rhs);
- if (rhs)
- ret |= visit_load (stmt, rhs, data);
- }
- }
- if (visit_addr
- && gimple_call_chain (stmt)
- && TREE_CODE (gimple_call_chain (stmt)) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (stmt), 0),
- data);
- if (visit_addr
- && gimple_call_return_slot_opt_p (stmt)
- && gimple_call_lhs (stmt) != NULL_TREE
- && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
- ret |= visit_addr (stmt, gimple_call_lhs (stmt), data);
- }
- else if (gimple_code (stmt) == GIMPLE_ASM)
- {
- unsigned noutputs;
- const char *constraint;
- const char **oconstraints;
- bool allows_mem, allows_reg, is_inout;
- noutputs = gimple_asm_noutputs (stmt);
- oconstraints = XALLOCAVEC (const char *, noutputs);
- if (visit_store || visit_addr)
- for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
- {
- tree link = gimple_asm_output_op (stmt, i);
- tree op = get_base_loadstore (TREE_VALUE (link));
- if (op && visit_store)
- ret |= visit_store (stmt, op, data);
- if (visit_addr)
- {
- constraint = TREE_STRING_POINTER
- (TREE_VALUE (TREE_PURPOSE (link)));
- oconstraints[i] = constraint;
- parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
- &allows_reg, &is_inout);
- if (op && !allows_reg && allows_mem)
- ret |= visit_addr (stmt, op, data);
- }
- }
- if (visit_load || visit_addr)
- for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
- {
- tree link = gimple_asm_input_op (stmt, i);
- tree op = TREE_VALUE (link);
- if (visit_addr
- && TREE_CODE (op) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
- else if (visit_load || visit_addr)
- {
- op = get_base_loadstore (op);
- if (op)
- {
- if (visit_load)
- ret |= visit_load (stmt, op, data);
- if (visit_addr)
- {
- constraint = TREE_STRING_POINTER
- (TREE_VALUE (TREE_PURPOSE (link)));
- parse_input_constraint (&constraint, 0, 0, noutputs,
- 0, oconstraints,
- &allows_mem, &allows_reg);
- if (!allows_reg && allows_mem)
- ret |= visit_addr (stmt, op, data);
- }
- }
- }
- }
- }
- else if (gimple_code (stmt) == GIMPLE_RETURN)
- {
- tree op = gimple_return_retval (stmt);
- if (op)
- {
- if (visit_addr
- && TREE_CODE (op) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
- else if (visit_load)
- {
- op = get_base_loadstore (op);
- if (op)
- ret |= visit_load (stmt, op, data);
- }
- }
- }
- else if (visit_addr
- && gimple_code (stmt) == GIMPLE_PHI)
- {
- for (i = 0; i < gimple_phi_num_args (stmt); ++i)
- {
- tree op = gimple_phi_arg_def (stmt, i);
- if (TREE_CODE (op) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
- }
- }
- else if (visit_addr
- && gimple_code (stmt) == GIMPLE_GOTO)
- {
- tree op = gimple_goto_dest (stmt);
- if (TREE_CODE (op) == ADDR_EXPR)
- ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
- }
-
- return ret;
-}
-
-/* Like walk_stmt_load_store_addr_ops but with NULL visit_addr. IPA-CP
- should make a faster clone for this case. */
-
-bool
-walk_stmt_load_store_ops (gimple stmt, void *data,
- bool (*visit_load)(gimple, tree, void *),
- bool (*visit_store)(gimple, tree, void *))
-{
- return walk_stmt_load_store_addr_ops (stmt, data,
- visit_load, visit_store, NULL);
-}
-
/* Helper for gimple_ior_addresses_taken_1. */
static bool
@@ -3428,3 +2650,210 @@ infer_nonnull_range (gimple stmt, tree op)
return false;
}
+
+/* Compare two case labels. Because the front end should already have
+ made sure that case ranges do not overlap, it is enough to only compare
+ the CASE_LOW values of each case label. */
+
+static int
+compare_case_labels (const void *p1, const void *p2)
+{
+ const_tree const case1 = *(const_tree const*)p1;
+ const_tree const case2 = *(const_tree const*)p2;
+
+ /* The 'default' case label always goes first. */
+ if (!CASE_LOW (case1))
+ return -1;
+ else if (!CASE_LOW (case2))
+ return 1;
+ else
+ return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
+}
+
+/* Sort the case labels in LABEL_VEC in place in ascending order. */
+
+void
+sort_case_labels (vec<tree> label_vec)
+{
+ label_vec.qsort (compare_case_labels);
+}
+
+/* Prepare a vector of case labels to be used in a GIMPLE_SWITCH statement.
+
+ LABELS is a vector that contains all case labels to look at.
+
+ INDEX_TYPE is the type of the switch index expression. Case labels
+ in LABELS are discarded if their values are not in the value range
+ covered by INDEX_TYPE. The remaining case label values are folded
+ to INDEX_TYPE.
+
+ If a default case exists in LABELS, it is removed from LABELS and
+ returned in DEFAULT_CASEP. If no default case exists, but the
+ case labels already cover the whole range of INDEX_TYPE, a default
+ case is returned pointing to one of the existing case labels.
+ Otherwise DEFAULT_CASEP is set to NULL_TREE.
+
+ DEFAULT_CASEP may be NULL, in which case the above comment doesn't
+ apply and no action is taken regardless of whether a default case is
+ found or not. */
+
+void
+preprocess_case_label_vec_for_gimple (vec<tree> labels,
+ tree index_type,
+ tree *default_casep)
+{
+ tree min_value, max_value;
+ tree default_case = NULL_TREE;
+ size_t i, len;
+
+ i = 0;
+ min_value = TYPE_MIN_VALUE (index_type);
+ max_value = TYPE_MAX_VALUE (index_type);
+ while (i < labels.length ())
+ {
+ tree elt = labels[i];
+ tree low = CASE_LOW (elt);
+ tree high = CASE_HIGH (elt);
+ bool remove_element = FALSE;
+
+ if (low)
+ {
+ gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
+ gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
+
+ /* This is a non-default case label, i.e. it has a value.
+
+ See if the case label is reachable within the range of
+ the index type. Remove out-of-range case values. Turn
+ case ranges into a canonical form (high > low strictly)
+ and convert the case label values to the index type.
+
+ NB: The type of gimple_switch_index() may be the promoted
+ type, but the case labels retain the original type. */
+
+ if (high)
+ {
+ /* This is a case range. Discard empty ranges.
+ If the bounds or the range are equal, turn this
+ into a simple (one-value) case. */
+ int cmp = tree_int_cst_compare (high, low);
+ if (cmp < 0)
+ remove_element = TRUE;
+ else if (cmp == 0)
+ high = NULL_TREE;
+ }
+
+ if (! high)
+ {
+ /* If the simple case value is unreachable, ignore it. */
+ if ((TREE_CODE (min_value) == INTEGER_CST
+ && tree_int_cst_compare (low, min_value) < 0)
+ || (TREE_CODE (max_value) == INTEGER_CST
+ && tree_int_cst_compare (low, max_value) > 0))
+ remove_element = TRUE;
+ else
+ low = fold_convert (index_type, low);
+ }
+ else
+ {
+ /* If the entire case range is unreachable, ignore it. */
+ if ((TREE_CODE (min_value) == INTEGER_CST
+ && tree_int_cst_compare (high, min_value) < 0)
+ || (TREE_CODE (max_value) == INTEGER_CST
+ && tree_int_cst_compare (low, max_value) > 0))
+ remove_element = TRUE;
+ else
+ {
+ /* If the lower bound is less than the index type's
+ minimum value, truncate the range bounds. */
+ if (TREE_CODE (min_value) == INTEGER_CST
+ && tree_int_cst_compare (low, min_value) < 0)
+ low = min_value;
+ low = fold_convert (index_type, low);
+
+ /* If the upper bound is greater than the index type's
+ maximum value, truncate the range bounds. */
+ if (TREE_CODE (max_value) == INTEGER_CST
+ && tree_int_cst_compare (high, max_value) > 0)
+ high = max_value;
+ high = fold_convert (index_type, high);
+
+ /* We may have folded a case range to a one-value case. */
+ if (tree_int_cst_equal (low, high))
+ high = NULL_TREE;
+ }
+ }
+
+ CASE_LOW (elt) = low;
+ CASE_HIGH (elt) = high;
+ }
+ else
+ {
+ gcc_assert (!default_case);
+ default_case = elt;
+ /* The default case must be passed separately to the
+ gimple_build_switch routine. But if DEFAULT_CASEP
+ is NULL, we do not remove the default case (it would
+ be completely lost). */
+ if (default_casep)
+ remove_element = TRUE;
+ }
+
+ if (remove_element)
+ labels.ordered_remove (i);
+ else
+ i++;
+ }
+ len = i;
+
+ if (!labels.is_empty ())
+ sort_case_labels (labels);
+
+ if (default_casep && !default_case)
+ {
+ /* If the switch has no default label, add one, so that we jump
+ around the switch body. If the labels already cover the whole
+ range of the switch index_type, add the default label pointing
+ to one of the existing labels. */
+ if (len
+ && TYPE_MIN_VALUE (index_type)
+ && TYPE_MAX_VALUE (index_type)
+ && tree_int_cst_equal (CASE_LOW (labels[0]),
+ TYPE_MIN_VALUE (index_type)))
+ {
+ tree low, high = CASE_HIGH (labels[len - 1]);
+ if (!high)
+ high = CASE_LOW (labels[len - 1]);
+ if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
+ {
+ for (i = 1; i < len; i++)
+ {
+ high = CASE_LOW (labels[i]);
+ low = CASE_HIGH (labels[i - 1]);
+ if (!low)
+ low = CASE_LOW (labels[i - 1]);
+ if (wi::add (low, 1) != high)
+ break;
+ }
+ if (i == len)
+ {
+ tree label = CASE_LABEL (labels[0]);
+ default_case = build_case_label (NULL_TREE, NULL_TREE,
+ label);
+ }
+ }
+ }
+ }
+
+ if (default_casep)
+ *default_casep = default_case;
+}
+
+/* Set the location of all statements in SEQ to LOC. */
+
+void
+gimple_seq_set_location (gimple_seq seq, location_t loc)
+{
+ for (gimple_stmt_iterator i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ gimple_set_location (gsi_stmt (i), loc);
+}
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 33e790c18da..c7cb9f75d18 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -102,12 +102,13 @@ enum gf_mask {
GF_CALL_ALLOCA_FOR_VAR = 1 << 5,
GF_CALL_INTERNAL = 1 << 6,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
- GF_OMP_FOR_KIND_MASK = 3 << 0,
+ GF_OMP_FOR_KIND_MASK = 7,
GF_OMP_FOR_KIND_FOR = 0 << 0,
- GF_OMP_FOR_KIND_SIMD = 1 << 0,
- GF_OMP_FOR_KIND_DISTRIBUTE = 2 << 0,
- GF_OMP_FOR_COMBINED = 1 << 2,
- GF_OMP_FOR_COMBINED_INTO = 1 << 3,
+ GF_OMP_FOR_KIND_SIMD = 2 << 0,
+ GF_OMP_FOR_KIND_CILKSIMD = 3 << 0,
+ GF_OMP_FOR_KIND_DISTRIBUTE = 1 << 2,
+ GF_OMP_FOR_COMBINED = 1 << 3,
+ GF_OMP_FOR_COMBINED_INTO = 1 << 4,
GF_OMP_TARGET_KIND_MASK = 3 << 0,
GF_OMP_TARGET_KIND_REGION = 0 << 0,
GF_OMP_TARGET_KIND_DATA = 1 << 0,
@@ -141,21 +142,6 @@ enum plf_mask {
GF_PLF_2 = 1 << 1
};
-/* Iterator object for GIMPLE statement sequences. */
-
-struct gimple_stmt_iterator_d
-{
- /* Sequence node holding the current statement. */
- gimple_seq_node ptr;
-
- /* Sequence and basic block holding the statement. These fields
- are necessary to handle edge cases such as when statement is
- added to an empty basic block or when the last statement of a
- block/sequence is removed. */
- gimple_seq *seq;
- basic_block bb;
-};
-
/* Data structure definitions for GIMPLE tuples. NOTE: word markers
are for 64 bit hosts. */
@@ -766,7 +752,6 @@ gimple gimple_build_call_valist (tree, unsigned, va_list);
gimple gimple_build_call_internal (enum internal_fn, unsigned, ...);
gimple gimple_build_call_internal_vec (enum internal_fn, vec<tree> );
gimple gimple_build_call_from_tree (tree);
-gimple gimplify_assign (tree, tree, gimple_seq *);
gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
gimple gimple_build_label (tree label);
gimple gimple_build_goto (tree dest);
@@ -806,8 +791,6 @@ gimple gimple_build_omp_atomic_store (tree);
gimple gimple_build_transaction (gimple_seq, tree);
gimple gimple_build_predict (enum br_predictor, enum prediction);
enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
-void sort_case_labels (vec<tree> );
-void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
gimple_seq gimple_seq_alloc (void);
void gimple_seq_free (gimple_seq);
void gimple_seq_add_seq (gimple_seq *, gimple_seq);
@@ -834,8 +817,10 @@ bool gimple_has_side_effects (const_gimple);
bool gimple_could_trap_p (gimple);
bool gimple_could_trap_p_1 (gimple, bool, bool);
bool gimple_assign_rhs_could_trap_p (gimple);
-void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
bool empty_body_p (gimple_seq);
+extern void annotate_all_with_location_after (gimple_seq, gimple_stmt_iterator,
+ location_t);
+extern void annotate_all_with_location (gimple_seq, location_t);
unsigned get_gimple_rhs_num_ops (enum tree_code);
#define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
@@ -848,59 +833,12 @@ extern bool gimple_compare_field_offset (tree, tree);
extern tree gimple_unsigned_type (tree);
extern tree gimple_signed_type (tree);
extern alias_set_type gimple_get_alias_set (tree);
-extern bool walk_stmt_load_store_addr_ops (gimple, void *,
- bool (*)(gimple, tree, void *),
- bool (*)(gimple, tree, void *),
- bool (*)(gimple, tree, void *));
-extern bool walk_stmt_load_store_ops (gimple, void *,
- bool (*)(gimple, tree, void *),
- bool (*)(gimple, tree, void *));
extern bool gimple_ior_addresses_taken (bitmap, gimple);
extern bool gimple_call_builtin_p (gimple, enum built_in_class);
extern bool gimple_call_builtin_p (gimple, enum built_in_function);
extern bool gimple_asm_clobbers_memory_p (const_gimple);
-
-/* In gimplify.c */
-extern tree create_tmp_var_raw (tree, const char *);
-extern tree create_tmp_var_name (const char *);
-extern tree create_tmp_var (tree, const char *);
-extern tree create_tmp_reg (tree, const char *);
-extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
-extern tree get_formal_tmp_var (tree, gimple_seq *);
-extern void declare_vars (tree, gimple, bool);
-extern void annotate_all_with_location (gimple_seq, location_t);
extern unsigned gimple_call_get_nobnd_arg_index (const_gimple, unsigned);
-/* Validation of GIMPLE expressions. Note that these predicates only check
- the basic form of the expression, they don't recurse to make sure that
- underlying nodes are also of the right form. */
-typedef bool (*gimple_predicate)(tree);
-
-
-/* FIXME we should deduce this from the predicate. */
-enum fallback {
- fb_none = 0, /* Do not generate a temporary. */
-
- fb_rvalue = 1, /* Generate an rvalue to hold the result of a
- gimplified expression. */
-
- fb_lvalue = 2, /* Generate an lvalue to hold the result of a
- gimplified expression. */
-
- fb_mayfail = 4, /* Gimplification may fail. Error issued
- afterwards. */
- fb_either= fb_rvalue | fb_lvalue
-};
-
-typedef int fallback_t;
-
-enum gimplify_status {
- GS_ERROR = -2, /* Something Bad Seen. */
- GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
- GS_OK = 0, /* We did something, maybe more to do. */
- GS_ALL_DONE = 1 /* The expression is fully gimplified. */
-};
-
/* Formal (expression) temporary table handling: multiple occurrences of
the same scalar expression are evaluated into the same temporary. */
@@ -910,85 +848,6 @@ typedef struct gimple_temp_hash_elt
tree temp; /* Value */
} elt_t;
-/* Gimplify hashtable helper. */
-
-struct gimplify_hasher : typed_free_remove <elt_t>
-{
- typedef elt_t value_type;
- typedef elt_t compare_type;
- static inline hashval_t hash (const value_type *);
- static inline bool equal (const value_type *, const compare_type *);
-};
-
-inline hashval_t
-gimplify_hasher::hash (const value_type *p)
-{
- tree t = p->val;
- return iterative_hash_expr (t, 0);
-}
-
-inline bool
-gimplify_hasher::equal (const value_type *p1, const compare_type *p2)
-{
- tree t1 = p1->val;
- tree t2 = p2->val;
- enum tree_code code = TREE_CODE (t1);
-
- if (TREE_CODE (t2) != code
- || TREE_TYPE (t1) != TREE_TYPE (t2))
- return false;
-
- if (!operand_equal_p (t1, t2, 0))
- return false;
-
-#ifdef ENABLE_CHECKING
- /* Only allow them to compare equal if they also hash equal; otherwise
- results are nondeterminate, and we fail bootstrap comparison. */
- gcc_assert (hash (p1) == hash (p2));
-#endif
-
- return true;
-}
-
-struct gimplify_ctx
-{
- struct gimplify_ctx *prev_context;
-
- vec<gimple> bind_expr_stack;
- tree temps;
- gimple_seq conditional_cleanups;
- tree exit_label;
- tree return_temp;
-
- vec<tree> case_labels;
- /* The formal temporary table. Should this be persistent? */
- hash_table <gimplify_hasher> temp_htab;
-
- int conditions;
- bool save_stack;
- bool into_ssa;
- bool allow_rhs_cond_expr;
- bool in_cleanup_point_expr;
-};
-
-/* Return true if gimplify_one_sizepos doesn't need to gimplify
- expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
- fields). */
-static inline bool
-is_gimple_sizepos (tree expr)
-{
- /* gimplify_one_sizepos doesn't need to do anything if the value isn't there,
- is constant, or contains A PLACEHOLDER_EXPR. We also don't want to do
- anything if it's already a VAR_DECL. If it's a VAR_DECL from another
- function, the gimplifier will want to replace it with a new variable,
- but that will cause problems if this type is from outside the function.
- It's OK to have that here. */
- return (expr == NULL_TREE
- || TREE_CONSTANT (expr)
- || TREE_CODE (expr) == VAR_DECL
- || CONTAINS_PLACEHOLDER_P (expr));
-}
-
/* Get the number of the next statement uid to be allocated. */
static inline unsigned int
gimple_stmt_max_uid (struct function *fn)
@@ -1010,31 +869,7 @@ inc_gimple_stmt_max_uid (struct function *fn)
return fn->last_stmt_uid++;
}
-extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
- bool (*) (tree), fallback_t);
-extern void gimplify_type_sizes (tree, gimple_seq *);
-extern void gimplify_one_sizepos (tree *, gimple_seq *);
-enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *, gimple_seq *,
- bool, tree);
-extern bool gimplify_stmt (tree *, gimple_seq *);
-extern gimple gimplify_body (tree, bool);
-extern void push_gimplify_context (struct gimplify_ctx *);
-extern void pop_gimplify_context (gimple);
-extern void gimplify_and_add (tree, gimple_seq *);
-
/* Miscellaneous helpers. */
-extern void gimple_add_tmp_var (tree);
-extern gimple gimple_current_bind_expr (void);
-extern vec<gimple> gimple_bind_expr_stack (void);
-extern tree voidify_wrapper_expr (tree, tree);
-extern tree build_and_jump (tree *);
-extern tree force_labels_r (tree *, int *, void *);
-extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
- gimple_seq *);
-struct gimplify_omp_ctx;
-extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
-extern tree gimple_boolify (tree);
-extern gimple_predicate rhs_predicate_for (tree);
extern tree canonicalize_cond_expr_cond (tree);
extern void dump_decl_set (FILE *, bitmap);
extern bool nonfreeing_call_p (gimple);
@@ -1043,14 +878,12 @@ extern bool infer_nonnull_range (gimple, tree);
/* In trans-mem.c. */
extern void diagnose_tm_safe_errors (tree);
extern void compute_transaction_bits (void);
+extern bool is_tm_ending (gimple);
/* In tree-nested.c. */
extern void lower_nested_functions (tree);
extern void insert_field_into_struct (tree, tree);
-/* In gimplify.c. */
-extern void gimplify_function_tree (tree);
-
/* In cfgexpand.c. */
extern tree gimple_assign_rhs_to_tree (gimple);
@@ -1121,14 +954,8 @@ gimple_seq_empty_p (gimple_seq s)
return s == NULL;
}
-void gimple_seq_add_stmt (gimple_seq *, gimple);
-
-/* Link gimple statement GS to the end of the sequence *SEQ_P. If
- *SEQ_P is NULL, a new sequence is allocated. This function is
- similar to gimple_seq_add_stmt, but does not scan the operands.
- During gimplification, we need to manipulate statement sequences
- before the def/use vectors have been constructed. */
-void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
+extern void gimple_seq_add_stmt (gimple_seq *, gimple);
+extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
/* Allocate a new sequence and initialize its first element with STMT. */
@@ -5296,352 +5123,8 @@ gimple_expr_type (const_gimple stmt)
return void_type_node;
}
-/* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
-
-static inline gimple_stmt_iterator
-gsi_start_1 (gimple_seq *seq)
-{
- gimple_stmt_iterator i;
-
- i.ptr = gimple_seq_first (*seq);
- i.seq = seq;
- i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
-
- return i;
-}
-
-#define gsi_start(x) gsi_start_1 (&(x))
-
-static inline gimple_stmt_iterator
-gsi_none (void)
-{
- gimple_stmt_iterator i;
- i.ptr = NULL;
- i.seq = NULL;
- i.bb = NULL;
- return i;
-}
-
-/* Return a new iterator pointing to the first statement in basic block BB. */
-
-static inline gimple_stmt_iterator
-gsi_start_bb (basic_block bb)
-{
- gimple_stmt_iterator i;
- gimple_seq *seq;
-
- seq = bb_seq_addr (bb);
- i.ptr = gimple_seq_first (*seq);
- i.seq = seq;
- i.bb = bb;
-
- return i;
-}
-
-
-/* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */
-
-static inline gimple_stmt_iterator
-gsi_last_1 (gimple_seq *seq)
-{
- gimple_stmt_iterator i;
-
- i.ptr = gimple_seq_last (*seq);
- i.seq = seq;
- i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
-
- return i;
-}
-
-#define gsi_last(x) gsi_last_1 (&(x))
-
-/* Return a new iterator pointing to the last statement in basic block BB. */
-
-static inline gimple_stmt_iterator
-gsi_last_bb (basic_block bb)
-{
- gimple_stmt_iterator i;
- gimple_seq *seq;
-
- seq = bb_seq_addr (bb);
- i.ptr = gimple_seq_last (*seq);
- i.seq = seq;
- i.bb = bb;
-
- return i;
-}
-
-
-/* Return true if I is at the end of its sequence. */
-
-static inline bool
-gsi_end_p (gimple_stmt_iterator i)
-{
- return i.ptr == NULL;
-}
-
-
-/* Return true if I is one statement before the end of its sequence. */
-
-static inline bool
-gsi_one_before_end_p (gimple_stmt_iterator i)
-{
- return i.ptr != NULL && i.ptr->gsbase.next == NULL;
-}
-
-
-/* Advance the iterator to the next gimple statement. */
-
-static inline void
-gsi_next (gimple_stmt_iterator *i)
-{
- i->ptr = i->ptr->gsbase.next;
-}
-
-/* Advance the iterator to the previous gimple statement. */
-
-static inline void
-gsi_prev (gimple_stmt_iterator *i)
-{
- gimple prev = i->ptr->gsbase.prev;
- if (prev->gsbase.next)
- i->ptr = prev;
- else
- i->ptr = NULL;
-}
-
-/* Return the current stmt. */
-
-static inline gimple
-gsi_stmt (gimple_stmt_iterator i)
-{
- return i.ptr;
-}
-
-/* Return a block statement iterator that points to the first non-label
- statement in block BB. */
-
-static inline gimple_stmt_iterator
-gsi_after_labels (basic_block bb)
-{
- gimple_stmt_iterator gsi = gsi_start_bb (bb);
-
- while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
- gsi_next (&gsi);
-
- return gsi;
-}
-
-/* Advance the iterator to the next non-debug gimple statement. */
-
-static inline void
-gsi_next_nondebug (gimple_stmt_iterator *i)
-{
- do
- {
- gsi_next (i);
- }
- while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
-}
-
-/* Advance the iterator to the next non-debug gimple statement. */
-
-static inline void
-gsi_prev_nondebug (gimple_stmt_iterator *i)
-{
- do
- {
- gsi_prev (i);
- }
- while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
-}
-
-/* Return a new iterator pointing to the first non-debug statement in
- basic block BB. */
-
-static inline gimple_stmt_iterator
-gsi_start_nondebug_bb (basic_block bb)
-{
- gimple_stmt_iterator i = gsi_start_bb (bb);
-
- if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
- gsi_next_nondebug (&i);
-
- return i;
-}
-
-/* Return a new iterator pointing to the first non-debug non-label statement in
- basic block BB. */
-
-static inline gimple_stmt_iterator
-gsi_start_nondebug_after_labels_bb (basic_block bb)
-{
- gimple_stmt_iterator i = gsi_after_labels (bb);
-
- if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
- gsi_next_nondebug (&i);
-
- return i;
-}
-
-/* Return a new iterator pointing to the last non-debug statement in
- basic block BB. */
-
-static inline gimple_stmt_iterator
-gsi_last_nondebug_bb (basic_block bb)
-{
- gimple_stmt_iterator i = gsi_last_bb (bb);
-
- if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
- gsi_prev_nondebug (&i);
-
- return i;
-}
-
-
-/* Return the basic block associated with this iterator. */
-
-static inline basic_block
-gsi_bb (gimple_stmt_iterator i)
-{
- return i.bb;
-}
-
-
-/* Return the sequence associated with this iterator. */
-
-static inline gimple_seq
-gsi_seq (gimple_stmt_iterator i)
-{
- return *i.seq;
-}
-
-
-enum gsi_iterator_update
-{
- GSI_NEW_STMT, /* Only valid when single statement is added, move
- iterator to it. */
- GSI_SAME_STMT, /* Leave the iterator at the same statement. */
- GSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable
- for linking other statements in the same
- direction. */
-};
-
-/* In gimple-iterator.c */
-gimple_stmt_iterator gsi_start_phis (basic_block);
-gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
-void gsi_split_seq_before (gimple_stmt_iterator *, gimple_seq *);
-void gsi_set_stmt (gimple_stmt_iterator *, gimple);
-void gsi_replace (gimple_stmt_iterator *, gimple, bool);
-void gsi_replace_with_seq (gimple_stmt_iterator *, gimple_seq, bool);
-void gsi_insert_before (gimple_stmt_iterator *, gimple,
- enum gsi_iterator_update);
-void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple,
- enum gsi_iterator_update);
-void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq,
- enum gsi_iterator_update);
-void gsi_insert_seq_before_without_update (gimple_stmt_iterator *, gimple_seq,
- enum gsi_iterator_update);
-void gsi_insert_after (gimple_stmt_iterator *, gimple,
- enum gsi_iterator_update);
-void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple,
- enum gsi_iterator_update);
-void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq,
- enum gsi_iterator_update);
-void gsi_insert_seq_after_without_update (gimple_stmt_iterator *, gimple_seq,
- enum gsi_iterator_update);
-bool gsi_remove (gimple_stmt_iterator *, bool);
-gimple_stmt_iterator gsi_for_stmt (gimple);
-void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
-void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
-void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
-void gsi_insert_on_edge (edge, gimple);
-void gsi_insert_seq_on_edge (edge, gimple_seq);
-basic_block gsi_insert_on_edge_immediate (edge, gimple);
-basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
-void gsi_commit_one_edge_insert (edge, basic_block *);
-void gsi_commit_edge_inserts (void);
gimple gimple_call_copy_skip_args (gimple, bitmap);
-/* In gimplify.c. */
-tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
-tree force_gimple_operand (tree, gimple_seq *, bool, tree);
-tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
- gimple_predicate, tree,
- bool, enum gsi_iterator_update);
-tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
- bool, enum gsi_iterator_update);
-
-/* Convenience routines to walk all statements of a gimple function.
- Note that this is useful exclusively before the code is converted
- into SSA form. Once the program is in SSA form, the standard
- operand interface should be used to analyze/modify statements. */
-struct walk_stmt_info
-{
- /* Points to the current statement being walked. */
- gimple_stmt_iterator gsi;
-
- /* Additional data that the callback functions may want to carry
- through the recursion. */
- void *info;
-
- /* Pointer map used to mark visited tree nodes when calling
- walk_tree on each operand. If set to NULL, duplicate tree nodes
- will be visited more than once. */
- struct pointer_set_t *pset;
-
- /* Operand returned by the callbacks. This is set when calling
- walk_gimple_seq. If the walk_stmt_fn or walk_tree_fn callback
- returns non-NULL, this field will contain the tree returned by
- the last callback. */
- tree callback_result;
-
- /* Indicates whether the operand being examined may be replaced
- with something that matches is_gimple_val (if true) or something
- slightly more complicated (if false). "Something" technically
- means the common subset of is_gimple_lvalue and is_gimple_rhs,
- but we never try to form anything more complicated than that, so
- we don't bother checking.
-
- Also note that CALLBACK should update this flag while walking the
- sub-expressions of a statement. For instance, when walking the
- statement 'foo (&var)', the flag VAL_ONLY will initially be set
- to true, however, when walking &var, the operand of that
- ADDR_EXPR does not need to be a GIMPLE value. */
- BOOL_BITFIELD val_only : 1;
-
- /* True if we are currently walking the LHS of an assignment. */
- BOOL_BITFIELD is_lhs : 1;
-
- /* Optional. Set to true by the callback functions if they made any
- changes. */
- BOOL_BITFIELD changed : 1;
-
- /* True if we're interested in location information. */
- BOOL_BITFIELD want_locations : 1;
-
- /* True if we've removed the statement that was processed. */
- BOOL_BITFIELD removed_stmt : 1;
-};
-
-/* Callback for walk_gimple_stmt. Called for every statement found
- during traversal. The first argument points to the statement to
- walk. The second argument is a flag that the callback sets to
- 'true' if it the callback handled all the operands and
- sub-statements of the statement (the default value of this flag is
- 'false'). The third argument is an anonymous pointer to data
- to be used by the callback. */
-typedef tree (*walk_stmt_fn) (gimple_stmt_iterator *, bool *,
- struct walk_stmt_info *);
-
-gimple walk_gimple_seq (gimple_seq, walk_stmt_fn, walk_tree_fn,
- struct walk_stmt_info *);
-gimple walk_gimple_seq_mod (gimple_seq *, walk_stmt_fn, walk_tree_fn,
- struct walk_stmt_info *);
-tree walk_gimple_stmt (gimple_stmt_iterator *, walk_stmt_fn, walk_tree_fn,
- struct walk_stmt_info *);
-tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *);
-
/* Enum and arrays used for allocation stats. Keep in sync with
gimple.c:gimple_alloc_kind_names. */
enum gimple_alloc_kind
@@ -5675,15 +5158,27 @@ gimple_alloc_kind (enum gimple_code code)
extern void dump_gimple_statistics (void);
-/* Set the location of all statements in SEQ to LOC. */
+/* Return true if a location should not be emitted for this statement
+ by annotate_all_with_location. */
+
+static inline bool
+gimple_do_not_emit_location_p (gimple g)
+{
+ return gimple_plf (g, GF_PLF_1);
+}
+
+/* Mark statement G so a location will not be emitted by
+ annotate_one_with_location. */
static inline void
-gimple_seq_set_location (gimple_seq seq, location_t loc)
+gimple_set_do_not_emit_location (gimple g)
{
- for (gimple_stmt_iterator i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
- gimple_set_location (gsi_stmt (i), loc);
+ /* The PLF flags are initialized to 0 when a new tuple is created,
+ so no need to initialize it anywhere. */
+ gimple_set_plf (g, GF_PLF_1, true);
}
+
/* Macros for showing usage statistics. */
#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
? (x) \
@@ -5695,4 +5190,8 @@ gimple_seq_set_location (gimple_seq seq, location_t loc)
#define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
+extern void sort_case_labels (vec<tree> );
+extern void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
+extern void gimple_seq_set_location (gimple_seq , location_t);
+
#endif /* GCC_GIMPLE_H */
diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c
new file mode 100644
index 00000000000..c4818fab756
--- /dev/null
+++ b/gcc/gimplify-me.c
@@ -0,0 +1,317 @@
+/* Tree lowering to gimple for middle end use only.
+ This converts the GENERIC functions-as-trees tree representation into
+ the GIMPLE form.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Major work done by Sebastian Pop <s.pop@laposte.net>,
+ Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
+
+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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify.h"
+#include "gimplify-me.h"
+#include "gimple-ssa.h"
+#include "tree-ssanames.h"
+
+
+/* Expand EXPR to list of gimple statements STMTS. GIMPLE_TEST_F specifies
+ the predicate that will hold for the result. If VAR is not NULL, make the
+ base variable of the final destination be VAR if suitable. */
+
+tree
+force_gimple_operand_1 (tree expr, gimple_seq *stmts,
+ gimple_predicate gimple_test_f, tree var)
+{
+ enum gimplify_status ret;
+ struct gimplify_ctx gctx;
+ location_t saved_location;
+
+ *stmts = NULL;
+
+ /* gimple_test_f might be more strict than is_gimple_val, make
+ sure we pass both. Just checking gimple_test_f doesn't work
+ because most gimple predicates do not work recursively. */
+ if (is_gimple_val (expr)
+ && (*gimple_test_f) (expr))
+ return expr;
+
+ push_gimplify_context (&gctx);
+ gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
+ gimplify_ctxp->allow_rhs_cond_expr = true;
+ saved_location = input_location;
+ input_location = UNKNOWN_LOCATION;
+
+ if (var)
+ {
+ if (gimplify_ctxp->into_ssa
+ && is_gimple_reg (var))
+ var = make_ssa_name (var, NULL);
+ expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
+ }
+
+ if (TREE_CODE (expr) != MODIFY_EXPR
+ && TREE_TYPE (expr) == void_type_node)
+ {
+ gimplify_and_add (expr, stmts);
+ expr = NULL_TREE;
+ }
+ else
+ {
+ ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
+ gcc_assert (ret != GS_ERROR);
+ }
+
+ input_location = saved_location;
+ pop_gimplify_context (NULL);
+
+ return expr;
+}
+
+/* Expand EXPR to list of gimple statements STMTS. If SIMPLE is true,
+ force the result to be either ssa_name or an invariant, otherwise
+ just force it to be a rhs expression. If VAR is not NULL, make the
+ base variable of the final destination be VAR if suitable. */
+
+tree
+force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
+{
+ return force_gimple_operand_1 (expr, stmts,
+ simple ? is_gimple_val : is_gimple_reg_rhs,
+ var);
+}
+
+/* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
+ and VAR. If some statements are produced, emits them at GSI.
+ If BEFORE is true. the statements are appended before GSI, otherwise
+ they are appended after it. M specifies the way GSI moves after
+ insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
+
+tree
+force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
+ gimple_predicate gimple_test_f,
+ tree var, bool before,
+ enum gsi_iterator_update m)
+{
+ gimple_seq stmts;
+
+ expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
+
+ if (!gimple_seq_empty_p (stmts))
+ {
+ if (before)
+ gsi_insert_seq_before (gsi, stmts, m);
+ else
+ gsi_insert_seq_after (gsi, stmts, m);
+ }
+
+ return expr;
+}
+
+/* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
+ If SIMPLE is true, force the result to be either ssa_name or an invariant,
+ otherwise just force it to be a rhs expression. If some statements are
+ produced, emits them at GSI. If BEFORE is true, the statements are
+ appended before GSI, otherwise they are appended after it. M specifies
+ the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
+ are the usual values). */
+
+tree
+force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
+ bool simple_p, tree var, bool before,
+ enum gsi_iterator_update m)
+{
+ return force_gimple_operand_gsi_1 (gsi, expr,
+ simple_p
+ ? is_gimple_val : is_gimple_reg_rhs,
+ var, before, m);
+}
+
+/* Some transformations like inlining may invalidate the GIMPLE form
+ for operands. This function traverses all the operands in STMT and
+ gimplifies anything that is not a valid gimple operand. Any new
+ GIMPLE statements are inserted before *GSI_P. */
+
+void
+gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
+{
+ size_t i, num_ops;
+ tree lhs;
+ gimple_seq pre = NULL;
+ gimple post_stmt = NULL;
+ struct gimplify_ctx gctx;
+
+ push_gimplify_context (&gctx);
+ gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_COND:
+ gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ break;
+ case GIMPLE_SWITCH:
+ gimplify_expr (gimple_switch_index_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ break;
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ break;
+ case GIMPLE_ASM:
+ {
+ size_t i, noutputs = gimple_asm_noutputs (stmt);
+ const char *constraint, **oconstraints;
+ bool allows_mem, allows_reg, is_inout;
+
+ oconstraints
+ = (const char **) alloca ((noutputs) * sizeof (const char *));
+ for (i = 0; i < noutputs; i++)
+ {
+ tree op = gimple_asm_output_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ oconstraints[i] = constraint;
+ parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
+ &allows_reg, &is_inout);
+ gimplify_expr (&TREE_VALUE (op), &pre, NULL,
+ is_inout ? is_gimple_min_lval : is_gimple_lvalue,
+ fb_lvalue | fb_mayfail);
+ }
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ {
+ tree op = gimple_asm_input_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+ if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
+ allows_reg = 0;
+ if (!allows_reg && allows_mem)
+ gimplify_expr (&TREE_VALUE (op), &pre, NULL,
+ is_gimple_lvalue, fb_lvalue | fb_mayfail);
+ else
+ gimplify_expr (&TREE_VALUE (op), &pre, NULL,
+ is_gimple_asm_val, fb_rvalue);
+ }
+ }
+ break;
+ default:
+ /* NOTE: We start gimplifying operands from last to first to
+ make sure that side-effects on the RHS of calls, assignments
+ and ASMs are executed before the LHS. The ordering is not
+ important for other statements. */
+ num_ops = gimple_num_ops (stmt);
+ for (i = num_ops; i > 0; i--)
+ {
+ tree op = gimple_op (stmt, i - 1);
+ if (op == NULL_TREE)
+ continue;
+ if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
+ gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
+ else if (i == 2
+ && is_gimple_assign (stmt)
+ && num_ops == 2
+ && get_gimple_rhs_class (gimple_expr_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ gimplify_expr (&op, &pre, NULL,
+ rhs_predicate_for (gimple_assign_lhs (stmt)),
+ fb_rvalue);
+ else if (i == 2 && is_gimple_call (stmt))
+ {
+ if (TREE_CODE (op) == FUNCTION_DECL)
+ continue;
+ gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
+ }
+ else
+ gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
+ gimple_set_op (stmt, i - 1, op);
+ }
+
+ lhs = gimple_get_lhs (stmt);
+ /* If the LHS changed it in a way that requires a simple RHS,
+ create temporary. */
+ if (lhs && !is_gimple_reg (lhs))
+ {
+ bool need_temp = false;
+
+ if (is_gimple_assign (stmt)
+ && num_ops == 2
+ && get_gimple_rhs_class (gimple_expr_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
+ rhs_predicate_for (gimple_assign_lhs (stmt)),
+ fb_rvalue);
+ else if (is_gimple_reg (lhs))
+ {
+ if (is_gimple_reg_type (TREE_TYPE (lhs)))
+ {
+ if (is_gimple_call (stmt))
+ {
+ i = gimple_call_flags (stmt);
+ if ((i & ECF_LOOPING_CONST_OR_PURE)
+ || !(i & (ECF_CONST | ECF_PURE)))
+ need_temp = true;
+ }
+ if (stmt_can_throw_internal (stmt))
+ need_temp = true;
+ }
+ }
+ else
+ {
+ if (is_gimple_reg_type (TREE_TYPE (lhs)))
+ need_temp = true;
+ else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
+ {
+ if (is_gimple_call (stmt))
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+
+ if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
+ && !(fndecl && DECL_RESULT (fndecl)
+ && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
+ need_temp = true;
+ }
+ else
+ need_temp = true;
+ }
+ }
+ if (need_temp)
+ {
+ tree temp = create_tmp_reg (TREE_TYPE (lhs), NULL);
+ if (gimple_in_ssa_p (cfun))
+ temp = make_ssa_name (temp, NULL);
+ gimple_set_lhs (stmt, temp);
+ post_stmt = gimple_build_assign (lhs, temp);
+ }
+ }
+ break;
+ }
+
+ if (!gimple_seq_empty_p (pre))
+ gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
+ if (post_stmt)
+ gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
+
+ pop_gimplify_context (NULL);
+}
+
+
diff --git a/gcc/gimplify-me.h b/gcc/gimplify-me.h
new file mode 100644
index 00000000000..a995af1d30e
--- /dev/null
+++ b/gcc/gimplify-me.h
@@ -0,0 +1,37 @@
+/* Header file for middle end gimplification.
+ Copyright (C) 2013 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/>. */
+
+#ifndef GCC_GIMPLIFY_ME_H
+#define GCC_GIMPLIFY_ME_H
+
+/* Validation of GIMPLE expressions. Note that these predicates only check
+ * the basic form of the expression, they don't recurse to make sure that
+ * underlying nodes are also of the right form. */
+typedef bool (*gimple_predicate)(tree);
+
+extern tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
+extern tree force_gimple_operand (tree, gimple_seq *, bool, tree);
+extern tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
+ gimple_predicate, tree,
+ bool, enum gsi_iterator_update);
+extern tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
+ bool, enum gsi_iterator_update);
+extern void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
+
+#endif /* GCC_GIMPLIFY_ME_H */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e20b9c6e852..94d0beba5e9 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -23,9 +23,10 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "tree-iterator.h"
#include "tree-inline.h"
#include "tree-pretty-print.h"
@@ -36,24 +37,15 @@ along with GCC; see the file COPYING3. If not see
#include "tree-cfg.h"
#include "tree-ssanames.h"
#include "tree-ssa.h"
-#include "timevar.h"
-#include "hashtab.h"
-#include "flags.h"
-#include "function.h"
-#include "ggc.h"
#include "diagnostic-core.h"
#include "target.h"
-#include "pointer-set.h"
#include "splay-tree.h"
-#include "vec.h"
#include "omp-low.h"
#include "gimple-low.h"
#include "cilk.h"
#include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
#include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
-#include "expr.h"
-#include "tm_p.h"
enum gimplify_omp_var_data
{
@@ -101,62 +93,13 @@ struct gimplify_omp_ctx
bool combined_loop;
};
-static struct gimplify_ctx *gimplify_ctxp;
+struct gimplify_ctx *gimplify_ctxp;
static struct gimplify_omp_ctx *gimplify_omp_ctxp;
/* Forward declaration. */
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
-/* Mark X addressable. Unlike the langhook we expect X to be in gimple
- form and we don't do any syntax checking. */
-
-void
-mark_addressable (tree x)
-{
- while (handled_component_p (x))
- x = TREE_OPERAND (x, 0);
- if (TREE_CODE (x) == MEM_REF
- && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
- x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
- if (TREE_CODE (x) != VAR_DECL
- && TREE_CODE (x) != PARM_DECL
- && 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;
- }
-}
-
-/* Link gimple statement GS to the end of the sequence *SEQ_P. If
- *SEQ_P is NULL, a new sequence is allocated. This function is
- similar to gimple_seq_add_stmt, but does not scan the operands.
- During gimplification, we need to manipulate statement sequences
- before the def/use vectors have been constructed. */
-
-void
-gimple_seq_add_stmt_without_update (gimple_seq *seq_p, gimple gs)
-{
- gimple_stmt_iterator si;
-
- if (gs == NULL)
- return;
-
- si = gsi_last (*seq_p);
- gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
-}
-
/* Shorter alias name for the above function for use in gimplify.c
only. */
@@ -365,125 +308,6 @@ gimplify_and_return_first (tree t, gimple_seq *seq_p)
return gimple_seq_first_stmt (*seq_p);
}
-/* Strip off a legitimate source ending from the input string NAME of
- length LEN. Rather than having to know the names used by all of
- our front ends, we strip off an ending of a period followed by
- up to five characters. (Java uses ".class".) */
-
-static inline void
-remove_suffix (char *name, int len)
-{
- int i;
-
- for (i = 2; i < 8 && len > i; i++)
- {
- if (name[len - i] == '.')
- {
- name[len - i] = '\0';
- break;
- }
- }
-}
-
-/* Create a new temporary name with PREFIX. Return an identifier. */
-
-static GTY(()) unsigned int tmp_var_id_num;
-
-tree
-create_tmp_var_name (const char *prefix)
-{
- char *tmp_name;
-
- if (prefix)
- {
- char *preftmp = ASTRDUP (prefix);
-
- remove_suffix (preftmp, strlen (preftmp));
- clean_symbol_name (preftmp);
-
- prefix = preftmp;
- }
-
- ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
- return get_identifier (tmp_name);
-}
-
-/* Create a new temporary variable declaration of type TYPE.
- Do NOT push it into the current binding. */
-
-tree
-create_tmp_var_raw (tree type, const char *prefix)
-{
- tree tmp_var;
-
- tmp_var = build_decl (input_location,
- VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
- type);
-
- /* The variable was declared by the compiler. */
- DECL_ARTIFICIAL (tmp_var) = 1;
- /* And we don't want debug info for it. */
- DECL_IGNORED_P (tmp_var) = 1;
-
- /* Make the variable writable. */
- TREE_READONLY (tmp_var) = 0;
-
- DECL_EXTERNAL (tmp_var) = 0;
- TREE_STATIC (tmp_var) = 0;
- TREE_USED (tmp_var) = 1;
-
- return tmp_var;
-}
-
-/* Create a new temporary variable declaration of type TYPE. DO push the
- variable into the current binding. Further, assume that this is called
- only from gimplification or optimization, at which point the creation of
- certain types are bugs. */
-
-tree
-create_tmp_var (tree type, const char *prefix)
-{
- tree tmp_var;
-
- /* We don't allow types that are addressable (meaning we can't make copies),
- or incomplete. We also used to reject every variable size objects here,
- but now support those for which a constant upper bound can be obtained.
- The processing for variable sizes is performed in gimple_add_tmp_var,
- point at which it really matters and possibly reached via paths not going
- through this function, e.g. after direct calls to create_tmp_var_raw. */
- gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
-
- tmp_var = create_tmp_var_raw (type, prefix);
- gimple_add_tmp_var (tmp_var);
- return tmp_var;
-}
-
-/* Create a new temporary variable declaration of type TYPE by calling
- create_tmp_var and if TYPE is a vector or a complex number, mark the new
- temporary as gimple register. */
-
-tree
-create_tmp_reg (tree type, const char *prefix)
-{
- tree tmp;
-
- tmp = create_tmp_var (type, prefix);
- if (TREE_CODE (type) == COMPLEX_TYPE
- || TREE_CODE (type) == VECTOR_TYPE)
- DECL_GIMPLE_REG_P (tmp) = 1;
-
- return tmp;
-}
-
-/* Returns true iff T is a valid RHS for an assignment to a renamed
- user -- or front-end generated artificial -- variable. */
-
-static bool
-is_gimple_reg_rhs (tree t)
-{
- return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
-}
-
/* Returns true iff T is a valid RHS for an assignment to an un-renamed
LHS, or for a call argument. */
@@ -750,84 +574,7 @@ gimple_add_tmp_var (tree tmp)
}
}
-/* Determine whether to assign a location to the statement GS. */
-
-static bool
-should_carry_location_p (gimple gs)
-{
- /* Don't emit a line note for a label. We particularly don't want to
- emit one for the break label, since it doesn't actually correspond
- to the beginning of the loop/switch. */
- if (gimple_code (gs) == GIMPLE_LABEL)
- return false;
-
- return true;
-}
-
-/* Return true if a location should not be emitted for this statement
- by annotate_one_with_location. */
-
-static inline bool
-gimple_do_not_emit_location_p (gimple g)
-{
- return gimple_plf (g, GF_PLF_1);
-}
-
-/* Mark statement G so a location will not be emitted by
- annotate_one_with_location. */
-
-static inline void
-gimple_set_do_not_emit_location (gimple g)
-{
- /* The PLF flags are initialized to 0 when a new tuple is created,
- so no need to initialize it anywhere. */
- gimple_set_plf (g, GF_PLF_1, true);
-}
-
-/* Set the location for gimple statement GS to LOCATION. */
-
-static void
-annotate_one_with_location (gimple gs, location_t location)
-{
- if (!gimple_has_location (gs)
- && !gimple_do_not_emit_location_p (gs)
- && should_carry_location_p (gs))
- gimple_set_location (gs, location);
-}
-
-/* Set LOCATION for all the statements after iterator GSI in sequence
- SEQ. If GSI is pointing to the end of the sequence, start with the
- first statement in SEQ. */
-
-static void
-annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi,
- location_t location)
-{
- if (gsi_end_p (gsi))
- gsi = gsi_start (seq);
- else
- gsi_next (&gsi);
-
- for (; !gsi_end_p (gsi); gsi_next (&gsi))
- annotate_one_with_location (gsi_stmt (gsi), location);
-}
-
-/* Set the location for all the statements in a sequence STMT_P to LOCATION. */
-
-void
-annotate_all_with_location (gimple_seq stmt_p, location_t location)
-{
- gimple_stmt_iterator i;
-
- if (gimple_seq_empty_p (stmt_p))
- return;
- for (i = gsi_start (stmt_p); !gsi_end_p (i); gsi_next (&i))
- {
- gimple gs = gsi_stmt (i);
- annotate_one_with_location (gs, location);
- }
-}
/* This page contains routines to unshare tree nodes, i.e. to duplicate tree
nodes that are referenced more than once in GENERIC functions. This is
@@ -1441,6 +1188,20 @@ gimplify_vla_decl (tree decl, gimple_seq *seq_p)
gimplify_ctxp->save_stack = true;
}
+/* A helper function to be called via walk_tree. Mark all labels under *TP
+ as being forced. To be called for DECL_INITIAL of static variables. */
+
+static tree
+force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+{
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ if (TREE_CODE (*tp) == LABEL_DECL)
+ FORCED_LABEL (*tp) = 1;
+
+ return NULL_TREE;
+}
+
/* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
and initialization explicit. */
@@ -1557,204 +1318,7 @@ gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
return GS_ALL_DONE;
}
-
-/* Compare two case labels. Because the front end should already have
- made sure that case ranges do not overlap, it is enough to only compare
- the CASE_LOW values of each case label. */
-
-static int
-compare_case_labels (const void *p1, const void *p2)
-{
- const_tree const case1 = *(const_tree const*)p1;
- const_tree const case2 = *(const_tree const*)p2;
-
- /* The 'default' case label always goes first. */
- if (!CASE_LOW (case1))
- return -1;
- else if (!CASE_LOW (case2))
- return 1;
- else
- return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
-}
-/* Sort the case labels in LABEL_VEC in place in ascending order. */
-
-void
-sort_case_labels (vec<tree> label_vec)
-{
- label_vec.qsort (compare_case_labels);
-}
-
-/* Prepare a vector of case labels to be used in a GIMPLE_SWITCH statement.
-
- LABELS is a vector that contains all case labels to look at.
-
- INDEX_TYPE is the type of the switch index expression. Case labels
- in LABELS are discarded if their values are not in the value range
- covered by INDEX_TYPE. The remaining case label values are folded
- to INDEX_TYPE.
-
- If a default case exists in LABELS, it is removed from LABELS and
- returned in DEFAULT_CASEP. If no default case exists, but the
- case labels already cover the whole range of INDEX_TYPE, a default
- case is returned pointing to one of the existing case labels.
- Otherwise DEFAULT_CASEP is set to NULL_TREE.
-
- DEFAULT_CASEP may be NULL, in which case the above comment doesn't
- apply and no action is taken regardless of whether a default case is
- found or not. */
-
-void
-preprocess_case_label_vec_for_gimple (vec<tree> labels,
- tree index_type,
- tree *default_casep)
-{
- tree min_value, max_value;
- tree default_case = NULL_TREE;
- size_t i, len;
-
- i = 0;
- min_value = TYPE_MIN_VALUE (index_type);
- max_value = TYPE_MAX_VALUE (index_type);
- while (i < labels.length ())
- {
- tree elt = labels[i];
- tree low = CASE_LOW (elt);
- tree high = CASE_HIGH (elt);
- bool remove_element = FALSE;
-
- if (low)
- {
- gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
- gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
-
- /* This is a non-default case label, i.e. it has a value.
-
- See if the case label is reachable within the range of
- the index type. Remove out-of-range case values. Turn
- case ranges into a canonical form (high > low strictly)
- and convert the case label values to the index type.
-
- NB: The type of gimple_switch_index() may be the promoted
- type, but the case labels retain the original type. */
-
- if (high)
- {
- /* This is a case range. Discard empty ranges.
- If the bounds or the range are equal, turn this
- into a simple (one-value) case. */
- int cmp = tree_int_cst_compare (high, low);
- if (cmp < 0)
- remove_element = TRUE;
- else if (cmp == 0)
- high = NULL_TREE;
- }
-
- if (! high)
- {
- /* If the simple case value is unreachable, ignore it. */
- if ((TREE_CODE (min_value) == INTEGER_CST
- && tree_int_cst_compare (low, min_value) < 0)
- || (TREE_CODE (max_value) == INTEGER_CST
- && tree_int_cst_compare (low, max_value) > 0))
- remove_element = TRUE;
- else
- low = fold_convert (index_type, low);
- }
- else
- {
- /* If the entire case range is unreachable, ignore it. */
- if ((TREE_CODE (min_value) == INTEGER_CST
- && tree_int_cst_compare (high, min_value) < 0)
- || (TREE_CODE (max_value) == INTEGER_CST
- && tree_int_cst_compare (low, max_value) > 0))
- remove_element = TRUE;
- else
- {
- /* If the lower bound is less than the index type's
- minimum value, truncate the range bounds. */
- if (TREE_CODE (min_value) == INTEGER_CST
- && tree_int_cst_compare (low, min_value) < 0)
- low = min_value;
- low = fold_convert (index_type, low);
-
- /* If the upper bound is greater than the index type's
- maximum value, truncate the range bounds. */
- if (TREE_CODE (max_value) == INTEGER_CST
- && tree_int_cst_compare (high, max_value) > 0)
- high = max_value;
- high = fold_convert (index_type, high);
-
- /* We may have folded a case range to a one-value case. */
- if (tree_int_cst_equal (low, high))
- high = NULL_TREE;
- }
- }
-
- CASE_LOW (elt) = low;
- CASE_HIGH (elt) = high;
- }
- else
- {
- gcc_assert (!default_case);
- default_case = elt;
- /* The default case must be passed separately to the
- gimple_build_switch routine. But if DEFAULT_CASEP
- is NULL, we do not remove the default case (it would
- be completely lost). */
- if (default_casep)
- remove_element = TRUE;
- }
-
- if (remove_element)
- labels.ordered_remove (i);
- else
- i++;
- }
- len = i;
-
- if (!labels.is_empty ())
- sort_case_labels (labels);
-
- if (default_casep && !default_case)
- {
- /* If the switch has no default label, add one, so that we jump
- around the switch body. If the labels already cover the whole
- range of the switch index_type, add the default label pointing
- to one of the existing labels. */
- if (len
- && TYPE_MIN_VALUE (index_type)
- && TYPE_MAX_VALUE (index_type)
- && tree_int_cst_equal (CASE_LOW (labels[0]),
- TYPE_MIN_VALUE (index_type)))
- {
- tree low, high = CASE_HIGH (labels[len - 1]);
- if (!high)
- high = CASE_LOW (labels[len - 1]);
- if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
- {
- for (i = 1; i < len; i++)
- {
- high = CASE_LOW (labels[i]);
- low = CASE_HIGH (labels[i - 1]);
- if (!low)
- low = CASE_LOW (labels[i - 1]);
- if (wi::add (low, 1) != high)
- break;
- }
- if (i == len)
- {
- tree label = CASE_LABEL (labels[0]);
- default_case = build_case_label (NULL_TREE, NULL_TREE,
- label);
- }
- }
- }
- }
-
- if (default_casep)
- *default_casep = default_case;
-}
/* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
branch to. */
@@ -1878,20 +1442,6 @@ gimplify_exit_expr (tree *expr_p)
return GS_OK;
}
-/* A helper function to be called via walk_tree. Mark all labels under *TP
- as being forced. To be called for DECL_INITIAL of static variables. */
-
-tree
-force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
-{
- if (TYPE_P (*tp))
- *walk_subtrees = 0;
- if (TREE_CODE (*tp) == LABEL_DECL)
- FORCED_LABEL (*tp) = 1;
-
- return NULL_TREE;
-}
-
/* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
different from its canonical type, wrap the whole thing inside a
NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
@@ -4048,9 +3598,9 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
objects. Initializers for such objects must explicitly set
every field that needs to be set. */
cleared = false;
- else if (!complete_p)
+ else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
/* If the constructor isn't complete, clear the whole object
- beforehand.
+ beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
??? This ought not to be needed. For any element not present
in the initializer, we should simply set them to zero. Except
@@ -4639,6 +4189,7 @@ is_gimple_stmt (tree t)
case OMP_PARALLEL:
case OMP_FOR:
case OMP_SIMD:
+ case CILK_SIMD:
case OMP_DISTRIBUTE:
case OMP_SECTIONS:
case OMP_SECTION:
@@ -6856,7 +6407,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
orig_for_stmt = for_stmt = *expr_p;
- simd = TREE_CODE (for_stmt) == OMP_SIMD;
+ simd = TREE_CODE (for_stmt) == OMP_SIMD
+ || TREE_CODE (for_stmt) == CILK_SIMD;
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
simd ? ORT_SIMD : ORT_WORKSHARE);
@@ -6993,15 +6545,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
- if (orig_for_stmt != for_stmt)
+ {
+ tree decl = TREE_OPERAND (t, 0);
+ // c_omp_for_incr_canonicalize_ptr() should have been
+ // called to massage things appropriately.
+ gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
+
+ if (orig_for_stmt != for_stmt)
+ break;
+ t = build_int_cst (TREE_TYPE (decl), 1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
+ t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
+ TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
break;
- t = build_int_cst (TREE_TYPE (decl), 1);
- if (c)
- OMP_CLAUSE_LINEAR_STEP (c) = t;
- t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
- t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
- TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
- break;
+ }
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
@@ -7111,6 +6670,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
+ case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
default:
gcc_unreachable ();
@@ -8180,6 +7740,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case OMP_FOR:
case OMP_SIMD:
+ case CILK_SIMD:
case OMP_DISTRIBUTE:
ret = gimplify_omp_for (expr_p, pre_p);
break;
@@ -9031,287 +8592,6 @@ gimplify_function_tree (tree fndecl)
pop_cfun ();
}
-/* Some transformations like inlining may invalidate the GIMPLE form
- for operands. This function traverses all the operands in STMT and
- gimplifies anything that is not a valid gimple operand. Any new
- GIMPLE statements are inserted before *GSI_P. */
-
-void
-gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
-{
- size_t i, num_ops;
- tree lhs;
- gimple_seq pre = NULL;
- gimple post_stmt = NULL;
- struct gimplify_ctx gctx;
-
- push_gimplify_context (&gctx);
- gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
-
- switch (gimple_code (stmt))
- {
- case GIMPLE_COND:
- gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
- is_gimple_val, fb_rvalue);
- gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
- is_gimple_val, fb_rvalue);
- break;
- case GIMPLE_SWITCH:
- gimplify_expr (gimple_switch_index_ptr (stmt), &pre, NULL,
- is_gimple_val, fb_rvalue);
- break;
- case GIMPLE_OMP_ATOMIC_LOAD:
- gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL,
- is_gimple_val, fb_rvalue);
- break;
- case GIMPLE_ASM:
- {
- size_t i, noutputs = gimple_asm_noutputs (stmt);
- const char *constraint, **oconstraints;
- bool allows_mem, allows_reg, is_inout;
-
- oconstraints
- = (const char **) alloca ((noutputs) * sizeof (const char *));
- for (i = 0; i < noutputs; i++)
- {
- tree op = gimple_asm_output_op (stmt, i);
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
- oconstraints[i] = constraint;
- parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
- &allows_reg, &is_inout);
- gimplify_expr (&TREE_VALUE (op), &pre, NULL,
- is_inout ? is_gimple_min_lval : is_gimple_lvalue,
- fb_lvalue | fb_mayfail);
- }
- for (i = 0; i < gimple_asm_ninputs (stmt); i++)
- {
- tree op = gimple_asm_input_op (stmt, i);
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
- parse_input_constraint (&constraint, 0, 0, noutputs, 0,
- oconstraints, &allows_mem, &allows_reg);
- if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
- allows_reg = 0;
- if (!allows_reg && allows_mem)
- gimplify_expr (&TREE_VALUE (op), &pre, NULL,
- is_gimple_lvalue, fb_lvalue | fb_mayfail);
- else
- gimplify_expr (&TREE_VALUE (op), &pre, NULL,
- is_gimple_asm_val, fb_rvalue);
- }
- }
- break;
- default:
- /* NOTE: We start gimplifying operands from last to first to
- make sure that side-effects on the RHS of calls, assignments
- and ASMs are executed before the LHS. The ordering is not
- important for other statements. */
- num_ops = gimple_num_ops (stmt);
- for (i = num_ops; i > 0; i--)
- {
- tree op = gimple_op (stmt, i - 1);
- if (op == NULL_TREE)
- continue;
- if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
- gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
- else if (i == 2
- && is_gimple_assign (stmt)
- && num_ops == 2
- && get_gimple_rhs_class (gimple_expr_code (stmt))
- == GIMPLE_SINGLE_RHS)
- gimplify_expr (&op, &pre, NULL,
- rhs_predicate_for (gimple_assign_lhs (stmt)),
- fb_rvalue);
- else if (i == 2 && is_gimple_call (stmt))
- {
- if (TREE_CODE (op) == FUNCTION_DECL)
- continue;
- gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
- }
- else
- gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
- gimple_set_op (stmt, i - 1, op);
- }
-
- lhs = gimple_get_lhs (stmt);
- /* If the LHS changed it in a way that requires a simple RHS,
- create temporary. */
- if (lhs && !is_gimple_reg (lhs))
- {
- bool need_temp = false;
-
- if (is_gimple_assign (stmt)
- && num_ops == 2
- && get_gimple_rhs_class (gimple_expr_code (stmt))
- == GIMPLE_SINGLE_RHS)
- gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
- rhs_predicate_for (gimple_assign_lhs (stmt)),
- fb_rvalue);
- else if (is_gimple_reg (lhs))
- {
- if (is_gimple_reg_type (TREE_TYPE (lhs)))
- {
- if (is_gimple_call (stmt))
- {
- i = gimple_call_flags (stmt);
- if ((i & ECF_LOOPING_CONST_OR_PURE)
- || !(i & (ECF_CONST | ECF_PURE)))
- need_temp = true;
- }
- if (stmt_can_throw_internal (stmt))
- need_temp = true;
- }
- }
- else
- {
- if (is_gimple_reg_type (TREE_TYPE (lhs)))
- need_temp = true;
- else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
- {
- if (is_gimple_call (stmt))
- {
- tree fndecl = gimple_call_fndecl (stmt);
-
- if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
- && !(fndecl && DECL_RESULT (fndecl)
- && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
- need_temp = true;
- }
- else
- need_temp = true;
- }
- }
- if (need_temp)
- {
- tree temp = create_tmp_reg (TREE_TYPE (lhs), NULL);
- if (gimple_in_ssa_p (cfun))
- temp = make_ssa_name (temp, NULL);
- gimple_set_lhs (stmt, temp);
- post_stmt = gimple_build_assign (lhs, temp);
- }
- }
- break;
- }
-
- if (!gimple_seq_empty_p (pre))
- gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
- if (post_stmt)
- gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
-
- pop_gimplify_context (NULL);
-}
-
-/* Expand EXPR to list of gimple statements STMTS. GIMPLE_TEST_F specifies
- the predicate that will hold for the result. If VAR is not NULL, make the
- base variable of the final destination be VAR if suitable. */
-
-tree
-force_gimple_operand_1 (tree expr, gimple_seq *stmts,
- gimple_predicate gimple_test_f, tree var)
-{
- enum gimplify_status ret;
- struct gimplify_ctx gctx;
- location_t saved_location;
-
- *stmts = NULL;
-
- /* gimple_test_f might be more strict than is_gimple_val, make
- sure we pass both. Just checking gimple_test_f doesn't work
- because most gimple predicates do not work recursively. */
- if (is_gimple_val (expr)
- && (*gimple_test_f) (expr))
- return expr;
-
- push_gimplify_context (&gctx);
- gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
- gimplify_ctxp->allow_rhs_cond_expr = true;
- saved_location = input_location;
- input_location = UNKNOWN_LOCATION;
-
- if (var)
- {
- if (gimplify_ctxp->into_ssa
- && is_gimple_reg (var))
- var = make_ssa_name (var, NULL);
- expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
- }
-
- if (TREE_CODE (expr) != MODIFY_EXPR
- && TREE_TYPE (expr) == void_type_node)
- {
- gimplify_and_add (expr, stmts);
- expr = NULL_TREE;
- }
- else
- {
- ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
- gcc_assert (ret != GS_ERROR);
- }
-
- input_location = saved_location;
- pop_gimplify_context (NULL);
-
- return expr;
-}
-
-/* Expand EXPR to list of gimple statements STMTS. If SIMPLE is true,
- force the result to be either ssa_name or an invariant, otherwise
- just force it to be a rhs expression. If VAR is not NULL, make the
- base variable of the final destination be VAR if suitable. */
-
-tree
-force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
-{
- return force_gimple_operand_1 (expr, stmts,
- simple ? is_gimple_val : is_gimple_reg_rhs,
- var);
-}
-
-/* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
- and VAR. If some statements are produced, emits them at GSI.
- If BEFORE is true. the statements are appended before GSI, otherwise
- they are appended after it. M specifies the way GSI moves after
- insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
-
-tree
-force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
- gimple_predicate gimple_test_f,
- tree var, bool before,
- enum gsi_iterator_update m)
-{
- gimple_seq stmts;
-
- expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
-
- if (!gimple_seq_empty_p (stmts))
- {
- if (before)
- gsi_insert_seq_before (gsi, stmts, m);
- else
- gsi_insert_seq_after (gsi, stmts, m);
- }
-
- return expr;
-}
-
-/* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
- If SIMPLE is true, force the result to be either ssa_name or an invariant,
- otherwise just force it to be a rhs expression. If some statements are
- produced, emits them at GSI. If BEFORE is true, the statements are
- appended before GSI, otherwise they are appended after it. M specifies
- the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
- are the usual values). */
-
-tree
-force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
- bool simple_p, tree var, bool before,
- enum gsi_iterator_update m)
-{
- return force_gimple_operand_gsi_1 (gsi, expr,
- simple_p
- ? is_gimple_val : is_gimple_reg_rhs,
- var, before, m);
-}
-
/* Return a dummy expression of type TYPE in order to keep going after an
error. */
@@ -9415,4 +8695,49 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
}
}
-#include "gt-gimplify.h"
+/* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
+
+ DST/SRC are the destination and source respectively. You can pass
+ ungimplified trees in DST or SRC, in which case they will be
+ converted to a gimple operand if necessary.
+
+ This function returns the newly created GIMPLE_ASSIGN tuple. */
+
+gimple
+gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
+{
+ tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
+ gimplify_and_add (t, seq_p);
+ ggc_free (t);
+ return gimple_seq_last_stmt (*seq_p);
+}
+
+inline hashval_t
+gimplify_hasher::hash (const value_type *p)
+{
+ tree t = p->val;
+ return iterative_hash_expr (t, 0);
+}
+
+inline bool
+gimplify_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ tree t1 = p1->val;
+ tree t2 = p2->val;
+ enum tree_code code = TREE_CODE (t1);
+
+ if (TREE_CODE (t2) != code
+ || TREE_TYPE (t1) != TREE_TYPE (t2))
+ return false;
+
+ if (!operand_equal_p (t1, t2, 0))
+ return false;
+
+#ifdef ENABLE_CHECKING
+ /* Only allow them to compare equal if they also hash equal; otherwise
+ results are nondeterminate, and we fail bootstrap comparison. */
+ gcc_assert (hash (p1) == hash (p2));
+#endif
+
+ return true;
+}
diff --git a/gcc/gimplify.h b/gcc/gimplify.h
new file mode 100644
index 00000000000..3f7e1b327a9
--- /dev/null
+++ b/gcc/gimplify.h
@@ -0,0 +1,132 @@
+/* Header file for gimplification.
+ Copyright (C) 2013 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/>. */
+
+#ifndef GCC_GIMPLIFY_H
+#define GCC_GIMPLIFY_H
+
+/* Validation of GIMPLE expressions. Note that these predicates only check
+ the basic form of the expression, they don't recurse to make sure that
+ underlying nodes are also of the right form. */
+typedef bool (*gimple_predicate)(tree);
+
+/* FIXME we should deduce this from the predicate. */
+enum fallback {
+ fb_none = 0, /* Do not generate a temporary. */
+
+ fb_rvalue = 1, /* Generate an rvalue to hold the result of a
+ gimplified expression. */
+
+ fb_lvalue = 2, /* Generate an lvalue to hold the result of a
+ gimplified expression. */
+
+ fb_mayfail = 4, /* Gimplification may fail. Error issued
+ afterwards. */
+ fb_either= fb_rvalue | fb_lvalue
+};
+
+typedef int fallback_t;
+
+enum gimplify_status {
+ GS_ERROR = -2, /* Something Bad Seen. */
+ GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
+ GS_OK = 0, /* We did something, maybe more to do. */
+ GS_ALL_DONE = 1 /* The expression is fully gimplified. */
+};
+/* Gimplify hashtable helper. */
+
+struct gimplify_hasher : typed_free_remove <elt_t>
+{
+ typedef elt_t value_type;
+ typedef elt_t compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+struct gimplify_ctx
+{
+ struct gimplify_ctx *prev_context;
+
+ vec<gimple> bind_expr_stack;
+ tree temps;
+ gimple_seq conditional_cleanups;
+ tree exit_label;
+ tree return_temp;
+
+ vec<tree> case_labels;
+ /* The formal temporary table. Should this be persistent? */
+ hash_table <gimplify_hasher> temp_htab;
+
+ int conditions;
+ bool save_stack;
+ bool into_ssa;
+ bool allow_rhs_cond_expr;
+ bool in_cleanup_point_expr;
+};
+
+extern struct gimplify_ctx *gimplify_ctxp;
+extern void push_gimplify_context (struct gimplify_ctx *);
+extern void pop_gimplify_context (gimple);
+extern gimple gimple_current_bind_expr (void);
+extern vec<gimple> gimple_bind_expr_stack (void);
+extern void gimplify_and_add (tree, gimple_seq *);
+extern tree get_formal_tmp_var (tree, gimple_seq *);
+extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
+extern void declare_vars (tree, gimple, bool);
+extern void gimple_add_tmp_var (tree);
+extern tree unshare_expr (tree);
+extern tree unshare_expr_without_location (tree);
+extern tree voidify_wrapper_expr (tree, tree);
+extern tree build_and_jump (tree *);
+extern enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *,
+ gimple_seq *, bool, tree);
+extern tree gimple_boolify (tree);
+extern gimple_predicate rhs_predicate_for (tree);
+extern bool gimplify_stmt (tree *, gimple_seq *);
+extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
+extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ bool (*) (tree), fallback_t);
+
+extern void gimplify_type_sizes (tree, gimple_seq *);
+extern void gimplify_one_sizepos (tree *, gimple_seq *);
+extern gimple gimplify_body (tree, bool);
+extern void gimplify_function_tree (tree);
+extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
+ gimple_seq *);
+gimple gimplify_assign (tree, tree, gimple_seq *);
+
+/* Return true if gimplify_one_sizepos doesn't need to gimplify
+ expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
+ fields). */
+
+static inline bool
+is_gimple_sizepos (tree expr)
+{
+ /* gimplify_one_sizepos doesn't need to do anything if the value isn't there,
+ is constant, or contains A PLACEHOLDER_EXPR. We also don't want to do
+ anything if it's already a VAR_DECL. If it's a VAR_DECL from another
+ function, the gimplifier will want to replace it with a new variable,
+ but that will cause problems if this type is from outside the function.
+ It's OK to have that here. */
+ return (expr == NULL_TREE
+ || TREE_CONSTANT (expr)
+ || TREE_CODE (expr) == VAR_DECL
+ || CONTAINS_PLACEHOLDER_P (expr));
+}
+
+#endif /* GCC_GIMPLIFY_H */
diff --git a/gcc/ginclude/stdatomic.h b/gcc/ginclude/stdatomic.h
index 622577f0877..b558bf10f19 100644
--- a/gcc/ginclude/stdatomic.h
+++ b/gcc/ginclude/stdatomic.h
@@ -87,7 +87,7 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
#define kill_dependency(Y) \
__extension__ \
({ \
- __typeof__ (Y) __kill_dependency_tmp = (Y); \
+ __auto_type __kill_dependency_tmp = (Y); \
__kill_dependency_tmp; \
})
@@ -121,9 +121,9 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
__atomic_type_lock_free (void * _Atomic)
-/* Note that these macros require __typeof__ to remove _Atomic
- qualifiers (and const qualifiers, if those are valid on macro
- operands).
+/* Note that these macros require __typeof__ and __auto_type to remove
+ _Atomic qualifiers (and const qualifiers, if those are valid on
+ macro operands).
Also note that the header file uses the generic form of __atomic
builtins, which requires the address to be taken of the value
@@ -132,11 +132,12 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
these to lock-free _N variants if possible, and throw away the
temps. */
-#define atomic_store_explicit(PTR, VAL, MO) \
- __extension__ \
- ({ \
- __typeof__ (*(PTR)) __atomic_store_tmp = (VAL); \
- __atomic_store ((PTR), &__atomic_store_tmp, (MO)); \
+#define atomic_store_explicit(PTR, VAL, MO) \
+ __extension__ \
+ ({ \
+ __auto_type __atomic_store_ptr = (PTR); \
+ __typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL); \
+ __atomic_store (__atomic_store_ptr, &__atomic_store_tmp, (MO)); \
})
#define atomic_store(PTR, VAL) \
@@ -146,8 +147,9 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
#define atomic_load_explicit(PTR, MO) \
__extension__ \
({ \
- __typeof__ (*(PTR)) __atomic_load_tmp; \
- __atomic_load ((PTR), &__atomic_load_tmp, (MO)); \
+ __auto_type __atomic_load_ptr = (PTR); \
+ __typeof__ (*__atomic_load_ptr) __atomic_load_tmp; \
+ __atomic_load (__atomic_load_ptr, &__atomic_load_tmp, (MO)); \
__atomic_load_tmp; \
})
@@ -157,8 +159,10 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
#define atomic_exchange_explicit(PTR, VAL, MO) \
__extension__ \
({ \
- __typeof__ (*(PTR)) __atomic_exchange_val = (VAL), __atomic_exchange_tmp; \
- __atomic_exchange ((PTR), &__atomic_exchange_val, \
+ __auto_type __atomic_exchange_ptr = (PTR); \
+ __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_val = (VAL); \
+ __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_tmp; \
+ __atomic_exchange (__atomic_exchange_ptr, &__atomic_exchange_val, \
&__atomic_exchange_tmp, (MO)); \
__atomic_exchange_tmp; \
})
@@ -170,8 +174,10 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
#define atomic_compare_exchange_strong_explicit(PTR, VAL, DES, SUC, FAIL) \
__extension__ \
({ \
- __typeof__ (*(PTR)) __atomic_compare_exchange_tmp = (DES); \
- __atomic_compare_exchange ((PTR), (VAL), \
+ __auto_type __atomic_compare_exchange_ptr = (PTR); \
+ __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \
+ = (DES); \
+ __atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), \
&__atomic_compare_exchange_tmp, 0, \
(SUC), (FAIL)); \
})
@@ -183,8 +189,10 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;
#define atomic_compare_exchange_weak_explicit(PTR, VAL, DES, SUC, FAIL) \
__extension__ \
({ \
- __typeof__ (*(PTR)) __atomic_compare_exchange_tmp = (DES); \
- __atomic_compare_exchange ((PTR), (VAL), \
+ __auto_type __atomic_compare_exchange_ptr = (PTR); \
+ __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \
+ = (DES); \
+ __atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), \
&__atomic_compare_exchange_tmp, 1, \
(SUC), (FAIL)); \
})
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 33ccc1cdce8..54d9f3bf9b4 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,11 @@
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * go-lang.c: Include only gimplify.h and gimple.h as needed.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * go-lang.c: Include gimplify.h.
+
2013-11-06 Ian Lance Taylor <iant@google.com>
* go-lang.c (go_langhook_post_options): If
diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
index 14080f098c8..aa1d80b5be2 100644
--- a/gcc/go/go-lang.c
+++ b/gcc/go/go-lang.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "opts.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "ggc.h"
#include "toplev.h"
#include "debug.h"
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 1d8de2f75ff..54e970c77dd 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -12,6 +12,7 @@
#include "intl.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-iterator.h"
#include "convert.h"
#include "real.h"
@@ -3633,7 +3634,8 @@ class Unary_expression : public Expression
public:
Unary_expression(Operator op, Expression* expr, Location location)
: Expression(EXPRESSION_UNARY, location),
- op_(op), escapes_(true), create_temp_(false), expr_(expr)
+ op_(op), escapes_(true), create_temp_(false), expr_(expr),
+ issue_nil_check_(false)
{ }
// Return the operator.
@@ -3719,6 +3721,10 @@ class Unary_expression : public Expression
void
do_dump_expression(Ast_dump_context*) const;
+ void
+ do_issue_nil_check()
+ { this->issue_nil_check_ = (this->op_ == OPERATOR_MULT); }
+
private:
// The unary operator to apply.
Operator op_;
@@ -3730,6 +3736,9 @@ class Unary_expression : public Expression
bool create_temp_;
// The operand.
Expression* expr_;
+ // Whether or not to issue a nil check for this expression if its address
+ // is being taken.
+ bool issue_nil_check_;
};
// If we are taking the address of a composite literal, and the
@@ -4107,7 +4116,10 @@ Unary_expression::do_check_types(Gogo*)
this->report_error(_("invalid operand for unary %<&%>"));
}
else
- this->expr_->address_taken(this->escapes_);
+ {
+ this->expr_->address_taken(this->escapes_);
+ this->expr_->issue_nil_check();
+ }
break;
case OPERATOR_MULT:
@@ -4277,12 +4289,13 @@ Unary_expression::do_get_tree(Translate_context* context)
// If we are dereferencing the pointer to a large struct, we
// need to check for nil. We don't bother to check for small
// structs because we expect the system to crash on a nil
- // pointer dereference.
+ // pointer dereference. However, if we know the address of this
+ // expression is being taken, we must always check for nil.
tree target_type_tree = TREE_TYPE(TREE_TYPE(expr));
if (!VOID_TYPE_P(target_type_tree))
{
HOST_WIDE_INT s = int_size_in_bytes(target_type_tree);
- if (s == -1 || s >= 4096)
+ if (s == -1 || s >= 4096 || this->issue_nil_check_)
{
if (!DECL_P(expr))
expr = save_expr(expr);
@@ -5308,7 +5321,7 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*,
}
}
- // Lower struct and array comparisons.
+ // Lower struct, array, and some interface comparisons.
if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
{
if (left->type()->struct_type() != NULL)
@@ -5316,6 +5329,11 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*,
else if (left->type()->array_type() != NULL
&& !left->type()->is_slice_type())
return this->lower_array_comparison(gogo, inserter);
+ else if ((left->type()->interface_type() != NULL
+ && right->type()->interface_type() == NULL)
+ || (left->type()->interface_type() == NULL
+ && right->type()->interface_type() != NULL))
+ return this->lower_interface_value_comparison(gogo, inserter);
}
return this;
@@ -5444,6 +5462,57 @@ Binary_expression::lower_array_comparison(Gogo* gogo,
return ret;
}
+// Lower an interface to value comparison.
+
+Expression*
+Binary_expression::lower_interface_value_comparison(Gogo*,
+ Statement_inserter* inserter)
+{
+ Type* left_type = this->left_->type();
+ Type* right_type = this->right_->type();
+ Interface_type* ift;
+ if (left_type->interface_type() != NULL)
+ {
+ ift = left_type->interface_type();
+ if (!ift->implements_interface(right_type, NULL))
+ return this;
+ }
+ else
+ {
+ ift = right_type->interface_type();
+ if (!ift->implements_interface(left_type, NULL))
+ return this;
+ }
+ if (!Type::are_compatible_for_comparison(true, left_type, right_type, NULL))
+ return this;
+
+ Location loc = this->location();
+
+ if (left_type->interface_type() == NULL
+ && left_type->points_to() == NULL
+ && !this->left_->is_addressable())
+ {
+ Temporary_statement* temp =
+ Statement::make_temporary(left_type, NULL, loc);
+ inserter->insert(temp);
+ this->left_ =
+ Expression::make_set_and_use_temporary(temp, this->left_, loc);
+ }
+
+ if (right_type->interface_type() == NULL
+ && right_type->points_to() == NULL
+ && !this->right_->is_addressable())
+ {
+ Temporary_statement* temp =
+ Statement::make_temporary(right_type, NULL, loc);
+ inserter->insert(temp);
+ this->right_ =
+ Expression::make_set_and_use_temporary(temp, this->right_, loc);
+ }
+
+ return this;
+}
+
// Lower a struct or array comparison to a call to memcmp.
Expression*
@@ -5906,8 +5975,7 @@ Binary_expression::do_get_tree(Translate_context* context)
case OPERATOR_GT:
case OPERATOR_GE:
return Expression::comparison_tree(context, this->type_, this->op_,
- this->left_->type(), left,
- this->right_->type(), right,
+ this->left_, this->right_,
this->location());
case OPERATOR_OROR:
@@ -6404,12 +6472,16 @@ Expression::make_binary(Operator op, Expression* left, Expression* right,
tree
Expression::comparison_tree(Translate_context* context, Type* result_type,
- Operator op, Type* left_type, tree left_tree,
- Type* right_type, tree right_tree,
- Location location)
+ Operator op, Expression* left_expr,
+ Expression* right_expr, Location location)
{
- Type* int_type = Type::lookup_integer_type("int");
- tree int_type_tree = type_to_tree(int_type->get_backend(context->gogo()));
+ Type* left_type = left_expr->type();
+ Type* right_type = right_expr->type();
+
+ mpz_t zval;
+ mpz_init_set_ui(zval, 0UL);
+ Expression* zexpr = Expression::make_integer(&zval, NULL, location);
+ mpz_clear(zval);
enum tree_code code;
switch (op)
@@ -6436,21 +6508,17 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
go_unreachable();
}
+ // FIXME: Computing the tree here means it will be computed multiple times,
+ // which is wasteful. This is a temporary modification until all tree code
+ // here can be replaced with frontend expressions.
+ tree left_tree = left_expr->get_tree(context);
+ tree right_tree = right_expr->get_tree(context);
if (left_type->is_string_type() && right_type->is_string_type())
{
- Type* st = Type::make_string_type();
- tree string_type = type_to_tree(st->get_backend(context->gogo()));
- static tree string_compare_decl;
- left_tree = Gogo::call_builtin(&string_compare_decl,
- location,
- "__go_strcmp",
- 2,
- int_type_tree,
- string_type,
- left_tree,
- string_type,
- right_tree);
- right_tree = build_int_cst_type(int_type_tree, 0);
+ Expression* strcmp_call = Runtime::make_call(Runtime::STRCMP, location, 2,
+ left_expr, right_expr);
+ left_tree = strcmp_call->get_tree(context);
+ right_tree = zexpr->get_tree(context);
}
else if ((left_type->interface_type() != NULL
&& right_type->interface_type() == NULL
@@ -6463,154 +6531,61 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
if (left_type->interface_type() == NULL)
{
std::swap(left_type, right_type);
- std::swap(left_tree, right_tree);
+ std::swap(left_expr, right_expr);
}
// The right operand is not an interface. We need to take its
// address if it is not a pointer.
- tree make_tmp;
- tree arg;
+ Expression* pointer_arg = NULL;
if (right_type->points_to() != NULL)
- {
- make_tmp = NULL_TREE;
- arg = right_tree;
- }
- else if (TREE_ADDRESSABLE(TREE_TYPE(right_tree))
- || (TREE_CODE(right_tree) != CONST_DECL
- && DECL_P(right_tree)))
- {
- make_tmp = NULL_TREE;
- arg = build_fold_addr_expr_loc(location.gcc_location(), right_tree);
- if (DECL_P(right_tree))
- TREE_ADDRESSABLE(right_tree) = 1;
- }
+ pointer_arg = right_expr;
else
{
- tree tmp = create_tmp_var(TREE_TYPE(right_tree),
- get_name(right_tree));
- DECL_IGNORED_P(tmp) = 0;
- DECL_INITIAL(tmp) = right_tree;
- TREE_ADDRESSABLE(tmp) = 1;
- make_tmp = build1(DECL_EXPR, void_type_node, tmp);
- SET_EXPR_LOCATION(make_tmp, location.gcc_location());
- arg = build_fold_addr_expr_loc(location.gcc_location(), tmp);
- }
- arg = fold_convert_loc(location.gcc_location(), ptr_type_node, arg);
-
- Bexpression* descriptor_bexpr =
- right_type->type_descriptor_pointer(context->gogo(), location);
- tree descriptor = expr_to_tree(descriptor_bexpr);
-
- if (left_type->interface_type()->is_empty())
- {
- static tree empty_interface_value_compare_decl;
- left_tree = Gogo::call_builtin(&empty_interface_value_compare_decl,
- location,
- "__go_empty_interface_value_compare",
- 3,
- int_type_tree,
- TREE_TYPE(left_tree),
- left_tree,
- TREE_TYPE(descriptor),
- descriptor,
- ptr_type_node,
- arg);
- if (left_tree == error_mark_node)
- return error_mark_node;
- // This can panic if the type is not comparable.
- TREE_NOTHROW(empty_interface_value_compare_decl) = 0;
+ go_assert(right_expr->is_addressable());
+ pointer_arg = Expression::make_unary(OPERATOR_AND, right_expr,
+ location);
}
- else
- {
- static tree interface_value_compare_decl;
- left_tree = Gogo::call_builtin(&interface_value_compare_decl,
- location,
- "__go_interface_value_compare",
- 3,
- int_type_tree,
- TREE_TYPE(left_tree),
- left_tree,
- TREE_TYPE(descriptor),
- descriptor,
- ptr_type_node,
- arg);
- if (left_tree == error_mark_node)
- return error_mark_node;
- // This can panic if the type is not comparable.
- TREE_NOTHROW(interface_value_compare_decl) = 0;
- }
- right_tree = build_int_cst_type(int_type_tree, 0);
- if (make_tmp != NULL_TREE)
- left_tree = build2(COMPOUND_EXPR, TREE_TYPE(left_tree), make_tmp,
- left_tree);
+ Expression* descriptor_expr = Expression::make_type_descriptor(right_type,
+ location);
+ Call_expression* iface_valcmp =
+ Runtime::make_call((left_type->interface_type()->is_empty()
+ ? Runtime::EMPTY_INTERFACE_VALUE_COMPARE
+ : Runtime::INTERFACE_VALUE_COMPARE),
+ location, 3, left_expr, descriptor_expr,
+ pointer_arg);
+ left_tree = iface_valcmp->get_tree(context);
+ right_tree = zexpr->get_tree(context);
}
else if (left_type->interface_type() != NULL
&& right_type->interface_type() != NULL)
{
+ Runtime::Function compare_function;
if (left_type->interface_type()->is_empty()
&& right_type->interface_type()->is_empty())
- {
- static tree empty_interface_compare_decl;
- left_tree = Gogo::call_builtin(&empty_interface_compare_decl,
- location,
- "__go_empty_interface_compare",
- 2,
- int_type_tree,
- TREE_TYPE(left_tree),
- left_tree,
- TREE_TYPE(right_tree),
- right_tree);
- if (left_tree == error_mark_node)
- return error_mark_node;
- // This can panic if the type is uncomparable.
- TREE_NOTHROW(empty_interface_compare_decl) = 0;
- }
+ compare_function = Runtime::EMPTY_INTERFACE_COMPARE;
else if (!left_type->interface_type()->is_empty()
&& !right_type->interface_type()->is_empty())
- {
- static tree interface_compare_decl;
- left_tree = Gogo::call_builtin(&interface_compare_decl,
- location,
- "__go_interface_compare",
- 2,
- int_type_tree,
- TREE_TYPE(left_tree),
- left_tree,
- TREE_TYPE(right_tree),
- right_tree);
- if (left_tree == error_mark_node)
- return error_mark_node;
- // This can panic if the type is uncomparable.
- TREE_NOTHROW(interface_compare_decl) = 0;
- }
+ compare_function = Runtime::INTERFACE_COMPARE;
else
{
if (left_type->interface_type()->is_empty())
{
go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
std::swap(left_type, right_type);
- std::swap(left_tree, right_tree);
+ std::swap(left_expr, right_expr);
}
go_assert(!left_type->interface_type()->is_empty());
go_assert(right_type->interface_type()->is_empty());
- static tree interface_empty_compare_decl;
- left_tree = Gogo::call_builtin(&interface_empty_compare_decl,
- location,
- "__go_interface_empty_compare",
- 2,
- int_type_tree,
- TREE_TYPE(left_tree),
- left_tree,
- TREE_TYPE(right_tree),
- right_tree);
- if (left_tree == error_mark_node)
- return error_mark_node;
- // This can panic if the type is uncomparable.
- TREE_NOTHROW(interface_empty_compare_decl) = 0;
+ compare_function = Runtime::INTERFACE_EMPTY_COMPARE;
}
- right_tree = build_int_cst_type(int_type_tree, 0);
+ Call_expression* ifacecmp_call =
+ Runtime::make_call(compare_function, location, 2,
+ left_expr, right_expr);
+
+ left_tree = ifacecmp_call->get_tree(context);
+ right_tree = zexpr->get_tree(context);
}
if (left_type->is_nil_type()
@@ -10402,6 +10377,10 @@ class Array_index_expression : public Expression
do_address_taken(bool escapes)
{ this->array_->address_taken(escapes); }
+ void
+ do_issue_nil_check()
+ { this->array_->issue_nil_check(); }
+
tree
do_get_tree(Translate_context*);
@@ -11891,14 +11870,11 @@ Interface_field_reference_expression::do_get_tree(Translate_context* context)
// Note that we are evaluating this->expr_ twice, but that is OK
// because in the lowering pass we forced it into a temporary
// variable.
- tree expr_tree = this->expr_->get_tree(context);
tree nil_check_tree = Expression::comparison_tree(context,
Type::lookup_bool_type(),
OPERATOR_EQEQ,
- this->expr_->type(),
- expr_tree,
- Type::make_nil_type(),
- null_pointer_node,
+ this->expr_,
+ Expression::make_nil(loc),
loc);
tree crash = context->gogo()->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
loc);
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index a94330dc4d7..e447418b949 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -613,6 +613,11 @@ class Expression
address_taken(bool escapes)
{ this->do_address_taken(escapes); }
+ // Note that a nil check must be issued for this expression.
+ void
+ issue_nil_check()
+ { this->do_issue_nil_check(); }
+
// Return whether this expression must be evaluated in order
// according to the order of evaluation rules. This is basically
// true of all expressions with side-effects.
@@ -650,12 +655,11 @@ class Expression
Type* rhs_type, tree rhs_tree,
bool for_type_guard, Location);
- // Return a tree implementing the comparison LHS_TREE OP RHS_TREE.
+ // Return a tree implementing the comparison LHS_EXPR OP RHS_EXPR.
// TYPE is the type of both sides.
static tree
comparison_tree(Translate_context*, Type* result_type, Operator op,
- Type* left_type, tree left_tree, Type* right_type,
- tree right_tree, Location);
+ Expression* left_expr, Expression* right_expr, Location);
// Return the backend expression for the numeric constant VAL.
static Bexpression*
@@ -742,6 +746,11 @@ class Expression
do_address_taken(bool)
{ }
+ // Child class implements issuing a nil check if the address is taken.
+ virtual void
+ do_issue_nil_check()
+ { }
+
// Child class implements whether this expression must be evaluated
// in order.
virtual bool
@@ -1296,6 +1305,9 @@ class Binary_expression : public Expression
lower_array_comparison(Gogo*, Statement_inserter*);
Expression*
+ lower_interface_value_comparison(Gogo*, Statement_inserter*);
+
+ Expression*
lower_compare_to_memcmp(Gogo*, Statement_inserter*);
Expression*
@@ -1721,6 +1733,9 @@ class Index_expression : public Parser_expression
void
do_dump_expression(Ast_dump_context*) const;
+ void
+ do_issue_nil_check()
+ { this->left_->issue_nil_check(); }
private:
// The expression being indexed.
Expression* left_;
@@ -2011,6 +2026,10 @@ class Field_reference_expression : public Expression
do_address_taken(bool escapes)
{ this->expr_->address_taken(escapes); }
+ void
+ do_issue_nil_check()
+ { this->expr_->issue_nil_check(); }
+
tree
do_get_tree(Translate_context*);
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index 3793b839b55..12a0889397d 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -9,6 +9,7 @@
#include "toplev.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-iterator.h"
#include "cgraph.h"
#include "langhooks.h"
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index ea68c43714b..7451a7bcff6 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -10,6 +10,7 @@
#include "intl.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
#include "real.h"
#include "convert.h"
@@ -8847,8 +8848,7 @@ Type::add_local_methods_for_type(const Named_type* nt,
bool is_value_method = (is_embedded_pointer
|| !Type::method_expects_pointer(no));
Method* m = new Named_method(no, field_indexes, depth, is_value_method,
- (needs_stub_method
- || (depth > 0 && is_value_method)));
+ (needs_stub_method || depth > 0));
if (!(*methods)->insert(no->name(), m))
delete m;
}
diff --git a/gcc/graphite-blocking.c b/gcc/graphite-blocking.c
index 1fff36c53bc..da457d20da1 100644
--- a/gcc/graphite-blocking.c
+++ b/gcc/graphite-blocking.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "cfgloop.h"
diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c
index ce3c5bd0792..8f17934710d 100644
--- a/gcc/graphite-clast-to-gimple.c
+++ b/gcc/graphite-clast-to-gimple.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop.h"
diff --git a/gcc/graphite-dependences.c b/gcc/graphite-dependences.c
index 417ea2cd153..f9f7004cb1d 100644
--- a/gcc/graphite-dependences.c
+++ b/gcc/graphite-dependences.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "tree-pass.h"
#include "cfgloop.h"
diff --git a/gcc/graphite-interchange.c b/gcc/graphite-interchange.c
index 36e1b55757d..8690313da35 100644
--- a/gcc/graphite-interchange.c
+++ b/gcc/graphite-interchange.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "cfgloop.h"
diff --git a/gcc/graphite-optimize-isl.c b/gcc/graphite-optimize-isl.c
index d039c1b74e1..2260c507f86 100644
--- a/gcc/graphite-optimize-isl.c
+++ b/gcc/graphite-optimize-isl.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "cfgloop.h"
diff --git a/gcc/graphite-poly.c b/gcc/graphite-poly.c
index 2749555c371..d75359e8537 100644
--- a/gcc/graphite-poly.c
+++ b/gcc/graphite-poly.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "gimple-pretty-print.h"
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c
index f1dd455fb05..7b0ae7ea74d 100644
--- a/gcc/graphite-scop-detection.c
+++ b/gcc/graphite-scop-detection.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index 342cf7b1189..11c61759548 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -35,6 +35,9 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/graphite.c b/gcc/graphite.c
index 176c47c980e..5223de959d5 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop.h"
#include "tree-dump.h"
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 728d51b7308..aa3ffe3be30 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -8589,8 +8589,8 @@ ready_remove_first_dispatch (struct ready_list *ready)
rtx insn = ready_element (ready, 0);
if (ready->n_ready == 1
- || INSN_CODE (insn) < 0
|| !INSN_P (insn)
+ || INSN_CODE (insn) < 0
|| !active_insn_p (insn)
|| targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
return ready_remove_first (ready);
@@ -8599,8 +8599,8 @@ ready_remove_first_dispatch (struct ready_list *ready)
{
insn = ready_element (ready, i);
- if (INSN_CODE (insn) < 0
- || !INSN_P (insn)
+ if (!INSN_P (insn)
+ || INSN_CODE (insn) < 0
|| !active_insn_p (insn))
continue;
@@ -8619,8 +8619,8 @@ ready_remove_first_dispatch (struct ready_list *ready)
{
insn = ready_element (ready, i);
- if (INSN_CODE (insn) < 0
- || !INSN_P (insn)
+ if (!INSN_P (insn)
+ || INSN_CODE (insn) < 0
|| !active_insn_p (insn))
continue;
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index fafff9d0925..17d26c583c7 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3694,7 +3694,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
/* Wire together the blocks again. */
if (current_ir_type () == IR_RTL_CFGLAYOUT)
single_succ_edge (test_bb)->flags |= EDGE_FALLTHRU;
- else
+ else if (trap_bb == then_bb)
{
rtx lab, newjump;
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 445872387d8..2231c77ad66 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see
#include "coverage.h"
#include "ggc.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index f4cb72a9c2b..85f8e5df59f 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -909,7 +909,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
/* Capping edge->count to max_count. edge->count can be larger than
max_count if an inline adds new edges which increase max_count
after max_count is computed. */
- int edge_count = edge->count > max_count ? max_count : edge->count;
+ gcov_type edge_count = edge->count > max_count ? max_count : edge->count;
sreal_init (&relbenefit_real, relbenefit, 0);
sreal_init (&growth_real, growth, 0);
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index 1260069207e..9b8ae3971ea 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "tree-pass.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "ggc.h"
#include "flags.h"
#include "target.h"
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index f24c4036579..e7b85a24ff8 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -22,6 +22,10 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "langhooks.h"
#include "ggc.h"
#include "target.h"
@@ -2454,7 +2458,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
ie->callee->order);
return NULL;
}
- callee = cgraph_get_create_real_symbol_node (target);
+ callee = cgraph_get_create_node (target);
}
ipa_check_create_node_params ();
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 50bf500b172..9963b39f461 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-niter.h"
#include "tree-inline.h"
@@ -397,6 +399,7 @@ better_state (enum pure_const_state_e *state, bool *looping,
*looping = looping2;
else
*looping = MIN (*looping, looping2);
+ *state = state2;
}
else if (state2 != IPA_NEITHER)
*looping = MIN (*looping, looping2);
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 849868ca68c..e55b3f59dbc 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -79,6 +79,10 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "target.h"
#include "ipa-prop.h"
#include "gimple-ssa.h"
diff --git a/gcc/ipa.c b/gcc/ipa.c
index aef437a46f5..f43986214d1 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "tree-pass.h"
#include "gimple.h"
+#include "gimplify.h"
#include "ggc.h"
#include "flags.h"
#include "pointer-set.h"
@@ -355,7 +356,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (DECL_ABSTRACT_ORIGIN (node->decl))
{
struct cgraph_node *origin_node
- = cgraph_get_create_real_symbol_node (DECL_ABSTRACT_ORIGIN (node->decl));
+ = cgraph_get_create_node (DECL_ABSTRACT_ORIGIN (node->decl));
origin_node->used_as_abstract_origin = true;
enqueue_node (origin_node, &first, reachable);
}
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 295cd5327d7..6c52a2b7245 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -142,6 +142,15 @@ struct allocno_color_data
used to restore original hard reg costs of allocnos connected to
this allocno by copies. */
struct update_cost_record *update_cost_records;
+ /* Threads. We collect allocnos connected by copies into threads
+ and try to assign hard regs to allocnos by threads. */
+ /* Allocno representing all thread. */
+ ira_allocno_t first_thread_allocno;
+ /* Allocnos in thread forms a cycle list through the following
+ member. */
+ ira_allocno_t next_thread_allocno;
+ /* All thread frequency. Defined only for first thread allocno. */
+ int thread_freq;
};
/* See above. */
@@ -1863,6 +1872,252 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
+/* An array used to sort copies. */
+static ira_copy_t *sorted_copies;
+
+/* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
+ used to find a conflict for new allocnos or allocnos with the
+ different allocno classes. */
+static bool
+allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
+{
+ rtx reg1, reg2;
+ int i, j;
+ int n1 = ALLOCNO_NUM_OBJECTS (a1);
+ int n2 = ALLOCNO_NUM_OBJECTS (a2);
+
+ if (a1 == a2)
+ return false;
+ reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
+ reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
+ if (reg1 != NULL && reg2 != NULL
+ && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
+ return false;
+
+ for (i = 0; i < n1; i++)
+ {
+ ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
+
+ for (j = 0; j < n2; j++)
+ {
+ ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
+
+ if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
+ OBJECT_LIVE_RANGES (c2)))
+ return true;
+ }
+ }
+ return false;
+}
+
+/* The function is used to sort copies according to their execution
+ frequencies. */
+static int
+copy_freq_compare_func (const void *v1p, const void *v2p)
+{
+ ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
+ int pri1, pri2;
+
+ pri1 = cp1->freq;
+ pri2 = cp2->freq;
+ if (pri2 - pri1)
+ return pri2 - pri1;
+
+ /* If freqencies are equal, sort by copies, so that the results of
+ qsort leave nothing to chance. */
+ return cp1->num - cp2->num;
+}
+
+
+
+/* Return true if any allocno from thread of A1 conflicts with any
+ allocno from thread A2. */
+static bool
+allocno_thread_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
+{
+ ira_allocno_t a, conflict_a;
+
+ for (a = ALLOCNO_COLOR_DATA (a2)->next_thread_allocno;;
+ a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
+ {
+ for (conflict_a = ALLOCNO_COLOR_DATA (a1)->next_thread_allocno;;
+ conflict_a = ALLOCNO_COLOR_DATA (conflict_a)->next_thread_allocno)
+ {
+ if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
+ return true;
+ if (conflict_a == a1)
+ break;
+ }
+ if (a == a2)
+ break;
+ }
+ return false;
+}
+
+/* Merge two threads given correspondingly by their first allocnos T1
+ and T2 (more accurately merging T2 into T1). */
+static void
+merge_threads (ira_allocno_t t1, ira_allocno_t t2)
+{
+ ira_allocno_t a, next, last;
+
+ gcc_assert (t1 != t2
+ && ALLOCNO_COLOR_DATA (t1)->first_thread_allocno == t1
+ && ALLOCNO_COLOR_DATA (t2)->first_thread_allocno == t2);
+ for (last = t2, a = ALLOCNO_COLOR_DATA (t2)->next_thread_allocno;;
+ a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
+ {
+ ALLOCNO_COLOR_DATA (a)->first_thread_allocno = t1;
+ if (a == t2)
+ break;
+ last = a;
+ }
+ next = ALLOCNO_COLOR_DATA (t1)->next_thread_allocno;
+ ALLOCNO_COLOR_DATA (t1)->next_thread_allocno = t2;
+ ALLOCNO_COLOR_DATA (last)->next_thread_allocno = next;
+ ALLOCNO_COLOR_DATA (t1)->thread_freq += ALLOCNO_COLOR_DATA (t2)->thread_freq;
+}
+
+/* Create threads by processing CP_NUM copies from sorted)ciopeis. We
+ process the most expensive copies first. */
+static void
+form_threads_from_copies (int cp_num)
+{
+ ira_allocno_t a, thread1, thread2;
+ ira_copy_t cp;
+ int i, n;
+
+ qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
+ /* Form threads processing copies, most frequently executed
+ first. */
+ for (; cp_num != 0;)
+ {
+ for (i = 0; i < cp_num; i++)
+ {
+ cp = sorted_copies[i];
+ thread1 = ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno;
+ thread2 = ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno;
+ if (thread1 == thread2)
+ continue;
+ if (! allocno_thread_conflict_p (thread1, thread2))
+ {
+ if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+ fprintf
+ (ira_dump_file,
+ " Forming thread by copy %d:a%dr%d-a%dr%d (freq=%d):\n",
+ cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
+ ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
+ cp->freq);
+ merge_threads (thread1, thread2);
+ if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
+ {
+ thread1 = ALLOCNO_COLOR_DATA (thread1)->first_thread_allocno;
+ fprintf (ira_dump_file, " Result (freq=%d): a%dr%d(%d)",
+ ALLOCNO_COLOR_DATA (thread1)->thread_freq,
+ ALLOCNO_NUM (thread1), ALLOCNO_REGNO (thread1),
+ ALLOCNO_FREQ (thread1));
+ for (a = ALLOCNO_COLOR_DATA (thread1)->next_thread_allocno;
+ a != thread1;
+ a = ALLOCNO_COLOR_DATA (a)->next_thread_allocno)
+ fprintf (ira_dump_file, " a%dr%d(%d)",
+ ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
+ ALLOCNO_FREQ (a));
+ fprintf (ira_dump_file, "\n");
+ }
+ i++;
+ break;
+ }
+ }
+ /* Collect the rest of copies. */
+ for (n = 0; i < cp_num; i++)
+ {
+ cp = sorted_copies[i];
+ if (ALLOCNO_COLOR_DATA (cp->first)->first_thread_allocno
+ != ALLOCNO_COLOR_DATA (cp->second)->first_thread_allocno)
+ sorted_copies[n++] = cp;
+ }
+ cp_num = n;
+ }
+}
+
+/* Create threads by processing copies of all alocnos from BUCKET. We
+ process the most expensive copies first. */
+static void
+form_threads_from_bucket (ira_allocno_t bucket)
+{
+ ira_allocno_t a;
+ ira_copy_t cp, next_cp;
+ int cp_num = 0;
+
+ for (a = bucket; a != NULL; a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
+ {
+ for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
+ {
+ if (cp->first == a)
+ {
+ next_cp = cp->next_first_allocno_copy;
+ sorted_copies[cp_num++] = cp;
+ }
+ else if (cp->second == a)
+ next_cp = cp->next_second_allocno_copy;
+ else
+ gcc_unreachable ();
+ }
+ }
+ form_threads_from_copies (cp_num);
+}
+
+/* Create threads by processing copies of colorable allocno A. We
+ process most expensive copies first. */
+static void
+form_threads_from_colorable_allocno (ira_allocno_t a)
+{
+ ira_allocno_t another_a;
+ ira_copy_t cp, next_cp;
+ int cp_num = 0;
+
+ for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
+ {
+ if (cp->first == a)
+ {
+ next_cp = cp->next_first_allocno_copy;
+ another_a = cp->second;
+ }
+ else if (cp->second == a)
+ {
+ next_cp = cp->next_second_allocno_copy;
+ another_a = cp->first;
+ }
+ else
+ gcc_unreachable ();
+ if ((! ALLOCNO_COLOR_DATA (another_a)->in_graph_p
+ && !ALLOCNO_COLOR_DATA (another_a)->may_be_spilled_p)
+ || ALLOCNO_COLOR_DATA (another_a)->colorable_p)
+ sorted_copies[cp_num++] = cp;
+ }
+ form_threads_from_copies (cp_num);
+}
+
+/* Form initial threads which contain only one allocno. */
+static void
+init_allocno_threads (void)
+{
+ ira_allocno_t a;
+ unsigned int j;
+ bitmap_iterator bi;
+
+ EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
+ {
+ a = ira_allocnos[j];
+ /* Set up initial thread data: */
+ ALLOCNO_COLOR_DATA (a)->first_thread_allocno
+ = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a;
+ ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a);
+ }
+}
+
+
+
/* This page contains the allocator based on the Chaitin-Briggs algorithm. */
/* Bucket of allocnos that can colored currently without spilling. */
@@ -1923,9 +2178,19 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
{
ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
- int diff, a1_freq, a2_freq, a1_num, a2_num;
+ int diff, freq1, freq2, a1_num, a2_num;
+ ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno;
+ ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
+ freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
+ freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
+ if ((diff = freq1 - freq2) != 0)
+ return diff;
+
+ if ((diff = ALLOCNO_NUM (t2) - ALLOCNO_NUM (t1)) != 0)
+ return diff;
+
/* Push pseudos requiring less hard registers first. It means that
we will assign pseudos requiring more hard registers first
avoiding creation small holes in free hard register file into
@@ -1933,10 +2198,12 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
- ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
return diff;
- a1_freq = ALLOCNO_FREQ (a1);
- a2_freq = ALLOCNO_FREQ (a2);
- if ((diff = a1_freq - a2_freq) != 0)
+
+ freq1 = ALLOCNO_FREQ (a1);
+ freq2 = ALLOCNO_FREQ (a2);
+ if ((diff = freq1 - freq2) != 0)
return diff;
+
a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
if ((diff = a2_num - a1_num) != 0)
@@ -1973,22 +2240,16 @@ sort_bucket (ira_allocno_t *bucket_ptr,
*bucket_ptr = head;
}
-/* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
+/* Add ALLOCNO to colorable bucket maintaining the order according
their priority. ALLOCNO should be not in a bucket before the
call. */
static void
-add_allocno_to_ordered_bucket (ira_allocno_t allocno,
- ira_allocno_t *bucket_ptr)
+add_allocno_to_ordered_colorable_bucket (ira_allocno_t allocno)
{
ira_allocno_t before, after;
- if (bucket_ptr == &uncolorable_allocno_bucket
- && ALLOCNO_CLASS (allocno) != NO_REGS)
- {
- uncolorable_allocnos_num++;
- ira_assert (uncolorable_allocnos_num > 0);
- }
- for (before = *bucket_ptr, after = NULL;
+ form_threads_from_colorable_allocno (allocno);
+ for (before = colorable_allocno_bucket, after = NULL;
before != NULL;
after = before,
before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
@@ -1997,7 +2258,7 @@ add_allocno_to_ordered_bucket (ira_allocno_t allocno,
ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
if (after == NULL)
- *bucket_ptr = allocno;
+ colorable_allocno_bucket = allocno;
else
ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
if (before != NULL)
@@ -2078,8 +2339,7 @@ push_allocno_to_stack (ira_allocno_t a)
{
delete_allocno_from_bucket
(conflict_a, &uncolorable_allocno_bucket);
- add_allocno_to_ordered_bucket
- (conflict_a, &colorable_allocno_bucket);
+ add_allocno_to_ordered_colorable_bucket (conflict_a);
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
{
fprintf (ira_dump_file, " Making");
@@ -2123,6 +2383,7 @@ remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
static void
push_only_colorable (void)
{
+ form_threads_from_bucket (colorable_allocno_bucket);
sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
for (;colorable_allocno_bucket != NULL;)
remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
@@ -2911,6 +3172,7 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
n++;
}
+ init_allocno_threads ();
/* Color all mentioned allocnos including transparent ones. */
color_allocnos ();
/* Process caps. They are processed just once. */
@@ -3041,7 +3303,7 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
}
}
ira_free (allocno_color_data);
- EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
+ EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
{
a = ira_allocnos[j];
ALLOCNO_ADD_DATA (a) = NULL;
@@ -3327,41 +3589,6 @@ ira_reassign_conflict_allocnos (int start_regno)
/* This page contains functions used to find conflicts using allocno
live ranges. */
-/* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is
- used to find a conflict for new allocnos or allocnos with the
- different allocno classes. */
-static bool
-allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
-{
- rtx reg1, reg2;
- int i, j;
- int n1 = ALLOCNO_NUM_OBJECTS (a1);
- int n2 = ALLOCNO_NUM_OBJECTS (a2);
-
- if (a1 == a2)
- return false;
- reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
- reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
- if (reg1 != NULL && reg2 != NULL
- && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
- return false;
-
- for (i = 0; i < n1; i++)
- {
- ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
-
- for (j = 0; j < n2; j++)
- {
- ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
-
- if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
- OBJECT_LIVE_RANGES (c2)))
- return true;
- }
- }
- return false;
-}
-
#ifdef ENABLE_IRA_CHECKING
/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
@@ -3423,24 +3650,6 @@ static coalesce_data_t allocno_coalesce_data;
/* Macro to access the data concerning coalescing. */
#define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
-/* The function is used to sort allocnos according to their execution
- frequencies. */
-static int
-copy_freq_compare_func (const void *v1p, const void *v2p)
-{
- ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
- int pri1, pri2;
-
- pri1 = cp1->freq;
- pri2 = cp2->freq;
- if (pri2 - pri1)
- return pri2 - pri1;
-
- /* If freqencies are equal, sort by copies, so that the results of
- qsort leave nothing to chance. */
- return cp1->num - cp2->num;
-}
-
/* Merge two sets of coalesced allocnos given correspondingly by
allocnos A1 and A2 (more accurately merging A2 set into A1
set). */
@@ -3511,13 +3720,11 @@ static void
coalesce_allocnos (void)
{
ira_allocno_t a;
- ira_copy_t cp, next_cp, *sorted_copies;
+ ira_copy_t cp, next_cp;
unsigned int j;
int i, n, cp_num, regno;
bitmap_iterator bi;
- sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
- * sizeof (ira_copy_t));
cp_num = 0;
/* Collect copies. */
EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
@@ -3581,7 +3788,6 @@ coalesce_allocnos (void)
}
cp_num = n;
}
- ira_free (sorted_copies);
}
/* Usage cost and order number of coalesced allocno set to which
@@ -4458,6 +4664,8 @@ ira_initiate_assign (void)
consideration_allocno_bitmap = ira_allocate_bitmap ();
initiate_cost_update ();
allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
+ sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
+ * sizeof (ira_copy_t));
}
/* Deallocate data used by assign_hard_reg. */
@@ -4468,6 +4676,7 @@ ira_finish_assign (void)
ira_free_bitmap (consideration_allocno_bitmap);
finish_cost_update ();
ira_free (allocno_priorities);
+ ira_free (sorted_copies);
}
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 424b99c2c53..d7299e658d7 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -1224,6 +1224,9 @@ record_operand_costs (rtx insn, enum reg_class *pref)
preferred class is very expensive as the source of a copy
instruction. */
if ((set = single_set (insn)) != NULL_RTX
+ /* In rare cases the single set insn might have less 2 operands
+ as the source can be a fixed special reg. */
+ && recog_data.n_operands > 1
&& ops[0] == SET_DEST (set) && ops[1] == SET_SRC (set))
{
int regno, other_regno;
diff --git a/gcc/ira.c b/gcc/ira.c
index 10e71d97db3..dbc5a0ad997 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -192,7 +192,14 @@ along with GCC; see the file COPYING3. If not see
this point. There is some freedom in the order of putting
allocnos on the stack which can affect the final result of
the allocation. IRA uses some heuristics to improve the
- order.
+ order. The major one is to form *threads* from colorable
+ allocnos and push them on the stack by threads. Thread is a
+ set of non-conflicting colorable allocnos connected by
+ copies. The thread contains allocnos from the colorable
+ bucket or colorable allocnos already pushed onto the coloring
+ stack. Pushing thread allocnos one after another onto the
+ stack increases chances of removing copies when the allocnos
+ get the same hard reg.
We also use a modification of Chaitin-Briggs algorithm which
works for intersected register classes of allocnos. To
@@ -4515,9 +4522,6 @@ find_moveable_pseudos (void)
pseudo_replaced_reg.release ();
pseudo_replaced_reg.safe_grow_cleared (max_regs);
- df_analyze ();
- calculate_dominance_info (CDI_DOMINATORS);
-
i = 0;
bitmap_initialize (&live, 0);
bitmap_initialize (&used, 0);
@@ -4830,14 +4834,196 @@ find_moveable_pseudos (void)
free (bb_moveable_reg_sets);
last_moveable_pseudo = max_reg_num ();
+}
- fix_reg_equiv_init ();
- expand_reg_info ();
- regstat_free_n_sets_and_refs ();
- regstat_free_ri ();
- regstat_init_n_sets_and_refs ();
- regstat_compute_ri ();
- free_dominance_info (CDI_DOMINATORS);
+
+/* If insn is interesting for parameter range-splitting shring-wrapping
+ preparation, i.e. it is a single set from a hard register to a pseudo, which
+ is live at CALL_DOM, return the destination. Otherwise return NULL. */
+
+static rtx
+interesting_dest_for_shprep (rtx insn, basic_block call_dom)
+{
+ rtx set = single_set (insn);
+ if (!set)
+ return NULL;
+ rtx src = SET_SRC (set);
+ rtx dest = SET_DEST (set);
+ if (!REG_P (src) || !HARD_REGISTER_P (src)
+ || !REG_P (dest) || HARD_REGISTER_P (dest)
+ || (call_dom && !bitmap_bit_p (df_get_live_in (call_dom), REGNO (dest))))
+ return NULL;
+ return dest;
+}
+
+/* Split live ranges of pseudos that are loaded from hard registers in the
+ first BB in a BB that dominates all non-sibling call if such a BB can be
+ found and is not in a loop. Return true if the function has made any
+ changes. */
+
+static bool
+split_live_ranges_for_shrink_wrap (void)
+{
+ basic_block bb, call_dom = NULL;
+ basic_block first = single_succ (ENTRY_BLOCK_PTR);
+ rtx insn, last_interesting_insn = NULL;
+ bitmap_head need_new, reachable;
+ vec<basic_block> queue;
+
+ if (!flag_shrink_wrap)
+ return false;
+
+ bitmap_initialize (&need_new, 0);
+ bitmap_initialize (&reachable, 0);
+ queue.create (n_basic_blocks);
+
+ FOR_EACH_BB (bb)
+ FOR_BB_INSNS (bb, insn)
+ if (CALL_P (insn) && !SIBLING_CALL_P (insn))
+ {
+ if (bb == first)
+ {
+ bitmap_clear (&need_new);
+ bitmap_clear (&reachable);
+ queue.release ();
+ return false;
+ }
+
+ bitmap_set_bit (&need_new, bb->index);
+ bitmap_set_bit (&reachable, bb->index);
+ queue.quick_push (bb);
+ break;
+ }
+
+ if (queue.is_empty ())
+ {
+ bitmap_clear (&need_new);
+ bitmap_clear (&reachable);
+ queue.release ();
+ return false;
+ }
+
+ while (!queue.is_empty ())
+ {
+ edge e;
+ edge_iterator ei;
+
+ bb = queue.pop ();
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->dest != EXIT_BLOCK_PTR
+ && bitmap_set_bit (&reachable, e->dest->index))
+ queue.quick_push (e->dest);
+ }
+ queue.release ();
+
+ FOR_BB_INSNS (first, insn)
+ {
+ rtx dest = interesting_dest_for_shprep (insn, NULL);
+ if (!dest)
+ continue;
+
+ if (DF_REG_DEF_COUNT (REGNO (dest)) > 1)
+ {
+ bitmap_clear (&need_new);
+ bitmap_clear (&reachable);
+ return false;
+ }
+
+ for (df_ref use = DF_REG_USE_CHAIN (REGNO(dest));
+ use;
+ use = DF_REF_NEXT_REG (use))
+ {
+ if (NONDEBUG_INSN_P (DF_REF_INSN (use))
+ && GET_CODE (DF_REF_REG (use)) == SUBREG)
+ {
+ /* This is necessary to avoid hitting an assert at
+ postreload.c:2294 in libstc++ testcases on x86_64-linux. I'm
+ not really sure what the probblem actually is there. */
+ bitmap_clear (&need_new);
+ bitmap_clear (&reachable);
+ return false;
+ }
+
+ int ubbi = DF_REF_BB (use)->index;
+ if (bitmap_bit_p (&reachable, ubbi))
+ bitmap_set_bit (&need_new, ubbi);
+ }
+ last_interesting_insn = insn;
+ }
+
+ bitmap_clear (&reachable);
+ if (!last_interesting_insn)
+ {
+ bitmap_clear (&need_new);
+ return false;
+ }
+
+ call_dom = nearest_common_dominator_for_set (CDI_DOMINATORS, &need_new);
+ bitmap_clear (&need_new);
+ if (call_dom == first)
+ return false;
+
+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+ while (bb_loop_depth (call_dom) > 0)
+ call_dom = get_immediate_dominator (CDI_DOMINATORS, call_dom);
+ loop_optimizer_finalize ();
+
+ if (call_dom == first)
+ return false;
+
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+ if (dominated_by_p (CDI_POST_DOMINATORS, first, call_dom))
+ {
+ free_dominance_info (CDI_POST_DOMINATORS);
+ return false;
+ }
+ free_dominance_info (CDI_POST_DOMINATORS);
+
+ if (dump_file)
+ fprintf (dump_file, "Will split live ranges of parameters at BB %i\n",
+ call_dom->index);
+
+ bool ret = false;
+ FOR_BB_INSNS (first, insn)
+ {
+ rtx dest = interesting_dest_for_shprep (insn, call_dom);
+ if (!dest)
+ continue;
+
+ rtx newreg = NULL_RTX;
+ df_ref use, next;
+ for (use = DF_REG_USE_CHAIN (REGNO(dest)); use; use = next)
+ {
+ rtx uin = DF_REF_INSN (use);
+ next = DF_REF_NEXT_REG (use);
+
+ basic_block ubb = BLOCK_FOR_INSN (uin);
+ if (ubb == call_dom
+ || dominated_by_p (CDI_DOMINATORS, ubb, call_dom))
+ {
+ if (!newreg)
+ newreg = ira_create_new_reg (dest);
+ validate_change (uin, DF_REF_LOC (use), newreg, true);
+ }
+ }
+
+ if (newreg)
+ {
+ rtx new_move = gen_move_insn (newreg, dest);
+ emit_insn_after (new_move, bb_note (call_dom));
+ if (dump_file)
+ {
+ fprintf (dump_file, "Split live-range of register ");
+ print_rtl_single (dump_file, dest);
+ }
+ ret = true;
+ }
+
+ if (insn == last_interesting_insn)
+ break;
+ }
+ apply_change_group ();
+ return ret;
}
/* Perform the second half of the transformation started in
@@ -5049,7 +5235,22 @@ ira (FILE *f)
allocation because of -O0 usage or because the function is too
big. */
if (ira_conflicts_p)
- find_moveable_pseudos ();
+ {
+ df_analyze ();
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ find_moveable_pseudos ();
+ if (split_live_ranges_for_shrink_wrap ())
+ df_analyze ();
+
+ fix_reg_equiv_init ();
+ expand_reg_info ();
+ regstat_free_n_sets_and_refs ();
+ regstat_free_ri ();
+ regstat_init_n_sets_and_refs ();
+ regstat_compute_ri ();
+ free_dominance_info (CDI_DOMINATORS);
+ }
max_regno_before_ira = max_reg_num ();
ira_setup_eliminable_regset (true);
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 4cb9e461a40..a474ccc0d7f 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,11 @@
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * java-gimplify.c: Include only gimplify.h and gimple.h as needed.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * java-gimplify.c: Include gimplify.h.
+
2013-11-07 Jeff Law <law@redhat.com>
* builtins.c (initialize_builtins): Provide __builtin_trap.
@@ -120,7 +128,7 @@
2012-07-16 Steven Bosscher <steven@gcc.gnu.org>
- * java-gimplify.c Include dumpfile.h instead of tree-dump.h
+ * java-gimplify.c: Include dumpfile.h instead of tree-dump.h
* Make-lang.in: Fix dependencies.
2012-07-11 Steven Bosscher <steven@gcc.gnu.org>
diff --git a/gcc/java/java-gimplify.c b/gcc/java/java-gimplify.c
index 6f159f8d829..f2d0460ae31 100644
--- a/gcc/java/java-gimplify.c
+++ b/gcc/java/java-gimplify.c
@@ -28,6 +28,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-tree.h"
#include "dumpfile.h"
#include "gimple.h"
+#include "gimplify.h"
static tree java_gimplify_block (tree);
static enum gimplify_status java_gimplify_modify_expr (tree *);
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 5d1457b1b22..ec0dd4d75ee 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tree-inline.h"
#include "gimple.h"
+#include "gimplify.h"
#include "rtl.h"
#include "insn-config.h"
#include "flags.h"
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index 0318ba9e5f6..8cc96af10fd 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "df.h"
#include "ggc.h"
-#include "gimple.h"
#include "tree-ssa-loop-niter.h"
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 6a52da8a662..99dbf96b7a5 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -482,6 +482,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
ref = LCC_NOT_FOUND;
streamer_write_hwi_stream (ob->main_stream, ref);
+ streamer_write_hwi_stream (ob->main_stream, node->tp_first_run);
+
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, node->local.local, 1);
bp_pack_value (&bp, node->externally_visible, 1);
@@ -1077,7 +1079,10 @@ input_node (struct lto_file_decl_data *file_data,
internal_error ("bytecode stream: found multiple instances of cgraph "
"node with uid %d", node->uid);
+ node->tp_first_run = streamer_read_uhwi (ib);
+
bp = streamer_read_bitpack (ib);
+
input_overwrite_node (file_data, node, tag, &bp);
/* Store a reference for now, and fix up later to be a pointer. */
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index bf823d0dcba..1a469391e66 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-ssanames.h"
@@ -927,7 +928,9 @@ input_function (tree fn_decl, struct data_in *data_in,
gimple_register_cfg_hooks ();
- node = cgraph_get_create_node (fn_decl);
+ node = cgraph_get_node (fn_decl);
+ if (!node)
+ node = cgraph_create_node (fn_decl);
input_struct_function_base (fn, data_in, ib);
input_cfg (ib_cfg, fn, node->count_materialization_scale);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index ff6d345fe32..dabf47f3cb7 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-pass.h"
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index ced6cf97908..2ebc07d4fb4 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "plugin-api.h"
#include "lto-streamer.h"
#include "ipa-utils.h"
+#include "ipa-inline.h"
/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
all edges and removing the old node. */
@@ -84,6 +85,12 @@ lto_cgraph_replace_node (struct cgraph_node *node,
if (node->decl != prevailing_node->decl)
cgraph_release_function_body (node);
+ /* Time profile merging */
+ if (node->tp_first_run)
+ prevailing_node->tp_first_run = prevailing_node->tp_first_run ?
+ MIN (prevailing_node->tp_first_run, node->tp_first_run) :
+ node->tp_first_run;
+
/* Finally remove the replaced node. */
cgraph_remove_node (node);
}
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index 0b08998372f..d54f32ca071 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -571,12 +571,15 @@ optimize_mode_switching (void)
info[bb->index].computing = last_mode;
/* Check for blocks without ANY mode requirements.
- N.B. because of MODE_AFTER, last_mode might still be different
- from no_mode. */
+ N.B. because of MODE_AFTER, last_mode might still
+ be different from no_mode, in which case we need to
+ mark the block as nontransparent. */
if (!any_set_required)
{
ptr = new_seginfo (no_mode, BB_END (bb), bb->index, live_now);
add_seginfo (info + bb->index, ptr);
+ if (last_mode != no_mode)
+ bitmap_clear_bit (transp[bb->index], j);
}
}
#if defined (MODE_ENTRY) && defined (MODE_EXIT)
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index e3be5f8d212..8777efba152 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,11 @@
+2013-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * objc-act.c: Include only gimplify.h and gimple.h as needed.
+
+2013-11-12 Andrew MacLeod <amacleod@redhat.com>
+
+ * objc-act.c: Include gimplify.h.
+
2013-11-07 Andrew MacLeod <amacleod@redhat.com>
* objc-act.c (objc_push_parm): Handle atomic qualifier.
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 112a7d1d65a..0b1b304e126 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
/* For enum gimplify_status */
#include "gimple.h"
+#include "gimplify.h"
/* For encode_method_prototype(). */
#include "objc-encoding.h"
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 8e4727cac75..f2268bce954 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -28,6 +28,10 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "rtl.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "tree-iterator.h"
#include "tree-inline.h"
#include "langhooks.h"
@@ -281,7 +285,7 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
int i;
struct omp_for_data_loop dummy_loop;
location_t loc = gimple_location (for_stmt);
- bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
+ bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_KIND_SIMD;
bool distribute = gimple_omp_for_kind (for_stmt)
== GF_OMP_FOR_KIND_DISTRIBUTE;
@@ -373,6 +377,10 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
case LT_EXPR:
case GT_EXPR:
break;
+ case NE_EXPR:
+ gcc_assert (gimple_omp_for_kind (for_stmt)
+ == GF_OMP_FOR_KIND_CILKSIMD);
+ break;
case LE_EXPR:
if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
@@ -999,7 +1007,7 @@ build_outer_var_ref (tree var, omp_context *ctx)
x = build_receiver_ref (var, by_ref, ctx);
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
{
/* #pragma omp simd isn't a worksharing construct, and can reference even
private vars in its linear etc. clauses. */
@@ -2226,7 +2234,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
if (ctx != NULL)
{
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
{
error_at (gimple_location (stmt),
"OpenMP constructs may not be nested inside simd region");
@@ -2249,7 +2257,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
switch (gimple_code (stmt))
{
case GIMPLE_OMP_FOR:
- if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
+ if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_KIND_SIMD)
return true;
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
{
@@ -2530,6 +2538,23 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Return true if FNDECL is a setjmp or a longjmp. */
+
+static bool
+setjmp_or_longjmp_p (const_tree fndecl)
+{
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
+ || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+ return true;
+
+ tree declname = DECL_NAME (fndecl);
+ if (!declname)
+ return false;
+ const char *name = IDENTIFIER_POINTER (declname);
+ return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
+}
+
/* Helper function for scan_omp.
@@ -2553,22 +2578,33 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
else if (is_gimple_call (stmt))
{
tree fndecl = gimple_call_fndecl (stmt);
- if (fndecl
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
- switch (DECL_FUNCTION_CODE (fndecl))
- {
- case BUILT_IN_GOMP_BARRIER:
- case BUILT_IN_GOMP_CANCEL:
- case BUILT_IN_GOMP_CANCELLATION_POINT:
- case BUILT_IN_GOMP_TASKYIELD:
- case BUILT_IN_GOMP_TASKWAIT:
- case BUILT_IN_GOMP_TASKGROUP_START:
- case BUILT_IN_GOMP_TASKGROUP_END:
- remove = !check_omp_nesting_restrictions (stmt, ctx);
- break;
- default:
- break;
- }
+ if (fndecl)
+ {
+ if (setjmp_or_longjmp_p (fndecl)
+ && ctx
+ && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
+ {
+ remove = true;
+ error_at (gimple_location (stmt),
+ "setjmp/longjmp inside simd construct");
+ }
+ else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_GOMP_BARRIER:
+ case BUILT_IN_GOMP_CANCEL:
+ case BUILT_IN_GOMP_CANCELLATION_POINT:
+ case BUILT_IN_GOMP_TASKYIELD:
+ case BUILT_IN_GOMP_TASKWAIT:
+ case BUILT_IN_GOMP_TASKGROUP_START:
+ case BUILT_IN_GOMP_TASKGROUP_END:
+ remove = !check_omp_nesting_restrictions (stmt, ctx);
+ break;
+ default:
+ break;
+ }
+ }
}
if (remove)
{
@@ -2961,7 +2997,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
bool reduction_omp_orig_ref = false;
int pass;
bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD);
int max_vf = 0;
tree lane = NULL_TREE, idx = NULL_TREE;
tree ivar = NULL_TREE, lvar = NULL_TREE;
@@ -3581,7 +3617,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
/* Don't add any barrier for #pragma omp simd or
#pragma omp distribute. */
if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
- || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
+ || gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_FOR)
gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
}
@@ -3660,7 +3696,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
}
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
{
simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
if (simduid)
@@ -3755,7 +3791,7 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
/* SIMD reductions are handled in lower_rec_input_clauses. */
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
return;
/* First see if there is exactly one reduction clause. Use OMP_ATOMIC
@@ -6787,7 +6823,7 @@ expand_omp_for (struct omp_region *region, gimple inner_stmt)
original loops from being detected. Fix that up. */
loops_state_set (LOOPS_NEED_FIXUP);
- if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_SIMD)
+ if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_KIND_SIMD)
expand_omp_simd (region, &fd);
else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
&& !fd.have_ordered)
@@ -8229,7 +8265,8 @@ execute_expand_omp (void)
static bool
gate_expand_omp (void)
{
- return ((flag_openmp != 0 || flag_openmp_simd != 0) && !seen_error ());
+ return ((flag_openmp != 0 || flag_openmp_simd != 0
+ || flag_enable_cilkplus != 0) && !seen_error ());
}
namespace {
@@ -10050,7 +10087,7 @@ execute_lower_omp (void)
/* This pass always runs, to provide PROP_gimple_lomp.
But there is nothing to do unless -fopenmp is given. */
- if (flag_openmp == 0 && flag_openmp_simd == 0)
+ if (flag_openmp == 0 && flag_openmp_simd == 0 && flag_enable_cilkplus == 0)
return 0;
all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
@@ -10170,12 +10207,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
error ("invalid entry to OpenMP structured block");
#endif
+ bool cilkplus_block = false;
+ if (flag_enable_cilkplus)
+ {
+ if ((branch_ctx
+ && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
+ || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
+ cilkplus_block = true;
+ }
+
/* If it's obvious we have an invalid entry, be specific about the error. */
if (branch_ctx == NULL)
- error ("invalid entry to OpenMP structured block");
+ {
+ if (cilkplus_block)
+ error ("invalid entry to Cilk Plus structured block");
+ else
+ error ("invalid entry to OpenMP structured block");
+ }
else
- /* Otherwise, be vague and lazy, but efficient. */
- error ("invalid branch to/from an OpenMP structured block");
+ {
+ /* Otherwise, be vague and lazy, but efficient. */
+ if (cilkplus_block)
+ error ("invalid branch to/from a Cilk Plus structured block");
+ else
+ error ("invalid branch to/from an OpenMP structured block");
+ }
gsi_replace (gsi_p, gimple_build_nop (), false);
return true;
@@ -10479,7 +10537,7 @@ diagnose_omp_structured_block_errors (void)
static bool
gate_diagnose_omp_blocks (void)
{
- return flag_openmp != 0;
+ return flag_openmp || flag_enable_cilkplus;
}
namespace {
diff --git a/gcc/passes.c b/gcc/passes.c
index 19e5869c14b..f45ed0aed1c 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1875,7 +1875,8 @@ execute_todo (unsigned int flags)
statistics_fini_pass ();
- do_per_function (execute_function_todo, (void *)(size_t) flags);
+ if (flags)
+ do_per_function (execute_function_todo, (void *)(size_t) flags);
/* Always remove functions just as before inlining: IPA passes might be
interested to see bodies of extern inline functions that are not inlined
@@ -2065,7 +2066,8 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
check_profile_consistency (pass->static_pass_number, 1, true);
- do_per_function (execute_function_dump, NULL);
+ if (dump_file)
+ do_per_function (execute_function_dump, NULL);
pass_fini_dump_file (pass);
current_pass = NULL;
@@ -2231,7 +2233,8 @@ execute_one_pass (struct opt_pass *pass)
check_profile_consistency (pass->static_pass_number, 1, true);
verify_interpass_invariants ();
- do_per_function (execute_function_dump, NULL);
+ if (dump_file)
+ do_per_function (execute_function_dump, NULL);
if (pass->type == IPA_PASS)
{
struct cgraph_node *node;
diff --git a/gcc/predict.c b/gcc/predict.c
index d164500d0c6..95f2be52243 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "cfgloop.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -2747,6 +2748,120 @@ estimate_loops (void)
BITMAP_FREE (tovisit);
}
+/* Drop the profile for NODE to guessed, and update its frequency based on
+ whether it is expected to be hot given the CALL_COUNT. */
+
+static void
+drop_profile (struct cgraph_node *node, gcov_type call_count)
+{
+ struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
+ /* In the case where this was called by another function with a
+ dropped profile, call_count will be 0. Since there are no
+ non-zero call counts to this function, we don't know for sure
+ whether it is hot, and therefore it will be marked normal below. */
+ bool hot = maybe_hot_count_p (NULL, call_count);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Dropping 0 profile for %s/%i. %s based on calls.\n",
+ cgraph_node_name (node), node->order,
+ hot ? "Function is hot" : "Function is normal");
+ /* We only expect to miss profiles for functions that are reached
+ via non-zero call edges in cases where the function may have
+ been linked from another module or library (COMDATs and extern
+ templates). See the comments below for handle_missing_profiles.
+ Also, only warn in cases where the missing counts exceed the
+ number of training runs. In certain cases with an execv followed
+ by a no-return call the profile for the no-return call is not
+ dumped and there can be a mismatch. */
+ if (!DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl)
+ && call_count > profile_info->runs)
+ {
+ if (flag_profile_correction)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Missing counts for called function %s/%i\n",
+ cgraph_node_name (node), node->order);
+ }
+ else
+ warning (0, "Missing counts for called function %s/%i",
+ cgraph_node_name (node), node->order);
+ }
+
+ profile_status_for_function (fn)
+ = (flag_guess_branch_prob ? PROFILE_GUESSED : PROFILE_ABSENT);
+ node->frequency
+ = hot ? NODE_FREQUENCY_HOT : NODE_FREQUENCY_NORMAL;
+}
+
+/* In the case of COMDAT routines, multiple object files will contain the same
+ function and the linker will select one for the binary. In that case
+ all the other copies from the profile instrument binary will be missing
+ profile counts. Look for cases where this happened, due to non-zero
+ call counts going to 0-count functions, and drop the profile to guessed
+ so that we can use the estimated probabilities and avoid optimizing only
+ for size.
+
+ The other case where the profile may be missing is when the routine
+ is not going to be emitted to the object file, e.g. for "extern template"
+ class methods. Those will be marked DECL_EXTERNAL. Emit a warning in
+ all other cases of non-zero calls to 0-count functions. */
+
+void
+handle_missing_profiles (void)
+{
+ struct cgraph_node *node;
+ int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
+ vec<struct cgraph_node *> worklist;
+ worklist.create (64);
+
+ /* See if 0 count function has non-0 count callers. In this case we
+ lost some profile. Drop its function profile to PROFILE_GUESSED. */
+ FOR_EACH_DEFINED_FUNCTION (node)
+ {
+ struct cgraph_edge *e;
+ gcov_type call_count = 0;
+ struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
+
+ if (node->count)
+ continue;
+ for (e = node->callers; e; e = e->next_caller)
+ call_count += e->count;
+ if (call_count
+ && fn && fn->cfg
+ && (call_count * unlikely_count_fraction >= profile_info->runs))
+ {
+ drop_profile (node, call_count);
+ worklist.safe_push (node);
+ }
+ }
+
+ /* Propagate the profile dropping to other 0-count COMDATs that are
+ potentially called by COMDATs we already dropped the profile on. */
+ while (worklist.length () > 0)
+ {
+ struct cgraph_edge *e;
+
+ node = worklist.pop ();
+ for (e = node->callees; e; e = e->next_caller)
+ {
+ struct cgraph_node *callee = e->callee;
+ struct function *fn = DECL_STRUCT_FUNCTION (callee->decl);
+
+ if (callee->count > 0)
+ continue;
+ if (DECL_COMDAT (callee->decl) && fn && fn->cfg
+ && profile_status_for_function (fn) == PROFILE_READ)
+ {
+ drop_profile (node, 0);
+ worklist.safe_push (callee);
+ }
+ }
+ }
+ worklist.release ();
+}
+
/* Convert counts measured by profile driven feedback to frequencies.
Return nonzero iff there was any nonzero execution count. */
@@ -2756,6 +2871,12 @@ counts_to_freqs (void)
gcov_type count_max, true_count_max = 0;
basic_block bb;
+ /* Don't overwrite the estimated frequencies when the profile for
+ the function is missing. We may drop this function PROFILE_GUESSED
+ later in drop_profile (). */
+ if (!ENTRY_BLOCK_PTR->count)
+ return 0;
+
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
true_count_max = MAX (bb->count, true_count_max);
diff --git a/gcc/predict.h b/gcc/predict.h
index 02650e2d55c..83b1695c65e 100644
--- a/gcc/predict.h
+++ b/gcc/predict.h
@@ -37,6 +37,7 @@ enum prediction
extern void predict_insn_def (rtx, enum br_predictor, enum prediction);
extern int counts_to_freqs (void);
+extern void handle_missing_profiles (void);
extern void estimate_bb_frequencies (bool);
extern const char *predictor_name (enum br_predictor);
extern tree build_predict_expr (enum br_predictor, enum prediction);
diff --git a/gcc/profile.c b/gcc/profile.c
index 7118ac8ac29..5f73b2ca462 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -62,9 +62,11 @@ along with GCC; see the file COPYING3. If not see
#include "value-prof.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "cfgloop.h"
#include "dumpfile.h"
+#include "cgraph.h"
#include "profile.h"
@@ -188,6 +190,15 @@ instrument_values (histogram_values values)
gimple_gen_ior_profiler (hist, t, 0);
break;
+ case HIST_TYPE_TIME_PROFILE:
+ {
+ basic_block bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
+ gimple_stmt_iterator gsi = gsi_start_bb (bb);
+
+ gimple_gen_time_profiler (t, 0, gsi);
+ break;
+ }
+
default:
gcc_unreachable ();
}
@@ -850,6 +861,7 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
gcov_type *aact_count;
+ struct cgraph_node *node;
for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
n_histogram_counters[t] = 0;
@@ -888,6 +900,7 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
t = (int) hist->type;
aact_count = act_count[t];
+
if (act_count[t])
act_count[t] += hist->n_counters;
@@ -895,9 +908,22 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
for (j = 0; j < hist->n_counters; j++)
if (aact_count)
- hist->hvalue.counters[j] = aact_count[j];
- else
- hist->hvalue.counters[j] = 0;
+ hist->hvalue.counters[j] = aact_count[j];
+ else
+ hist->hvalue.counters[j] = 0;
+
+ /* Time profiler counter is not related to any statement,
+ so that we have to read the counter and set the value to
+ the corresponding call graph node. */
+ if (hist->type == HIST_TYPE_TIME_PROFILE)
+ {
+ node = cgraph_get_node (hist->fun->decl);
+
+ node->tp_first_run = hist->hvalue.counters[0];
+
+ if (dump_file)
+ fprintf (dump_file, "Read tp_first_run: %d\n", node->tp_first_run);
+ }
}
for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 204685da316..a40e16b12c3 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -2123,7 +2123,8 @@ delete_dead_insn (rtx insn)
block local equivalences. Instead of trying to figure out the exact
circumstances where we can delete the potentially dead insns, just
let DCE do the job. */
- if (prev && GET_CODE (PATTERN (prev)) == SET
+ if (prev && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn)
+ && GET_CODE (PATTERN (prev)) == SET
&& (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
&& reg_mentioned_p (prev_dest, PATTERN (insn))
&& find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
diff --git a/gcc/reorg.c b/gcc/reorg.c
index e9aa889b17d..a87979db293 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -2302,15 +2302,16 @@ follow_jumps (rtx label, rtx jump, bool *crossing)
depth++)
{
rtx this_label = JUMP_LABEL (insn);
- rtx tem;
/* If we have found a cycle, make the insn jump to itself. */
if (this_label == label)
return label;
+
+ /* Cannot follow returns and cannot look through tablejumps. */
if (ANY_RETURN_P (this_label))
return this_label;
- tem = next_active_insn (this_label);
- if (tem && JUMP_TABLE_DATA_P (tem))
+ if (NEXT_INSN (this_label)
+ && JUMP_TABLE_DATA_P (NEXT_INSN (this_label)))
break;
if (!targetm.can_follow_jump (jump, insn))
diff --git a/gcc/sese.c b/gcc/sese.c
index 1daf4576258..d05b14afbb8 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index ef5d74087cc..c171fee826a 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-dump.h"
#include "gimple.h"
+#include "gimplify.h"
/* Data type for the expressions representing sizes of data types.
It is the first integer type laid out. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 9bb925af854..677f25513ff 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "opts.h"
#include "gimple.h"
+#include "gimplify.h"
#include "tree-ssanames.h"
#include "tree-ssa-alias.h"
#include "insn-codes.h"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7ceba705781..2adcce4f13e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,297 @@
+2013-11-15 Mike Stump <mikestump@comcast.net>
+
+ * lib/gcc.exp (gcc_target_compile): Add support for random runtime
+ * lib/g++.exp (g++_target_compile): Likewise.
+ * gcc.dg/cilk-plus/cilk-plus.exp: Improve support for runtime
+ libraries. Remove debugging.
+ * g++.dg/cilk-plus/cilk-plus.exp: Add support to find runtime
+ libraries. Remove -O0, redundant with default.
+
+2013-11-15 Joseph Myers <joseph@codesourcery.com>
+
+ * c-c++-common/cpp/ucnid-2011-1.c: New test.
+
+2013-11-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58188
+ * g++.dg/cpp0x/nsdmi-template8.C: New.
+
+2013-11-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58725
+ * g++.dg/cpp0x/nsdmi-template7.C: New.
+
+2013-11-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58829
+ * g++.dg/cpp0x/nsdmi-template6.C: New.
+
+2013-11-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58599
+ * g++.dg/cpp0x/nsdmi-template5.C: New.
+
+2013-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-c++-common/cilk-plus/PS: New directory.
+ * g++.dg/cilk-plus/cilk-plus.exp: Run shared tests.
+ * g++.dg/dg.exp: Run Cilk Plus tests.
+ * gcc.dg/cilk-plus/cilk-plus.exp: Run shared tests.
+
+2013-11-15 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * gcc.dg/vmx/3b-15.c: Revise for little endian.
+
+2013-11-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/50262
+ * gcc.dg/tree-ssa/alias-28.c: New testcase.
+ * gcc.dg/strlenopt-1.c: Adjust.
+ * gcc.dg/strlenopt-1f.c: Likewise.
+
+2013-11-15 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/torture/20131115-1.c: New testcase.
+
+2013-11-15 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/cpp/ucnid-9.c: New test.
+
+2013-11-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/stack_usage1b.adb: New test.
+ * gnat.dg/stack_usage1c.adb: Likewise.
+
+2013-11-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gnat.dg/specs/addr1.ads: Revert the last change.
+ * gnat.dg/specs/atomic1.ads: Likewise.
+
+2013-11-14 Cong Hou <congh@google.com>
+
+ * gcc.dg/vect/vect-alias-check.c: Update.
+
+2013-11-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57887
+ * g++.dg/cpp0x/nsdmi-template3.C: New.
+ * g++.dg/cpp0x/nsdmi-template4.C: Likewise.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * gcc.target/powerpc/ppc64-abi-1.c (stack_frame_t): Remove
+ compiler and linker field if _CALL_ELF == 2.
+ * gcc.target/powerpc/ppc64-abi-2.c (stack_frame_t): Likewise.
+ * gcc.target/powerpc/ppc64-abi-dfp-1.c (stack_frame_t): Likewise.
+ * gcc.dg/stack-usage-1.c (SIZE): Update value for _CALL_ELF == 2.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * gcc.target/powerpc/ppc64-abi-dfp-1.c (FUNC_START): New macro.
+ (WRAPPER): Use it.
+ * gcc.target/powerpc/no-r11-1.c: Skip on powerpc_elfv2.
+ * gcc.target/powerpc/no-r11-2.c: Skip on powerpc_elfv2.
+ * gcc.target/powerpc/no-r11-3.c: Skip on powerpc_elfv2.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * lib/target-supports.exp (check_effective_target_powerpc_elfv2):
+ New function.
+ * gcc.target/powerpc/pr57949-1.c: Disable for powerpc_elfv2.
+ * gcc.target/powerpc/pr57949-2.c: Likewise.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * g++.dg/eh/ppc64-sighandle-cr.C: New test.
+
+2013-11-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/torture/float128-cmp-invalid.c: Require fenv_exceptions.
+ * gcc.dg/torture/float128-div-underflow.c: Likewise.
+ * gcc.dg/torture/float128-extend-nan.c: Likewise.
+
+2013-11-14 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-vrp-thread-1.c: Fix target selector.
+
+2013-11-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gnat.dg/specs/addr1.ads: XFAIL on x32.
+ * gnat.dg/specs/atomic1.ads: Likewise.
+
+2013-11-14 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * gcc.target/aarch64/cpu-diagnostics-2.c: Change "-mcpu="
+ to "cortex-a53".
+ * gcc.target/aarch64/cpu-diagnostics-3.c: Change "-mcpu="
+ to "cortex-a53".
+
+2013-11-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/atomic/c11-atomic-exec-4.c: Define _XOPEN_SOURCE=600 on
+ *-*-solaris2.1[0-9]*.
+ * gcc.dg/atomic/c11-atomic-exec-5.c: Likewise.
+
+2013-11-14 Joey Ye <joey.ye@arm.com>
+
+ * gcc.dg/tree-ssa/forwprop-28.c: Disable for cortex_m.
+ * gcc.dg/tree-ssa/vrp47.c: Likewise.
+ * gcc.dg/tree-ssa/vrp87.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-dom-thread-4.c: Ingore for cortex_m.
+ * gcc.dg/tree-ssa/ssa-vrp-thread-1.c: Likewise.
+
+2013-11-14 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/58533
+ * g++.dg/cpp1y/pr58533.C: New testcase (fixed by r204714).
+
+2013-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/59101
+ * gcc.c-torture/execute/pr59101.c: New test.
+
+2013-11-13 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/59102
+ * gcc.c-torture/compile/pr59102.c: New test.
+
+2013-11-13 Tom de Vries <tom@codesourcery.com>
+
+ * gcc.dg/tail-merge-store.c: New test.
+
+2013-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * testsuite/g++.dg/plugin/selfassign.c: Include gimple-iterator.h.
+ * testsuite/gcc.dg/plugin/selfassign.c: Likewise.
+
+2013-11-13 Jeff Law <law@redhat.com>
+
+ * PR middle-end/59119
+ * gcc.c-torture/compile/pr59119.c: New test.
+
+2013-11-13 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/ira-shrinkwrap-prep-1.c: Add lp64 to target requirements.
+ * gcc.dg/ira-shrinkwrap-prep-2.c: Likewise.
+ * gcc.dg/pr10474.c: Likewise.
+
+2013-11-13 Cesar Philippidis <cesar@codesourcery.com>
+
+ * lib/target-supports.exp
+ (check_effective_target_vect_cmdline_neeed): Add AArch64 to the list
+ of targets that do not need command line argument to enable SIMD.
+
+2013-11-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/guality/param-4.c: New test.
+
+2013-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c11-complex-1.c: New test.
+
+2013-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/atomic/stdatomic-vm.c, gcc.dg/auto-type-1.c,
+ gcc.dg/auto-type-2.c: New tests.
+
+2013-11-12 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * gcc.dg/cilk-plus/cilk-plus.exp: Added a check for LTO before running
+ LTO tests.
+
+2013-11-12 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/isolate-1.c: Update expected output.
+ * gcc.dg/tree-ssa/isolate-5.c: Verify the load survives through
+ the SSA optimizers.
+
+2013-11-12 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/59054
+ * gcc.target/powerpc/pr59054.c: New test.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ * g++.dg/cpp1y/lambda-generic.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-cfun.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-dep.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-udt.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-variadic.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-x.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-xcfun.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-xudt.C: New test case.
+ * g++.dg/cpp1y/lambda-generic-mixed.C: New test case.
+
+2013-11-12 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/58534
+ PR c++/58536
+ PR c++/58548
+ PR c++/58549
+ PR c++/58637
+ * g++.dg/cpp1y/pr58534.C: New testcase.
+ * g++.dg/cpp1y/pr58536.C: New testcase.
+ * g++.dg/cpp1y/pr58548.C: New testcase.
+ * g++.dg/cpp1y/pr58549.C: New testcase.
+ * g++.dg/cpp1y/pr58637.C: New testcase.
+
+2013-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c90-thread-local-1.c, gcc.dg/c99-thread-local-1.c,
+ gcc.dg/c11-thread-local-1.c, gcc.dg/c11-thread-local-2.c: New
+ tests.
+ * gcc.dg/tls/diag-2.c, objc.dg/tls/diag-2.m: Update expected
+ diagnostics.
+
+2013-11-12 Tristan Gingold <gingold@adacore.com>
+
+ * gnat.dg/aggr21.adb: New test.
+ * gnat.dg/aggr21_pkg.ad[sb]: New helper.
+
+2013-11-12 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/isolate-1.c: Update expected output.
+ * gcc.dg/tree-ssa/isolate-5.c: New test.
+
+2013-11-12 Martin Jambor <mjambor@suse.cz>
+
+ PR rtl-optimization/10474
+ * gcc.dg/pr10474.c: New testcase.
+ * gcc.dg/ira-shrinkwrap-prep-1.c: Likewise.
+ * gcc.dg/ira-shrinkwrap-prep-2.c: Likewise.
+
+2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57734
+ * g++.dg/cpp0x/alias-decl-enum-1.C: New.
+
+2013-11-11 Martin Liska <marxin.liska@gmail.com>
+
+ * gcc.dg/time-profiler-1.c: New test.
+ * gcc.dg/time-profiler-2.c: Ditto.
+
+2013-11-11 Marc Glisse <marc.glisse@inria.fr>
+ Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/alias-27.c: New testcase.
+
+2013-11-11 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/58853
+ * gcc.target/i386/pr58853.c: New test.
+
+2013-11-11 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * gcc.dg/tree-ssa/forwprop-28.c: Adjust for ARC
+ LOGICAL_OP_NON_SHORT_CIRCUIT definition.
+ * gcc.dg/tree-ssa/ssa-dom-thread-4.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c: Likewise.
+ * gcc.dg/tree-ssa/vrp47.c: Likewise.
+ * gcc.dg/tree-ssa/vrp87.c: Likewise.
+
2013-11-08 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/atomic/stdatomic-compare-exchange-1.c,
@@ -83,7 +377,6 @@
gcc.dg/c11-atomic-2.c, gcc.dg/c11-atomic-3.c,
gcc.dg/c90-atomic-1.c, gcc.dg/c99-atomic-1.c: New tests.
->>>>>>> .r204589
2013-11-07 Cong Hou <congh@google.com>
* gcc.dg/vect/vect-alias-check.c: New.
@@ -351,7 +644,7 @@
PR fortran/58989
* gfortran.dg/reshape_6.f90: New test.
-2013-10-05 Jeff Law <law@redhat.com>
+2013-11-05 Jeff Law <law@redhat.com>
* gcc.dg/pr38984.c: Add -fno-isolate-erroneous-paths.
* gcc.dg/tree-ssa/isolate-1.c: New test.
@@ -1059,7 +1352,7 @@
* gcc.dg/tree-ssa/gen-vect-2.c: Likewise.
* gcc.dg/tree-ssa/gen-vect-25.c: Likewise.
-2013-10-17 Charles Bayis <charles.baylis@linaro.org>
+2013-10-17 Charles Baylis <charles.baylis@linaro.org>
* gcc.dg/builtin-apply2.c: Skip test on arm hardfloat ABI targets.
* gcc.dg/tls/pr42894.c: Remove dg-options for arm*-*-* targets.
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
new file mode 100644
index 00000000000..9b10041d669
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -fopenmp" } */
+
+int *a, *b, c;
+void *jmpbuf[10];
+
+void foo()
+{
+ int j;
+
+#pragma simd
+ for (int i=0; i < 1000; ++i)
+ {
+ if (c == 6)
+ __builtin_setjmp (jmpbuf); /* { dg-error "setjmp" } */
+ a[i] = b[i];
+ }
+
+#pragma simd
+ for (int i=0; i < 1000; ++i)
+ {
+ if (c==5)
+ break; /* { dg-error "break statement " } */
+ }
+
+#pragma simd
+ for (int i=0; i < 1000; ++i)
+ {
+#pragma omp for /* { dg-error "OpenMP constructs may not" } */
+ for (j=0; j < 1000; ++j)
+ a[i] = b[i];
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses1.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses1.c
new file mode 100644
index 00000000000..27d117ec2f0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses1.c
@@ -0,0 +1,80 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -Werror -Wunknown-pragmas -fcilkplus" } */
+
+volatile int *a, *b;
+
+void foo()
+{
+ int i, j, k;
+
+#pragma simd assert /* { dg-error "expected '#pragma simd' clause" } */
+ for (i=0; i < 100; ++i)
+ a[i] = b[i];
+
+#pragma simd vectorlength /* { dg-error "expected '\\('" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength /* { dg-error "expected '\\('" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength(sizeof (a) == sizeof (float) ? 4 : 8)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength(4,8) /* { dg-error "expected '\\)'" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength(i) /* { dg-error "\(vectorlength must be an integer\|in a constant\)" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(35) /* { dg-error "expected identifier" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(blah) /* { dg-error "'blah' \(undeclared\|has not been\)" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(j, 36, k) /* { dg-error "expected" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i, j)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i : 4)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i : 2, j : 4, k)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(j : sizeof (a) == sizeof (float) ? 4 : 8)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+ // And now everyone in unison!
+#pragma simd linear(j : 4) vectorlength(4)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(blah2, 36)
+ /* { dg-error "'blah2' \(undeclared\|has not been\)" "undeclared" { target *-*-* } 71 } */
+ /* { dg-error "expected" "expected" { target *-*-* } 71 } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(j : k)
+ for (int i=0; i < 1234; ++i)
+ a[i] = b[j];
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses2.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses2.c
new file mode 100644
index 00000000000..71589c2b178
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-original -fcilkplus" } */
+
+volatile int *a, *b;
+
+void foo()
+{
+ int j, k;
+
+#pragma simd linear(j : 4, k) vectorlength(4)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+}
+
+/* { dg-final { scan-tree-dump-times "linear\\(j:4\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "linear\\(k:1\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "safelen\\(4\\)" 1 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c
new file mode 100644
index 00000000000..579b718a01c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/clauses3.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+#define N 1000
+
+int A[N], B[N], C[N];
+int main (void)
+{
+#pragma simd private (B) linear(B:1) /* { dg-error "more than one clause" } */
+ for (int ii = 0; ii < N; ii++)
+ {
+ A[ii] = B[ii] + C[ii];
+ }
+
+#pragma simd private (B, C) linear(B:1) /* { dg-error "more than one clause" } */
+ for (int ii = 0; ii < N; ii++)
+ {
+ A[ii] = B[ii] + C[ii];
+ }
+
+#pragma simd private (B) linear(C:2, B:1) /* { dg-error "more than one clause" } */
+ for (int ii = 0; ii < N; ii++)
+ {
+ A[ii] = B[ii] + C[ii];
+ }
+
+#pragma simd reduction (+:B) linear(B:1) /* { dg-error "more than one clause" } */
+ for (int ii = 0; ii < N; ii++)
+ {
+ A[ii] = B[ii] + C[ii];
+ }
+
+#pragma simd reduction (+:B) linear(B) /* { dg-error "more than one clause" } */
+ for (int ii = 0; ii < N; ii++)
+ {
+ A[ii] = B[ii] + C[ii];
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c
new file mode 100644
index 00000000000..3b678952c72
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c
@@ -0,0 +1,132 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+int *a, *b, *c;
+int something;
+
+void foo()
+{
+ int i, j;
+
+ // Declaration and initialization is allowed.
+#pragma simd
+ for (int i=0; i < 1000; i++)
+ a[i] = b[j];
+
+ // Empty initialization is not allowed.
+#pragma simd
+ for (; i < 5; ++i) // { dg-error "expected iteration" }
+ a[i] = i;
+
+ // Empty condition is not allowed.
+#pragma simd
+ for (int i=0; ; ++i) /* { dg-error "missing controlling" } */
+ a[i] = i;
+
+ // Empty increment is not allowed.
+#pragma simd
+ for (int i=0; i < 1234; ) /* { dg-error "missing increment" } */
+ a[i] = i*2;
+
+#pragma simd
+ i = 5; /* { dg-error "for statement expected" } */
+
+ // Initialization variables must be either integral or pointer types.
+ struct S {
+ int i;
+ };
+#pragma simd
+ for (struct S ss = { 0 }; ss.i <= 1000; ++ss.i) /* { dg-error "invalid controlling\|invalid type for iteration\|invalid increment" } */
+ a[ss.i] = b[ss.i];
+
+ #pragma simd
+ for (float f=0.0; f < 15.0; ++f) /* { dg-error "invalid type" } */
+ a[(int)f] = (int) f;
+
+ // Pointers are OK.
+ #pragma simd
+ for (int *i=c; i < &c[100]; ++i)
+ *a = '5';
+
+ // Condition of '==' is not allowed.
+#pragma simd
+ for (int i=j; i == 5; ++i) /* { dg-error "invalid controlling predicate" } */
+ a[i] = b[i];
+
+ // The LHS or RHS of the condition must be the initialization variable.
+#pragma simd
+ for (int i=0; i+j < 1234; ++i) /* { dg-error "invalid controlling predicate" } */
+ a[i] = b[i];
+
+ // Likewise.
+#pragma simd
+ for (int i=0; 1234 < i + j; ++i) /* { dg-error "invalid controlling predicate" } */
+ a[i] = b[i];
+
+ // Likewise, this is ok.
+#pragma simd
+ for (int i=0; 1234 + j < i; ++i)
+ a[i] = b[i];
+
+ // According to the CilkPlus forum, casts are not allowed, even if
+ // they are no-ops.
+#pragma simd
+ for (int i=0; (char)i < 1234; ++i) /* { dg-error "invalid controlling predicate" } */
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=255; i != something; --i)
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=100; i != 5; i += something)
+ a[i] = b[i];
+
+ // Increment must be on the induction variable.
+#pragma simd
+ for (int i=0; i < 100; j++) /* { dg-error "invalid increment expression" } */
+ a[i] = b[i];
+
+ // Likewise.
+#pragma simd
+ for (int i=0; i < 100; j = i + 1) /* { dg-error "invalid increment expression" } */
+ a[i] = b[i];
+
+ // Likewise.
+#pragma simd
+ for (int i=0; i < 100; i = j + 1) /* { dg-error "invalid increment expression" } */
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=0; i < 100; i = i + 5)
+ a[i] = b[i];
+
+ // Only PLUS and MINUS increments are allowed.
+#pragma simd
+ for (int i=0; i < 100; i *= 5) /* { dg-error "invalid increment expression" } */
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=0; i < 100; i -= j)
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=0; i < 100; i = i + j)
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=0; i < 100; i = j + i)
+ a[i] = b[i];
+
+#pragma simd
+ for (int i=0; i < 100; ++i, ++j) /* { dg-error "invalid increment expression" } */
+ a[i] = b[i];
+
+#pragma simd
+ for (int *point=0; point < b; ++point)
+ *point = 555;
+
+#pragma simd
+ for (int *point=0; point > b; --point)
+ *point = 555;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c
new file mode 100644
index 00000000000..86606275ac4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+#pragma simd /* { dg-error "must be inside a function" } */
+
+void foo()
+{
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/for3.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/for3.c
new file mode 100644
index 00000000000..2da8235f319
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/for3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+int *a, *c;
+
+void foo()
+{
+ int i, j;
+
+ // Pointers are OK.
+ #pragma simd
+ for (int *i=c; i < c; ++i)
+ *a = '5';
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-1.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-1.c
new file mode 100644
index 00000000000..d8cec84f149
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-1.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+/* FIXME: This test has been xfailed until reductions are fixed. */
+
+int argc = 1;
+
+/* This is a simple vectorization test. It tests if reduction works
+ and if it can vectorize the loop in func correctly. */
+#define N 1000
+
+int func (int *p, int *q) {
+ int x = 0;
+#pragma simd reduction (+:x)
+ for (int ii = 0; ii < N; ii++) {
+ x += (q[ii] + p[ii]);
+ }
+ return x;
+
+}
+
+int main ()
+{
+ int ii = 0, x;
+ int Array[N], Array2[N];
+
+ for (ii = 0; ii < N; ii++)
+ {
+ Array[ii] = 5 + argc;
+ Array2[ii] = argc;
+ }
+ x = func (Array, Array2);
+
+ if (x != N * 7)
+ return 1;
+ return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-2.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-2.c
new file mode 100644
index 00000000000..f5554f6b1ae
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+/* FIXME: This test has been xfailed until reductions are fixed. */
+
+#include <stdio.h>
+
+#define ARRAY_SIZE (256)
+int a[ARRAY_SIZE];
+
+__attribute__((noinline))
+int addit (int *arr, int N)
+{
+ int s=0;
+#pragma simd reduction (+:s)
+ for (int i = 0; i < N; i++)
+ s += arr[i];
+ return s;
+}
+
+int main () {
+ int i, s = 0, r = 0;
+ for (i = 0; i < ARRAY_SIZE; i++)
+ {
+ a[i] = i;
+ }
+
+ s = addit (a, ARRAY_SIZE);
+
+ for (i = 0; i < ARRAY_SIZE; i++)
+ r += i;
+
+ if (s == r)
+ return 0;
+ return 1;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c
new file mode 100644
index 00000000000..26822d633ff
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/reduction-3.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+/* FIXME: This test has been xfailed until reductions are fixed. */
+
+#define N 256
+#if HAVE_IO
+#include <stdio.h>
+#endif
+#include <malloc.h>
+
+int
+reduction_simd (int *a)
+{
+ int s = 0;
+
+#pragma simd reduction (+:s)
+ for (int i = 0; i < N; i++)
+ {
+ s += a[i];
+ }
+
+ return s;
+}
+
+int
+main ()
+{
+ int *a = (int *) malloc (N * sizeof (int));
+ int i, s = (N - 1) * N / 2;
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = i;
+ }
+#if HAVE_IO
+ printf ("%d, %d\n", s, reduction_simd (a));
+#endif
+ if (s == reduction_simd (a))
+ return 0;
+ else
+ return 1;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/run-1.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/run-1.c
new file mode 100644
index 00000000000..c8fe1c762bc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/run-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus -O3" } */
+
+#include <stdlib.h>
+
+#define N 4
+
+float f1[] = { 2.0, 3.0, 4.0, 5.0 };
+float f2[] = { 1.0, 6.0, -1.0, -2.0 };
+float res[] = { 3.0, 9.0, 3.0, 3.0 };
+
+__attribute__((noinline))
+void verify (float *sum)
+{
+ for (int i=0; i < N; ++i)
+ if (sum[i] != res[i])
+ abort ();
+}
+
+int main()
+{
+ float sum[N];
+#pragma simd
+ for (int i=0; i < N; ++i)
+ sum[i] = f1[i] + f2[i];
+ verify (sum);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/safelen.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/safelen.c
new file mode 100644
index 00000000000..2c59de9b02d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/safelen.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-gimple -fcilkplus" } */
+
+int *a, *b;
+
+void foo()
+{
+#pragma simd vectorlength(8)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "safelen\\(8\\)" 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/vectorlength.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/vectorlength.c
new file mode 100644
index 00000000000..9aa4a68290d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/vectorlength.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+volatile int *a, *b, N;
+typedef int tint;
+struct someclass {
+ int a;
+ char b;
+ int *p;
+};
+
+void foo()
+{
+#pragma simd vectorlength(4) vectorlength(8) /* { dg-error "too many 'vectorlength' clauses" } */
+ for (int i=0; i < N; ++i)
+ a[i] = b[i];
+
+#pragma simd vectorlength(3) /* { dg-error "must be a power of 2" } */
+ for (int i=0; i < N; ++i)
+ a[i] = b[i];
+}
diff --git a/gcc/testsuite/c-c++-common/cpp/ucnid-2011-1.c b/gcc/testsuite/c-c++-common/cpp/ucnid-2011-1.c
new file mode 100644
index 00000000000..e3c6d260855
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/ucnid-2011-1.c
@@ -0,0 +1,15 @@
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic -fextended-identifiers" { target c } } */
+/* { dg-options "-std=c++11 -pedantic -fextended-identifiers" { target c++ } } */
+
+\u00A8
+
+B\u0300
+
+\u0300 /* { dg-error "not valid at the start of an identifier" } */
+
+A\u0300 /* { dg-warning "not in NFC" } */
+
+\U00010000
+\U0001FFFD
+\U000E1234
diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
index 7e0fda57b27..a66ec44f297 100644
--- a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
+++ b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
@@ -16,7 +16,6 @@
# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-
load_lib g++-dg.exp
if { ![check_effective_target_cilkplus] } {
@@ -24,13 +23,25 @@ if { ![check_effective_target_cilkplus] } {
}
dg-init
+# Run the tests that are shared with C.
+g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/PS/*.c]] ""
+# Run the C++ only tests.
+g++-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] ""
+dg-finish
+
+set library_var [get_multilibs]
+# Pointing the ld_library_path to the Cilk Runtime library binaries.
+set ld_library_path "${library_var}/libcilkrts/.libs"
+
+global TEST_EXTRA_LIBS
+set TEST_EXTRA_LIBS "-L${library_var}/libcilkrts/.libs"
+
+dg-init
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O0 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O1 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O3 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -fcilkplus" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O0 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O1 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -g -O3 -fcilkplus" " "
@@ -50,3 +61,5 @@ dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O2
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O3 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -O3 -ftree-vectorize -fcilkplus -g" " "
dg-finish
+
+unset TEST_EXTRA_LIBS
diff --git a/gcc/testsuite/g++.dg/cilk-plus/for.C b/gcc/testsuite/g++.dg/cilk-plus/for.C
new file mode 100644
index 00000000000..6e16cfcd1d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/for.C
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+// Test storage classes in the initialization of a <#pragma simd> for
+// loop.
+
+int *a, *b;
+
+void foo()
+{
+#pragma simd
+ for (static int tt=5; tt < 10; ++tt) /* { dg-error "before 'static'\|not declared\|expected" } */
+ a[tt] = b[tt];
+
+#pragma simd
+ for (extern int var=0; var < 1000; ++var) /* { dg-error "before 'extern'\|not declared\|expected" } */
+ a[var] = var;
+
+#pragma simd
+ for (register int regj = 0; regj < 1000; ++regj) /* { dg-error "before 'register'\|not declared\|expected" } */
+ b[regj] = a[regj] * 2;
+
+#pragma simd
+ for (volatile int vj=0; vj<1000; ++vj) /* { dg-error "iteration variable cannot be volatile" } */
+ a[vj] = b[vj];
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/for2.C b/gcc/testsuite/g++.dg/cilk-plus/for2.C
new file mode 100644
index 00000000000..345e54236f8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/for2.C
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int *p;
+extern int stuff();
+
+template <int value>
+void foobar(int a)
+{
+#pragma simd
+ for (int i=0; i < a; ++i)
+ p[i] = value;
+}
+
+template <int value>
+void foobar2(int a)
+{
+ int j = 123;
+#pragma simd linear(j : value)
+ for (int i=0; i < a; ++i)
+ {
+ p[i] = value;
+ j += stuff();
+ }
+}
+
+void funky()
+{
+ foobar <69> (1000);
+ foobar2 <123> (2000);
+}
+
+void foobar3(int a)
+{
+ int j = 123;
+#pragma simd linear(j : a + a) /* { dg-error "step size must be an integer" } */
+ for (int i=0; i < a; ++i)
+ {
+ p[i] = 1234;
+ extern int bar();
+ j += bar();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/for3.C b/gcc/testsuite/g++.dg/cilk-plus/for3.C
new file mode 100644
index 00000000000..28dbdee4339
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/for3.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+// Test storage classes in the initialization of a <#pragma simd> for
+// loop.
+
+int *a, *b;
+
+void foo()
+{
+#pragma simd
+ for (int tt=5; tt < 10; ++tt)
+ {
+ a[tt] = b[tt];
+ if (tt == 8)
+ throw 1; /* { dg-error "throw expressions are not allowed" } */
+ }
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/for4.C b/gcc/testsuite/g++.dg/cilk-plus/for4.C
new file mode 100644
index 00000000000..5b86b9f7db5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/for4.C
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int *p;
+extern int stuff();
+
+template <int value>
+void foobar(int a)
+{
+ int j = 123;
+#pragma simd linear(j : value + 1)
+ for (int i=0; i < a; ++i)
+ {
+ p[i] = value;
+ j += stuff();
+ }
+}
+
+void funky()
+{
+ foobar <69> (1000);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C
new file mode 100644
index 00000000000..260a193a083
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-enum-1.C
@@ -0,0 +1,47 @@
+// PR c++/57734
+// { dg-do compile { target c++11 } }
+
+template<typename T, typename U>
+struct same_type { static const bool value = false; };
+
+template<typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+enum e { zero };
+enum class eclass { one };
+
+template<typename T>
+using enum_alias = e;
+
+template<typename T>
+using eclass_alias = eclass;
+
+typedef enum_alias<void> etest0;
+typedef enum_alias<void> etest0;
+typedef enum_alias<int> etest0;
+typedef enum_alias<int> etest1;
+
+static_assert (same_type<etest0, etest1>::value, "");
+
+typedef eclass_alias<void> ectest0;
+typedef eclass_alias<void> ectest0;
+typedef eclass_alias<int> ectest0;
+typedef eclass_alias<int> ectest1;
+
+static_assert (same_type<ectest0, ectest1>::value, "");
+
+template<typename T>
+enum_alias<T> efoo(T f) { return enum_alias<T>::zero; }
+
+template<typename T>
+constexpr enum_alias<T> cefoo(T f) { return enum_alias<T>::zero; }
+
+static_assert ( cefoo(1) == e::zero, "");
+
+template<typename T>
+eclass_alias<T> ecfoo(T f) { return eclass_alias<T>::one; }
+
+template<typename T>
+constexpr eclass_alias<T> cecfoo(T f) { return eclass_alias<T>::one; }
+
+static_assert ( cecfoo(1) == eclass::one, "");
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template3.C
new file mode 100644
index 00000000000..8a6f913d215
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template3.C
@@ -0,0 +1,16 @@
+// PR c++/58760
+// { dg-do compile { target c++11 } }
+
+enum en
+{
+ a,b,c
+};
+
+struct B
+{
+ template<en N>
+ struct A
+ {
+ const int X = N;
+ };
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template4.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template4.C
new file mode 100644
index 00000000000..ff8dc7e932b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template4.C
@@ -0,0 +1,24 @@
+// PR c++/57887
+// { dg-do compile { target c++11 } }
+
+struct B
+{
+ template<int N>
+ struct A
+ {
+ int X = N;
+ };
+};
+
+template<int M>
+struct C
+{
+ int Y = M;
+
+ template<int N>
+ struct A
+ {
+ int X = N;
+ int Y = M;
+ };
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template5.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template5.C
new file mode 100644
index 00000000000..fdaf4611ee2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template5.C
@@ -0,0 +1,38 @@
+// PR c++/58599
+// { dg-do compile { target c++11 } }
+
+template<int> struct A1;
+
+template<> struct A1<0>
+{
+ template<typename, typename...> struct B1
+ {
+ template<typename> int foo1() {}
+
+ int i1 = foo1<int>();
+ };
+};
+
+template<int> struct A2;
+
+template<> struct A2<0>
+{
+ template<typename, typename> struct B2
+ {
+ template<typename> int foo2() {}
+
+ int i2 = foo2<int>();
+ };
+};
+
+template<int> struct A3;
+
+template<> struct A3<0>
+{
+ template<typename> struct B3
+ {
+ template<typename> int foo3() {}
+
+ int i3 = foo3<int>();
+ };
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template6.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template6.C
new file mode 100644
index 00000000000..33ed82d0813
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template6.C
@@ -0,0 +1,13 @@
+// PR c++/58829
+// { dg-do compile { target c++11 } }
+
+struct A {
+ int f() {return 0;}
+} a;
+
+struct B {
+ template<int=0> struct C {
+ int i = a.f();
+ };
+};
+B::C<> c;
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template7.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template7.C
new file mode 100644
index 00000000000..cec7b7bea2b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template7.C
@@ -0,0 +1,15 @@
+// PR c++/58725
+// { dg-do compile { target c++11 } }
+
+struct A {
+ template<int=0>
+ struct B {
+ struct C {
+ int x = 0;
+ double y = x;
+ } c;
+ };
+};
+int main() {
+ A::B<>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template8.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template8.C
new file mode 100644
index 00000000000..ef0dddd7310
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template8.C
@@ -0,0 +1,27 @@
+// PR c++/58188
+// { dg-do compile { target c++11 } }
+
+struct B {};
+struct A
+{
+ A( B );
+};
+
+struct Bar
+{
+ template< unsigned v >
+ struct Foo
+ {
+ A z = B();
+ unsigned value;
+ Foo(): value( v ) {}
+ };
+
+ struct Baz
+ {
+ Foo< 8 > foo1;
+ Foo< 1 > foo3;
+ };
+};
+
+Bar::Baz baz;
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C
new file mode 100644
index 00000000000..5e515268f24
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C
@@ -0,0 +1,25 @@
+// Generic lambda conversion to function ptr test from N3690 5.1.2.6
+// { dg-options "-std=c++1y" }
+
+void f1(int (*)(int)) { }
+void f2(char (*)(int)) { }
+void g(int (*)(int)) { } // #1
+void g(char (*)(char)) { } // #2
+void h(int (*)(int)) { } // #3
+void h(char (*)(int)) { } // #4
+
+int main()
+{
+ auto glambda = [](auto a) { return a; };
+ int (*fp)(int) = glambda;
+ f1(glambda); // OK
+ f2(glambda); // { dg-error "invalid user-defined conversion" }
+ g(glambda); // { dg-error "ambiguous" }
+ h(glambda); // OK: calls #3 since it is convertible from ID
+ int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
+
+ auto GL = [](auto a) { return a; };
+ int (*GL_int)(int) = GL; // OK: through conversion function template
+ GL_int(3);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C
new file mode 100644
index 00000000000..bb687381978
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C
@@ -0,0 +1,42 @@
+// Generic lambda type dependence test part from N3690 5.1.2.12
+// { dg-options "-std=c++1y" }
+
+void f(int, const int (&)[2] = {}) { } // #1
+void f(const int&, const int (&)[1]) { } // #2
+
+void test()
+{
+ const int x = 17;
+ auto g = [](auto a) {
+ f(x); // OK: calls #1, does not capture x
+ };
+ auto g2 = [=](auto a) {
+ int selector[sizeof(a) == 1 ? 1 : 2]{};
+ f(x, selector); // OK: is a dependent expression, so captures x
+ };
+}
+
+struct S {
+ struct N {
+ auto test () { return 7.f; }
+ };
+};
+
+#include <utility>
+
+int main()
+{
+ auto f = [] <typename T> (T const& s) mutable {
+ typename T::N x;
+ return x.test ();
+ };
+ auto g = [] (auto const& s) {
+ typename std::decay<decltype (s)>::type::N x;
+ return x.test ();
+ };
+
+ S i;
+ f(i);
+ g(i);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C
new file mode 100644
index 00000000000..4e26fc500b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C
@@ -0,0 +1,10 @@
+// Mixed explicit and implicit generic lambda test.
+// { dg-options "-std=c++1y" }
+
+int main()
+{
+ auto f = [] <typename T> (T a, auto b) { return a + b; };
+ auto g = [] <typename T> (auto a, T b) { return a + b; };
+
+ return f (1.0, 3) + g (1.0, 3);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C
new file mode 100644
index 00000000000..9f6d45aa8f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C
@@ -0,0 +1,51 @@
+// Ensure that generic lambdas properly construct and destroy user types.
+// { dg-options "-std=c++1y -DUSE_AUTO_SYNTAX" }
+// { dg-do run }
+
+int i = 3;
+
+struct S
+{
+ S () { ++i; }
+ S (S const&) { ++i; }
+ S (S&& old) { old.shadow = true; i += 2; }
+ ~S () { if (shadow) i -= 2; else --i; }
+
+ bool shadow = false;
+};
+
+extern "C" void printf(...);
+#define assert(e) if (e); else \
+ printf ("%s:%d: !(%s)\n", __FILE__, __LINE__, #e), __builtin_abort ();
+
+int main ()
+{
+ assert (i == 3);
+ {
+ S s; assert (i == 4);
+
+ #if USE_AUTO_SYNTAX
+ auto byref = [] (auto& r) { (void) r; };
+ auto bycref = [] (auto const& r) { (void) r; };
+ auto byval = [] (auto v, auto const x) { assert (i == x); (void) v; };
+ auto byrval = [] (auto&& r, auto const x) { S steal (static_cast<S&&>(r));
+ assert (i == x); };
+
+ #elif USE_EXPLICIT_TEMPLATE_SYNTAX
+ auto byref = [] <typename T> (T& r) { (void) r; };
+ auto bycref = [] <typename T> (T const& r) { (void) r; };
+ auto byval = [] <typename T, typename I>
+ (T v, I const x) { assert (i == x); (void) v; };
+ auto byrval = [] <typename T, typename I>
+ (T&& r, I const x) { S steal (static_cast<S&&>(r));
+ assert (i == x); };
+ #endif
+
+ byref (s); assert (i == 4);
+ bycref (s); assert (i == 4);
+ byval (s, 5); assert (i == 4);
+ byrval (static_cast<S&&>(s), 6); assert (i == 5);
+ }
+ assert (i == 3);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
new file mode 100644
index 00000000000..bd41b35bbcb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
@@ -0,0 +1,15 @@
+// Basic generic lambda test
+// { dg-options "-std=c++1y" }
+// { dg-do run }
+
+template <typename T, typename U> struct pair {};
+template <typename... T> struct tuple {};
+
+int main()
+{
+ auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
+ auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); };
+
+ a(1, pair<int, float>());
+ b(2, pair<pair<short,char>, double>(), pair<pair<float,long>, int>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C
new file mode 100644
index 00000000000..48a62686316
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C
@@ -0,0 +1,25 @@
+// Explicit generic lambda test from N3690 5.1.2.5
+// { dg-options "-std=gnu++1y" }
+
+#include <iostream>
+
+int main()
+{
+ auto glambda = [] <typename A, typename B> (A a, B&& b) { return a < b; };
+ bool b = glambda(3, 3.14); // OK
+ auto vglambda = [] <typename P> (P printer) {
+ return [=] <typename... T> (T&& ... ts) { // OK: ts is a function parameter pack
+ printer(std::forward<decltype(ts)>(ts)...);
+ return [=]() {
+ printer(ts ...);
+ };
+ };
+ };
+ auto p = vglambda( [] <typename A,
+ typename B,
+ typename C> (A v1, B v2, C v3)
+ { std::cout << v1 << v2 << v3; } );
+ auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
+ q(); // OK: outputs 1a3.14
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C
new file mode 100644
index 00000000000..d44b7963843
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C
@@ -0,0 +1,25 @@
+// Explicit generic lambda conversion to function ptr test from N3690 5.1.2.6
+// { dg-options "-std=gnu++1y" }
+
+void f1(int (*)(int)) { }
+void f2(char (*)(int)) { }
+void g(int (*)(int)) { } // #1
+void g(char (*)(char)) { } // #2
+void h(int (*)(int)) { } // #3
+void h(char (*)(int)) { } // #4
+
+int main()
+{
+ auto glambda = [] <typename T> (T a) { return a; };
+ int (*fp)(int) = glambda;
+ f1(glambda); // OK
+ f2(glambda); // { dg-error "invalid user-defined conversion" }
+ g(glambda); // { dg-error "ambiguous" }
+ h(glambda); // OK: calls #3 since it is convertible from ID
+ int& (*fpi)(int*) = [] <typename T> (T* a) -> auto& { return *a; }; // OK
+
+ auto GL = [] <typename T> (T a) { return a; };
+ int (*GL_int)(int) = GL; // OK: through conversion function template
+ GL_int(3);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C
new file mode 100644
index 00000000000..fba864bbbe9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C
@@ -0,0 +1,4 @@
+// Ensure that generic lambdas properly construct and destroy user types.
+// { dg-options "-std=gnu++1y -DUSE_EXPLICIT_TEMPLATE_SYNTAX" }
+
+#include "lambda-generic-udt.C"
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic.C
new file mode 100644
index 00000000000..1f66475a07b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic.C
@@ -0,0 +1,23 @@
+// Generic lambda test from N3690 5.1.2.5
+// { dg-options "-std=c++1y" }
+
+#include <iostream>
+
+int main()
+{
+ auto glambda = [](auto a, auto&& b) { return a < b; };
+ bool b = glambda(3, 3.14); // OK
+ auto vglambda = [](auto printer) {
+ return [=](auto&& ... ts) { // OK: ts is a function parameter pack
+ printer(std::forward<decltype(ts)>(ts)...);
+ return [=]() {
+ printer(ts ...);
+ };
+ };
+ };
+ auto p = vglambda( [](auto v1, auto v2, auto v3)
+ { std::cout << v1 << v2 << v3; } );
+ auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
+ q(); // OK: outputs 1a3.14
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58533.C b/gcc/testsuite/g++.dg/cpp1y/pr58533.C
new file mode 100644
index 00000000000..e1855d78e08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58533.C
@@ -0,0 +1,7 @@
+// PR c++/58533
+// { dg-options "-std=gnu++1y" }
+
+void foo()
+{
+ void (*fp)(auto); // { dg-error "template" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58534.C b/gcc/testsuite/g++.dg/cpp1y/pr58534.C
new file mode 100644
index 00000000000..4aa4f430189
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58534.C
@@ -0,0 +1,9 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/58534
+
+template<typename> void foo(const auto&) {}
+
+template<typename, typename...T> void foo(const auto&, T...) {}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58536.C b/gcc/testsuite/g++.dg/cpp1y/pr58536.C
new file mode 100644
index 00000000000..8050c1957c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58536.C
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/58536
+
+struct A
+{
+ A(auto);
+};
+
+A::A(auto) {}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58548.C b/gcc/testsuite/g++.dg/cpp1y/pr58548.C
new file mode 100644
index 00000000000..0ac2e1c341d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58548.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/58548
+
+void foo(auto)
+{
+ struct A { int i; };
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58549.C b/gcc/testsuite/g++.dg/cpp1y/pr58549.C
new file mode 100644
index 00000000000..b71bac9975a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58549.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/58549
+
+void foo(auto)
+{
+ void bar();
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58637.C b/gcc/testsuite/g++.dg/cpp1y/pr58637.C
new file mode 100644
index 00000000000..46200ff1c5d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr58637.C
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/58637
+
+template<> void foo(auto); // { dg-error "auto|not a template" }
+
diff --git a/gcc/testsuite/g++.dg/dg.exp b/gcc/testsuite/g++.dg/dg.exp
index 0528538cee7..d107dfe7894 100644
--- a/gcc/testsuite/g++.dg/dg.exp
+++ b/gcc/testsuite/g++.dg/dg.exp
@@ -49,6 +49,7 @@ set tests [prune $tests $srcdir/$subdir/tree-prof/*]
set tests [prune $tests $srcdir/$subdir/torture/*]
set tests [prune $tests $srcdir/$subdir/graphite/*]
set tests [prune $tests $srcdir/$subdir/tm/*]
+set tests [prune $tests $srcdir/$subdir/cilk-plus/*]
set tests [prune $tests $srcdir/$subdir/guality/*]
set tests [prune $tests $srcdir/$subdir/simulate-thread/*]
set tests [prune $tests $srcdir/$subdir/asan/*]
diff --git a/gcc/testsuite/g++.dg/eh/ppc64-sighandle-cr.C b/gcc/testsuite/g++.dg/eh/ppc64-sighandle-cr.C
new file mode 100644
index 00000000000..32561736077
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/ppc64-sighandle-cr.C
@@ -0,0 +1,54 @@
+// { dg-do run { target { powerpc64*-*-linux* } } }
+// { dg-options "-fexceptions -fnon-call-exceptions" }
+
+#include <signal.h>
+#include <stdlib.h>
+#include <fenv.h>
+
+#define SET_CR(R,V) __asm__ __volatile__ ("mtcrf %0,%1" : : "n" (1<<(7-R)), "r" (V<<(4*(7-R))) : "cr" #R)
+#define GET_CR(R) ({ int tmp; __asm__ __volatile__ ("mfcr %0" : "=r" (tmp)); (tmp >> 4*(7-R)) & 15; })
+
+void sighandler (int signo, siginfo_t * si, void * uc)
+{
+ SET_CR(2, 3);
+ SET_CR(3, 2);
+ SET_CR(4, 1);
+
+ throw 0;
+}
+
+float test (float a, float b) __attribute__ ((__noinline__));
+float test (float a, float b)
+{
+ float x;
+ asm ("mtcrf %1,%2" : "=f" (x) : "n" (1 << (7-3)), "r" (0), "0" (b) : "cr3");
+ return a / x;
+}
+
+int main ()
+{
+ struct sigaction sa;
+ int status;
+
+ sa.sa_sigaction = sighandler;
+ sa.sa_flags = SA_SIGINFO;
+
+ status = sigaction (SIGFPE, & sa, NULL);
+
+ feenableexcept (FE_DIVBYZERO);
+
+ SET_CR(2, 6);
+ SET_CR(3, 9);
+ SET_CR(4, 12);
+
+ try {
+ test (1, 0);
+ }
+ catch (...) {
+ return GET_CR(2) != 6 || GET_CR(3) != 9 || GET_CR(4) != 12;
+ }
+
+ return 1;
+}
+
+
diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c
index 5331f792cb2..2498153a273 100644
--- a/gcc/testsuite/g++.dg/plugin/selfassign.c
+++ b/gcc/testsuite/g++.dg/plugin/selfassign.c
@@ -11,6 +11,7 @@
#include "toplev.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59102.c b/gcc/testsuite/gcc.c-torture/compile/pr59102.c
new file mode 100644
index 00000000000..495473322a5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr59102.c
@@ -0,0 +1,28 @@
+
+int a, b, c, f;
+
+struct S
+{
+ int f0;
+} d, *e;
+
+struct S
+foo ()
+{
+ b = c = b || a == 0 || f % 11;
+ return d;
+}
+
+int
+main ()
+{
+ foo ();
+ if (b);
+ else
+ {
+ struct S **g = &e;
+ *g = 0;
+ *e = foo ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr59119.c b/gcc/testsuite/gcc.c-torture/compile/pr59119.c
new file mode 100644
index 00000000000..b026ba5d4ac
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr59119.c
@@ -0,0 +1,23 @@
+extern void *memmove (void *, const void *, __SIZE_TYPE__);
+extern void *memset (void *, int, __SIZE_TYPE__);
+
+typedef struct {
+ long n_prefix;
+ long n_spadding;
+} NumberFieldWidths;
+
+void
+fill_number(char *buf, const NumberFieldWidths *spec)
+{
+ if (spec->n_prefix) {
+ memmove(buf,
+ (char *) 0,
+ spec->n_prefix * sizeof(char));
+ buf += spec->n_prefix;
+ }
+ if (spec->n_spadding) {
+ memset(buf, 0, spec->n_spadding);
+ buf += spec->n_spadding;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59101.c b/gcc/testsuite/gcc.c-torture/execute/pr59101.c
new file mode 100644
index 00000000000..ed6a7e8fa31
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr59101.c
@@ -0,0 +1,15 @@
+/* PR target/59101 */
+
+__attribute__((noinline, noclone)) int
+foo (int a)
+{
+ return (~a & 4102790424LL) > 0 | 6;
+}
+
+int
+main ()
+{
+ if (foo (0) != 7)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c
index 02bb3cb7960..1558200dbfe 100644
--- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c
+++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c
@@ -3,6 +3,7 @@
out in two threads. */
/* { dg-do run } */
/* { dg-options "-std=c11 -pedantic-errors -pthread -D_POSIX_C_SOURCE=200809L" } */
+/* { dg-additional-options "-D_XOPEN_SOURCE=600" { target *-*-solaris2.1[0-9]* } }
/* { dg-require-effective-target pthread } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
index 9e6977b4286..bc87de4cc89 100644
--- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
+++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
@@ -4,6 +4,7 @@
get properly cleared). */
/* { dg-do run } */
/* { dg-options "-std=c11 -pedantic-errors -pthread -D_POSIX_C_SOURCE=200809L" } */
+/* { dg-additional-options "-D_XOPEN_SOURCE=600" { target *-*-solaris2.1[0-9]* } }
/* { dg-require-effective-target fenv_exceptions } */
/* { dg-require-effective-target pthread } */
diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c
new file mode 100644
index 00000000000..f43fa49ef12
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c
@@ -0,0 +1,68 @@
+/* Test atomic operations on expressions of variably modified type
+ with side effects. */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+int s = 5;
+
+int count = 0;
+
+int
+func (void)
+{
+ count++;
+ return 0;
+}
+
+int
+main (void)
+{
+ int vla[s][s];
+ int (*_Atomic p)[s] = &vla[0];
+ int (*b)[s] = kill_dependency (++p);
+ if (b != &vla[1] || p != &vla[1])
+ abort ();
+ int (*_Atomic *q)[s] = &p;
+ atomic_store_explicit (q + func (), &vla[0], memory_order_seq_cst);
+ if (count != 1)
+ abort ();
+ atomic_store (q + func (), &vla[0]);
+ if (count != 2)
+ abort ();
+ (void) atomic_load_explicit (q + func (), memory_order_seq_cst);
+ if (count != 3)
+ abort ();
+ (void) atomic_load (q + func ());
+ if (count != 4)
+ abort ();
+ (void) atomic_exchange_explicit (q + func (), &vla[0], memory_order_seq_cst);
+ if (count != 5)
+ abort ();
+ (void) atomic_exchange (q + func (), &vla[0]);
+ if (count != 6)
+ abort ();
+ int vla2[s][s];
+ int (*p2)[s] = &vla2[0];
+ int (**qna)[s] = &p2;
+ (void) atomic_compare_exchange_strong_explicit (q + func (), qna, &vla[0],
+ memory_order_seq_cst,
+ memory_order_seq_cst);
+ if (count != 7)
+ abort ();
+ (void) atomic_compare_exchange_strong (q + func (), qna, &vla[0]);
+ if (count != 8)
+ abort ();
+ (void) atomic_compare_exchange_weak_explicit (q + func (), qna, &vla[0],
+ memory_order_seq_cst,
+ memory_order_seq_cst);
+ if (count != 9)
+ abort ();
+ (void) atomic_compare_exchange_weak (q + func (), qna, &vla[0]);
+ if (count != 10)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/auto-type-1.c b/gcc/testsuite/gcc.dg/auto-type-1.c
new file mode 100644
index 00000000000..f47693abbf3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-type-1.c
@@ -0,0 +1,37 @@
+/* Test __auto_type. Test correct uses. */
+/* { dg-do run } */
+/* { dg-options "" } */
+
+extern void abort (void);
+extern void exit (int);
+
+__auto_type i = 1;
+extern int i;
+__auto_type c = (char) 1;
+extern char c;
+static __auto_type u = 10U;
+extern unsigned int u;
+const __auto_type ll = 1LL;
+extern const long long ll;
+
+int
+main (void)
+{
+ if (i != 1 || c != 1 || u != 10U)
+ abort ();
+ __auto_type ai = i;
+ int *aip = &ai;
+ if (ai != 1)
+ abort ();
+ __auto_type p = (int (*) [++i]) 0;
+ if (i != 2)
+ abort ();
+ if (sizeof (*p) != 2 * sizeof (int))
+ abort ();
+ int vla[u][u];
+ int (*vp)[u] = &vla[0];
+ __auto_type vpp = ++vp;
+ if (vp != &vla[1])
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/auto-type-2.c b/gcc/testsuite/gcc.dg/auto-type-2.c
new file mode 100644
index 00000000000..761671b3c5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-type-2.c
@@ -0,0 +1,23 @@
+/* Test __auto_type. Test invalid uses. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+__auto_type; /* { dg-error "empty declaration" } */
+__auto_type *p = (int *) 0; /* { dg-error "plain identifier" } */
+struct s0 { int i : 1; } x;
+void f (void) { __auto_type v = x.i; } /* { dg-error "bit-field initializer" } */
+__auto_type i; /* { dg-error "initialized data declaration" } */
+__auto_type g { } /* { dg-error "initialized data declaration" } */
+__auto_type a = 1, b = 2; /* { dg-error "single declarator" } */
+__auto_type long e0 = 0; /* { dg-error "__auto_type" } */
+__auto_type short e1 = 0; /* { dg-error "__auto_type" } */
+__auto_type signed e2 = 0; /* { dg-error "__auto_type" } */
+__auto_type unsigned e3 = 0; /* { dg-error "__auto_type" } */
+__auto_type _Complex e4 = 0; /* { dg-error "__auto_type" } */
+long __auto_type e5 = 0; /* { dg-error "__auto_type" } */
+short __auto_type e6 = 0; /* { dg-error "__auto_type" } */
+signed __auto_type e7 = 0; /* { dg-error "__auto_type" } */
+unsigned __auto_type e8 = 0; /* { dg-error "__auto_type" } */
+_Complex __auto_type e9 = 0; /* { dg-error "__auto_type" } */
+int __auto_type e10 = 0; /* { dg-error "two or more data types" } */
+__auto_type _Bool e11 = 0; /* { dg-error "two or more data types" } */
diff --git a/gcc/testsuite/gcc.dg/c11-complex-1.c b/gcc/testsuite/gcc.dg/c11-complex-1.c
new file mode 100644
index 00000000000..e2d3c460f40
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-complex-1.c
@@ -0,0 +1,42 @@
+/* Test complex divide does not have the bug identified in N1496. */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+extern void abort (void);
+extern void exit (int);
+
+#define CMPLX(x, y) __builtin_complex ((double) (x), (double) (y))
+#define CMPLXF(x, y) __builtin_complex ((float) (x), (float) (y))
+#define CMPLXL(x, y) __builtin_complex ((long double) (x), (long double) (y))
+#define NAN __builtin_nanf ("")
+#define isnan(x) __builtin_isnan (x)
+
+volatile _Complex float num_f = CMPLXF (1, 1);
+volatile _Complex float den_f = CMPLXF (0, NAN);
+volatile _Complex float res_f, cres_f = CMPLXF (1, 1) / CMPLXF (0, NAN);
+
+volatile _Complex double num_d = CMPLX (1, 1);
+volatile _Complex double den_d = CMPLX (0, NAN);
+volatile _Complex double res_d, cres_d = CMPLX (1, 1) / CMPLX (0, NAN);
+
+volatile _Complex long double num_ld = CMPLXL (1, 1);
+volatile _Complex long double den_ld = CMPLXL (0, NAN);
+volatile _Complex long double res_ld, cres_ld = CMPLXL (1, 1) / CMPLXL (0, NAN);
+
+int
+main (void)
+{
+ res_f = num_f / den_f;
+ if (!isnan (__real__ res_f) || !isnan (__imag__ res_f)
+ || !isnan (__real__ cres_f) || !isnan (__imag__ cres_f))
+ abort ();
+ res_d = num_d / den_d;
+ if (!isnan (__real__ res_d) || !isnan (__imag__ res_d)
+ || !isnan (__real__ cres_d) || !isnan (__imag__ cres_d))
+ abort ();
+ res_ld = num_ld / den_ld;
+ if (!isnan (__real__ res_ld) || !isnan (__imag__ res_ld)
+ || !isnan (__real__ cres_ld) || !isnan (__imag__ cres_ld))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c11-thread-local-1.c b/gcc/testsuite/gcc.dg/c11-thread-local-1.c
new file mode 100644
index 00000000000..b21209aecd1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-thread-local-1.c
@@ -0,0 +1,28 @@
+/* Test for _Thread_local in C11. Test of valid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+_Thread_local int a;
+static _Thread_local long b;
+extern _Thread_local int c, a;
+_Thread_local static int d;
+long _Thread_local extern b;
+_Thread_local int extern a;
+_Thread_local struct s; /* { dg-warning "useless" } */
+_Thread_local int a = 1;
+extern _Thread_local int c = 2; /* { dg-warning "initialized and" } */
+void
+f (void)
+{
+ static _Thread_local int x;
+ extern _Thread_local long b;
+ _Thread_local extern int a;
+}
+
+inline void
+fi (void)
+{
+ static _Thread_local const int v;
+ (void) a;
+ static _Thread_local int (*const p)[a];
+}
diff --git a/gcc/testsuite/gcc.dg/c11-thread-local-2.c b/gcc/testsuite/gcc.dg/c11-thread-local-2.c
new file mode 100644
index 00000000000..33872261689
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-thread-local-2.c
@@ -0,0 +1,46 @@
+/* Test for _Thread_local in C11. Test of invalid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+_Thread_local void f (void); /* { dg-error "storage class" } */
+_Thread_local void g (void) {} /* { dg-error "_Thread_local" } */
+typedef _Thread_local int t1; /* { dg-error "_Thread_local" } */
+_Thread_local typedef int t2; /* { dg-error "_Thread_local" } */
+
+void
+h (void)
+{
+ _Thread_local auto int a; /* { dg-error "_Thread_local" } */
+ _Thread_local register int b; /* { dg-error "_Thread_local" } */
+ auto _Thread_local int c; /* { dg-error "_Thread_local" } */
+ register _Thread_local int d; /* { dg-error "_Thread_local" } */
+ _Thread_local int e; /* { dg-error "_Thread_local" } */
+}
+
+_Thread_local int v; /* { dg-message "previous" } */
+extern int v; /* { dg-error "thread" } */
+int w; /* { dg-message "previous" } */
+extern _Thread_local int w; /* { dg-error "thread" } */
+
+_Thread_local int x; /* { dg-message "previous" } */
+int y; /* { dg-message "previous" } */
+
+int vv;
+
+void
+i (void)
+{
+ extern int x; /* { dg-error "thread" } */
+ extern _Thread_local int y; /* { dg-error "thread" } */
+ static _Thread_local int a[vv]; /* { dg-error "storage size" } */
+ static _Thread_local int vi = vv; /* { dg-error "not constant" } */
+}
+
+static _Thread_local int sv;
+
+inline void
+j (void)
+{
+ static _Thread_local int vj; /* { dg-error "static but declared" } */
+ (void) sv; /* { dg-error "static but used in inline" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c90-thread-local-1.c b/gcc/testsuite/gcc.dg/c90-thread-local-1.c
new file mode 100644
index 00000000000..92bf57a90bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c90-thread-local-1.c
@@ -0,0 +1,5 @@
+/* Test for _Thread_local: not in C90. */
+/* { dg-do compile } */
+/* { dg-options "-std=c90 -pedantic-errors" } */
+
+static _Thread_local int x; /* { dg-error "_Thread_local" } */
diff --git a/gcc/testsuite/gcc.dg/c99-thread-local-1.c b/gcc/testsuite/gcc.dg/c99-thread-local-1.c
new file mode 100644
index 00000000000..ff531252c86
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-thread-local-1.c
@@ -0,0 +1,5 @@
+/* Test for _Thread_local: not in C99. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+static _Thread_local int x; /* { dg-error "_Thread_local" } */
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp b/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
index 3a3cba80a70..dc66fcb4c0c 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
+++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp
@@ -18,20 +18,27 @@
load_lib gcc-dg.exp
+load_lib lto.exp
if { ![check_effective_target_cilkplus] } {
return;
}
-verbose "$tool $libdir" 1
set library_var [get_multilibs]
# Pointing the ld_library_path to the Cilk Runtime library binaries.
set ld_library_path "${library_var}/libcilkrts/.libs"
-set ALWAYS_CFLAGS ""
-lappend ALWAYS_CFLAGS "-L${library_var}/libcilkrts/.libs"
+global TEST_EXTRA_LIBS
+set TEST_EXTRA_LIBS "-L${library_var}/libcilkrts/.libs"
dg-init
+
+# Run the tests that are shared with C++.
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/PS/*.c]] " -ftree-vectorize -fcilkplus -std=c99" " "
+# Run the C-only tests.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \
+ "-ftree-vectorize -fcilkplus -std=c99" " "
+
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O1 -fcilkplus" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O2 -fcilkplus" " "
@@ -43,13 +50,15 @@ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -f
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -O3 -std=c99" " "
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O0 -std=c99" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -fcilkplus $ALWAYS_CFLAGS " " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1 -fcilkplus $ALWAYS_CFLAGS" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -std=c99 -fcilkplus $ALWAYS_CFLAGS" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -ftree-vectorize -fcilkplus $ALWAYS_CFLAGS" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -g -fcilkplus $ALWAYS_CFLAGS" " "
-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -flto -g -fcilkplus $ALWAYS_CFLAGS" " "
-
-
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -std=c99 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -g -fcilkplus" " "
+if { [check_effective_target_lto] } {
+ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -flto -g -fcilkplus" " "
+}
dg-finish
+
+unset TEST_EXTRA_LIBS
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/for1.c b/gcc/testsuite/gcc.dg/cilk-plus/for1.c
new file mode 100644
index 00000000000..4fb534286d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/for1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+int *a, *b, *c;
+
+void foo()
+{
+ int i, j;
+ // The initialization shall declare or initialize a *SINGLE* variable.
+#pragma simd
+ for (i=0, j=5; i < 1000; i++) // { dg-error "expected ';' before ','" }
+ a[i] = b[j];
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/for2.c b/gcc/testsuite/gcc.dg/cilk-plus/for2.c
new file mode 100644
index 00000000000..285f35a5079
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/for2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+int *a, *b;
+
+void foo()
+{
+#pragma simd
+ for (const int ci=0; ci<1000; ++ci) /* { dg-error "increment of read-only var\|invalid controlling\|invalid increment\|assignment of read" } */
+ a[ci] = b[ci];
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/jump.c b/gcc/testsuite/gcc.dg/cilk-plus/jump.c
new file mode 100644
index 00000000000..9ec3293cc97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/jump.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int *a, *b, c;
+
+void foo()
+{
+#pragma simd
+ for (int i=0; i < 1000; ++i)
+ {
+ a[i] = b[i];
+ if (c == 5)
+ return; /* { dg-error "invalid branch to.from a Cilk" } */
+ }
+}
+
+void bar()
+{
+#pragma simd
+ for (int i=0; i < 1000; ++i)
+ {
+ lab:
+ a[i] = b[i];
+ }
+ if (c == 6)
+ goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
+}
diff --git a/gcc/testsuite/gcc.dg/cpp/ucnid-9.c b/gcc/testsuite/gcc.dg/cpp/ucnid-9.c
new file mode 100644
index 00000000000..8dc43458ec2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/ucnid-9.c
@@ -0,0 +1,8 @@
+/* { dg-do preprocess } */
+/* { dg-options "-std=c99 -pedantic -fextended-identifiers" } */
+
+\u2160
+\u2182
+\u3007
+\u3021
+\u3029
diff --git a/gcc/testsuite/gcc.dg/guality/param-4.c b/gcc/testsuite/gcc.dg/guality/param-4.c
new file mode 100644
index 00000000000..a76b251f3cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/param-4.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+void
+foo (int i)
+{
+ int j = 0;
+ i = 1;
+ j = j + 1; /* BREAK */
+}
+
+int
+main (void)
+{
+ foo (0);
+ return 0;
+}
+
+/* { dg-final { gdb-test 10 "i" "1" } } */ \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c
new file mode 100644
index 00000000000..4fc00b292dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue" } */
+
+int __attribute__((noinline, noclone))
+foo (int a)
+{
+ return a + 5;
+}
+
+static int g;
+
+int __attribute__((noinline, noclone))
+bar (int a)
+{
+ int r;
+
+ if (a)
+ {
+ r = foo (a);
+ g = r + a;
+ }
+ else
+ r = a+1;
+ return r;
+}
+
+/* { dg-final { scan-rtl-dump "Will split live ranges of parameters" "ira" } } */
+/* { dg-final { scan-rtl-dump "Split live-range of register" "ira" } } */
+/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" } } */
+/* { dg-final { cleanup-rtl-dump "ira" } } */
+/* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */
diff --git a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c
new file mode 100644
index 00000000000..bb725e1651c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue" } */
+
+int __attribute__((noinline, noclone))
+foo (int a)
+{
+ return a + 5;
+}
+
+static int g;
+
+int __attribute__((noinline, noclone))
+bar (int a)
+{
+ int r;
+
+ if (a)
+ {
+ r = a;
+ while (r < 500)
+ if (r % 2)
+ r = foo (r);
+ else
+ r = foo (r+1);
+ g = r + a;
+ }
+ else
+ r = g+1;
+ return r;
+}
+
+/* { dg-final { scan-rtl-dump "Will split live ranges of parameters" "ira" } } */
+/* { dg-final { scan-rtl-dump "Split live-range of register" "ira" } } */
+/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" } } */
+/* { dg-final { cleanup-rtl-dump "ira" } } */
+/* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c
index 5331f792cb2..2498153a273 100644
--- a/gcc/testsuite/gcc.dg/plugin/selfassign.c
+++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c
@@ -11,6 +11,7 @@
#include "toplev.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
diff --git a/gcc/testsuite/gcc.dg/pr10474.c b/gcc/testsuite/gcc.dg/pr10474.c
new file mode 100644
index 00000000000..08324d83a1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr10474.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-options "-O3 -fdump-rtl-pro_and_epilogue" } */
+
+void f(int *i)
+{
+ if (!i)
+ return;
+ else
+ {
+ __builtin_printf("Hi");
+ *i=0;
+ }
+}
+
+/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" } } */
+/* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */
diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c
index ff9709ad4a2..78807bacd30 100644
--- a/gcc/testsuite/gcc.dg/stack-usage-1.c
+++ b/gcc/testsuite/gcc.dg/stack-usage-1.c
@@ -40,7 +40,11 @@
# endif
#elif defined (__powerpc64__) || defined (__ppc64__) || defined (__POWERPC64__) \
|| defined (__PPC64__)
-# define SIZE 180
+# if _CALL_ELF == 2
+# define SIZE 208
+# else
+# define SIZE 180
+# endif
#elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) \
|| defined (__POWERPC__) || defined (PPC) || defined (_IBMR2)
# if defined (__ALTIVEC__)
diff --git a/gcc/testsuite/gcc.dg/strlenopt-1.c b/gcc/testsuite/gcc.dg/strlenopt-1.c
index 5bc4f0cd176..5ed5be1f927 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-1.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-1.c
@@ -16,9 +16,7 @@ foo (char *p, char *r)
is immediately overwritten. */
strcat (q, "/");
strcat (q, "abcde");
- /* Due to inefficient PTA (PR50262) the above calls invalidate
- string length of r, so it is optimized just into strcpy instead
- of memcpy. */
+ /* This can also be optimized into memcpy. */
strcat (q, r);
return q;
}
@@ -39,8 +37,8 @@ main ()
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-1f.c b/gcc/testsuite/gcc.dg/strlenopt-1f.c
index ce1097f9b9e..e0a2c926ca2 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-1f.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-1f.c
@@ -6,8 +6,8 @@
#include "strlenopt-1.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 3 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 1 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */
+/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/tail-merge-store.c b/gcc/testsuite/gcc.dg/tail-merge-store.c
new file mode 100644
index 00000000000..1aefbdc1495
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tail-merge-store.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */
+
+int z;
+int x;
+
+void
+f (int c, int d)
+{
+ if (c)
+ z = 5;
+ else
+ {
+ if (d)
+ x = 4;
+ z = 5;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "duplicate of" 1 "pre"} } */
+/* { dg-final { scan-tree-dump-times "z = 5" 1 "pre"} } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tls/diag-2.c b/gcc/testsuite/gcc.dg/tls/diag-2.c
index 8276cb3be49..854824385a5 100644
--- a/gcc/testsuite/gcc.dg/tls/diag-2.c
+++ b/gcc/testsuite/gcc.dg/tls/diag-2.c
@@ -3,7 +3,7 @@
__thread extern int g1; /* { dg-error "'__thread' before 'extern'" } */
__thread static int g2; /* { dg-error "'__thread' before 'static'" } */
-__thread __thread int g3; /* { dg-error "duplicate '__thread'" } */
+__thread __thread int g3; /* { dg-error "duplicate" } */
typedef __thread int g4; /* { dg-error "'__thread' used with 'typedef'" } */
void foo()
diff --git a/gcc/testsuite/gcc.dg/torture/20131115-1.c b/gcc/testsuite/gcc.dg/torture/20131115-1.c
new file mode 100644
index 00000000000..edb05f04c47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/20131115-1.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+struct S { int i; };
+__attribute__((const, noinline, noclone))
+struct S foo (int x)
+{
+ struct S s;
+ s.i = x;
+ return s;
+}
+
+int a[2048], b[2048], c[2048], d[2048];
+struct S e[2048];
+
+__attribute__((noinline, noclone)) void
+bar (void)
+{
+ int i;
+ for (i = 0; i < 1024; i++)
+ {
+ e[i] = foo (i);
+ a[i+2] = a[i] + a[i+1];
+ b[10] = b[10] + i;
+ c[i] = c[2047 - i];
+ d[i] = d[i + 1];
+ }
+}
+
+int
+main ()
+{
+ int i;
+ bar ();
+ for (i = 0; i < 1024; i++)
+ if (e[i].i != i)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c b/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c
index 53ef7ed01b3..9d37ba25b6d 100644
--- a/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c
+++ b/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c
@@ -1,6 +1,7 @@
/* Test for "invalid" exceptions from __float128 comparisons. */
/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
/* { dg-options "" } */
+/* { dg-require-effective-target fenv_exceptions } */
#include <fenv.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c b/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c
index 43d350f4e44..f721e562b8a 100644
--- a/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c
+++ b/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c
@@ -1,6 +1,7 @@
/* Test for spurious underflow from __float128 division. */
/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
/* { dg-options "" } */
+/* { dg-require-effective-target fenv_exceptions } */
#include <fenv.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c b/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c
index 1942d80f190..60f9bbe9435 100644
--- a/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c
+++ b/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c
@@ -1,6 +1,7 @@
/* Test extensions to __float128 quiet signaling NaNs. */
/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
/* { dg-options "-fsignaling-nans" } */
+/* { dg-require-effective-target fenv_exceptions } */
#include <fenv.h>
#include <float.h>
diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c
new file mode 100644
index 00000000000..c61b534a250
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-1.c
@@ -0,0 +1,22 @@
+/* { dg-options "-O2 -fdump-ipa-profile" } */
+
+__attribute__ ((noinline))
+int foo()
+{
+ return 0;
+}
+
+__attribute__ ((noinline))
+int bar()
+{
+ return 1;
+}
+
+int main ()
+{
+ return foo ();
+}
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 0" 1 "profile"} } */
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 1" 1 "profile"} } */
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 2" 1 "profile"} } */
+/* { dg-final-use { cleanup-ipa-dump "profile" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
new file mode 100644
index 00000000000..04113419753
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
@@ -0,0 +1,50 @@
+/* { dg-options "-O2 -fdump-ipa-profile" } */
+
+#include <unistd.h>
+
+__attribute__ ((noinline))
+int foo()
+{
+ return 1;
+}
+
+__attribute__ ((noinline))
+int bar()
+{
+ return 1;
+}
+
+__attribute__ ((noinline))
+int baz()
+{
+ return 1;
+}
+
+__attribute__ ((noinline))
+int baz1()
+{
+ return 1;
+}
+
+int main ()
+{
+ int f = fork();
+ int r = 0;
+
+ foo ();
+
+ if (f < 0)
+ return 1; /* Fork failed. */
+
+ if(f == 0) /* Child process. */
+ r = bar() - foo();
+ else /* Parent process. */
+ r = foo() - foo();
+
+ return r;
+}
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 0" 2 "profile"} } */
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 1" 1 "profile"} } */
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 2" 1 "profile"} } */
+/* { dg-final-use { scan-ipa-dump-times "Read tp_first_run: 3" 1 "profile"} } */
+/* { dg-final-use { cleanup-ipa-dump "profile" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-27.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-27.c
new file mode 100644
index 00000000000..91c737eae25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-27.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+void f (long *p) {
+ *p = 42;
+ p[4] = 42;
+ __builtin_memset (p, 0, 100);
+}
+
+/* { dg-final { scan-tree-dump-not "= 42" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-28.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-28.c
new file mode 100644
index 00000000000..8413230eaf4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-28.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+extern void abort (void);
+extern void *malloc(__SIZE_TYPE__);
+
+int * __attribute__((noinline,noclone))
+foo (int *p)
+{
+ int *q = (int *) malloc (sizeof (int));
+ *p = 1;
+ *q = 2;
+ if (*p != 1)
+ __link_error ();
+ *p = 3;
+ return q;
+}
+
+int main()
+{
+ int i;
+ int *p = foo (&i);
+ if (i != 3 || *p != 2)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
index a64987bfdfa..1a4bf4a4444 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
@@ -1,5 +1,9 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+/* Skip on ARM Cortex-M, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
+ leading to two conditional jumps when evaluating an && condition. Forwprop1
+ is not able to optimize this. */
+/* { dg-skip-if "" { arm_cortex_m } } */
extern char *frob (void);
extern _Bool testit (void);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c
index 6b779b4a4bc..f1f3101d3d2 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c
@@ -43,12 +43,14 @@ d_type (struct d_info *di)
return ret;
}
-/* We're testing two aspects of isolation here. First that isolation
+/* We're testing three aspects of isolation here. First that isolation
occurs, second that if we have two null dereferences in a block that
that we delete everything from the first dereferece to the end of the
- block, regardless of which comes first in the immediate use iterator. */
+ block, regardless of which comes first in the immediate use iterator
+ and finally that we set the RHS of the store to zero. */
/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */
-/* { dg-final { scan-tree-dump-times "->type" 1 "isolate-paths"} } */
+/* { dg-final { scan-tree-dump-times "->type = 42" 1 "isolate-paths"} } */
+/* { dg-final { scan-tree-dump-times "->type ={v} 0" 1 "isolate-paths"} } */
/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */
/* { dg-final { cleanup-tree-dump "isolate-paths" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c
new file mode 100644
index 00000000000..ee587d2320d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c
@@ -0,0 +1,62 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-isolate-paths -fdump-tree-optimized" } */
+
+
+struct demangle_component
+{
+
+ int type;
+ int zzz;
+
+};
+
+
+struct d_info
+{
+ struct demangle_component *comps;
+ int next_comp;
+ int num_comps;
+};
+
+
+static struct demangle_component *
+d_make_empty (struct d_info *di)
+{
+ struct demangle_component *p;
+
+ if (di->next_comp >= di->num_comps)
+ return ((void *)0);
+ p = &di->comps[di->next_comp];
+ return p;
+}
+
+
+
+struct demangle_component *
+d_type (struct d_info *di)
+{
+ struct demangle_component *ret;
+ ret = d_make_empty (di);
+ foo (ret->type);
+ bar (ret->zzz);
+ return ret;
+}
+
+/* We're testing two aspects of isolation here. First that isolation
+ occurs, second that if we have two null dereferences in a block that
+ that we delete everything from the first dereferece to the end of the
+ block, regardless of which comes first in the immediate use iterator.
+
+ We leave the 0->type in the IL, so expect to see ->type twice. */
+/* { dg-final { scan-tree-dump-times "__builtin_trap" 1 "isolate-paths"} } */
+/* { dg-final { scan-tree-dump-times "->type" 2 "isolate-paths"} } */
+/* { dg-final { scan-tree-dump-times "->type" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "\\.type" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */
+/* { dg-final { cleanup-tree-dump "isolate-paths" } } */
+/* { dg-final { cleanup-tree-dump "optimized-paths" } } */
+
+
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
index e97719f9c13..0e4797cbd9f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
@@ -59,9 +59,9 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
code we missed the edge when the first conditional is false
(b_elt is zero, which means the second conditional is always
zero. */
-/* ARM Cortex-M0 defined LOGICAL_OP_NON_SHORT_CIRCUIT to false,
+/* ARM Cortex-M defined LOGICAL_OP_NON_SHORT_CIRCUIT to false,
so skip below test. */
-/* { dg-final { scan-tree-dump-times "Threaded" 3 "dom1" { target { ! { { mips*-*-* avr-*-* } || { arm_cortex_m && arm_thumb1 } } } } } } */
+/* { dg-final { scan-tree-dump-times "Threaded" 3 "dom1" { target { ! { { mips*-*-* avr-*-* arc*-*-* } || { arm_cortex_m } } } } } } */
/* MIPS defines LOGICAL_OP_NON_SHORT_CIRCUIT to 0, so we split both
"a_elt || b_elt" and "b_elt && kill_elt" into two conditions each,
rather than using "(var1 != 0) op (var2 != 0)". Also, as on other targets,
@@ -81,8 +81,9 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
-> "kill_elt->indx == b_elt->indx" in the second condition,
skipping the known-true "b_elt && kill_elt" in the second
condition. */
+/* Likewise for arc. */
/* For avr, BRANCH_COST is by default 0, so the default
LOGICAL_OP_NON_SHORT_CIRCUIT definition also computes as 0. */
-/* { dg-final { scan-tree-dump-times "Threaded" 6 "dom1" { target mips*-*-* avr-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Threaded" 6 "dom1" { target mips*-*-* avr-*-* arc*-*-* } } } */
/* { dg-final { cleanup-tree-dump "dom1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c
index 56c936daccd..efc8a7133c9 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c
index 8b8710115c0..3be2310e9b5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c
index 2aa225bd433..c22a0e04c11 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c
index 659e8164beb..aa0970dee7f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c
index 9d9473e7f31..476ee5e9411 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c
@@ -26,6 +26,8 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
oof ();
}
-/* { dg-final { scan-tree-dump-times "Threaded" 1 "vrp1" } } */
+/* ARM Cortex-M defined LOGICAL_OP_NON_SHORT_CIRCUIT to false,
+ so skip below test. */
+/* { dg-final { scan-tree-dump-times "Threaded" 1 "vrp1" { target { ! arm_cortex_m } } } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c
index d8c5841eb58..5a09fa0f49d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp47.c
@@ -1,15 +1,15 @@
-/* Skip on MIPS, where LOGICAL_OP_NON_SHORT_CIRCUIT inhibits the setcc
+/* Skip on MIPS/ARC, where LOGICAL_OP_NON_SHORT_CIRCUIT inhibits the setcc
optimizations that expose the VRP opportunity. */
/* Skip on S/390 and avr. Lower values in BRANCH_COST lead to two conditional
jumps when evaluating an && condition. VRP is not able to optimize
this. */
-/* { dg-do compile { target { ! "mips*-*-* s390*-*-* avr-*-* mn10300-*-*" } } } */
+/* { dg-do compile { target { ! "mips*-*-* arc*-*-* s390*-*-* avr-*-* mn10300-*-*" } } } */
/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-dom1 -fdump-tree-vrp2" } */
/* { dg-additional-options "-march=i586" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
-/* Skip on ARM Cortex-M0, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
+/* Skip on ARM Cortex-M, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
leading to two conditional jumps when evaluating an && condition. VRP is
not able to optimize this. */
-/* { dg-skip-if "" { arm_cortex_m && arm_thumb1} } */
+/* { dg-skip-if "" { arm_cortex_m } } */
int h(int x, int y)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
index 7339823f480..9aff0a6c46f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
@@ -1,7 +1,11 @@
-/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
+/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-* arc*-*-*"} } } */
/* { dg-options "-O2 -fdump-tree-vrp2-details -fdump-tree-cddce2-details" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
+/* Skip on ARM Cortex-M, where LOGICAL_OP_NON_SHORT_CIRCUIT is set to false,
+ leading to two conditional jumps when evaluating an && condition. VRP is
+ not able to optimize this. */
+/* { dg-skip-if "" { arm_cortex_m } } */
struct bitmap_head_def;
typedef struct bitmap_head_def *bitmap;
diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check.c
index 64a4e0ce05c..c1bffed2f48 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-alias-check.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check.c
@@ -1,17 +1,17 @@
/* { dg-require-effective-target vect_int } */
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize --param=vect-max-version-for-alias-checks=2 -fdump-tree-vect-details" } */
+/* { dg-additional-options "--param=vect-max-version-for-alias-checks=2" } */
-/* A test case showing three potential alias checks between
- a[i] and b[i], b[i+7], b[i+14]. With alias checks merging
- enabled, those tree checks can be merged into one, and the
- loop will be vectorized with vect-max-version-for-alias-checks=2. */
+/* A test case showing four potential alias checks between a[i] and b[0], b[1],
+ b[i+1] and b[i+2]. With alias check merging enabled, those four checks
+ can be merged into two, and the loop will be vectorized with
+ vect-max-version-for-alias-checks=2. */
void foo (int *a, int *b)
{
int i;
for (i = 0; i < 1000; ++i)
- a[i] = b[i] + b[i+7] + b[i+14];
+ a[i] = b[0] + b[1] + b[i+1] + b[i+2];
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-15.c b/gcc/testsuite/gcc.dg/vmx/3b-15.c
index ec9cf2c5a0d..356e248b761 100644
--- a/gcc/testsuite/gcc.dg/vmx/3b-15.c
+++ b/gcc/testsuite/gcc.dg/vmx/3b-15.c
@@ -3,7 +3,11 @@
vector unsigned char
f (vector unsigned char a, vector unsigned char b, vector unsigned char c)
{
+#ifdef __BIG_ENDIAN__
return vec_perm(a,b,c);
+#else
+ return vec_perm(b,a,c);
+#endif
}
static void test()
@@ -12,8 +16,13 @@ static void test()
8,9,10,11,12,13,14,15}),
((vector unsigned char){70,71,72,73,74,75,76,77,
78,79,80,81,82,83,84,85}),
+#ifdef __BIG_ENDIAN__
((vector unsigned char){0x1,0x14,0x18,0x10,0x16,0x15,0x19,0x1a,
0x1c,0x1c,0x1c,0x12,0x8,0x1d,0x1b,0xe})),
+#else
+ ((vector unsigned char){0x1e,0xb,0x7,0xf,0x9,0xa,0x6,0x5,
+ 0x3,0x3,0x3,0xd,0x17,0x2,0x4,0x11})),
+#endif
((vector unsigned char){1,74,78,70,76,75,79,80,82,82,82,72,8,83,81,14})),
"f");
}
diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c
index 284971d832c..2ca006598ff 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c
@@ -1,5 +1,5 @@
/* { dg-error "missing" "" {target "aarch64*-*-*" } } */
-/* { dg-options "-O2 -mcpu=example-1+no" } */
+/* { dg-options "-O2 -mcpu=cortex-a53+no" } */
void f ()
{
diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c
index 4e5d17c3b82..155def05155 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c
@@ -1,5 +1,5 @@
/* { dg-error "unknown" "" {target "aarch64*-*-*" } } */
-/* { dg-options "-O2 -mcpu=example-1+dummy" } */
+/* { dg-options "-O2 -mcpu=cortex-a53+dummy" } */
void f ()
{
diff --git a/gcc/testsuite/gcc.target/i386/pr58853.c b/gcc/testsuite/gcc.target/i386/pr58853.c
new file mode 100644
index 00000000000..046da8bee5f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr58853.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-minline-all-stringops" } */
+/* { dg-additional-options "-mtune=pentiumpro" { target { ia32 } } } */
+
+void
+my_memcpy (char *dest, const char *src, int n)
+{
+ __builtin_memcpy (dest, src, n);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/no-r11-1.c b/gcc/testsuite/gcc.target/powerpc/no-r11-1.c
index 57c01a3e259..94b7988ec76 100644
--- a/gcc/testsuite/gcc.target/powerpc/no-r11-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/no-r11-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
/* { dg-options "-O2 -mno-pointers-to-nested-functions" } */
int
diff --git a/gcc/testsuite/gcc.target/powerpc/no-r11-2.c b/gcc/testsuite/gcc.target/powerpc/no-r11-2.c
index 3e4a6ca0ff4..214a9dfb49a 100644
--- a/gcc/testsuite/gcc.target/powerpc/no-r11-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/no-r11-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
/* { dg-options "-O2 -mpointers-to-nested-functions" } */
int
diff --git a/gcc/testsuite/gcc.target/powerpc/no-r11-3.c b/gcc/testsuite/gcc.target/powerpc/no-r11-3.c
index c98797e7f69..9cc83090921 100644
--- a/gcc/testsuite/gcc.target/powerpc/no-r11-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/no-r11-3.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
/* { dg-options "-O2 -mno-pointers-to-nested-functions" } */
extern void ext_call (int (func) (void));
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
index 8fcb7fd7fae..9dc730e0dbd 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
@@ -89,8 +89,10 @@ typedef struct sf
long a1;
long a2;
long a3;
+#if _CALL_ELF != 2
long a4;
long a5;
+#endif
parm_t slot[100];
} stack_frame_t;
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c
index a9883d9e335..fdb781554c6 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-2.c
@@ -107,8 +107,10 @@ typedef struct sf
long a1;
long a2;
long a3;
+#if _CALL_ELF != 2
long a4;
long a5;
+#endif
parm_t slot[100];
} stack_frame_t;
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-dfp-1.c b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-dfp-1.c
index eb54a653bf7..4e91b1bba26 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc64-abi-dfp-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc64-abi-dfp-1.c
@@ -33,15 +33,27 @@ reg_parms_t gparms;
/* Wrapper to save the GPRs and FPRs and then jump to the real function. */
+#if _CALL_ELF != 2
+#define FUNC_START(NAME) \
+ "\t.globl\t" NAME "\n\t" \
+ ".section \".opd\",\"aw\"\n\t" \
+ ".align 3\n" \
+ NAME ":\n\t" \
+ ".quad .L." NAME ",.TOC.@tocbase,0\n\t" \
+ ".text\n\t" \
+ ".type " NAME ", @function\n" \
+ ".L." NAME ":\n\t"
+#else
+#define FUNC_START(NAME) \
+ "\t.globl\t" NAME "\n\t" \
+ ".text\n\t" \
+ NAME ":\n" \
+ "0:\taddis 2,12,(.TOC.-0b)@ha\n\t" \
+ "addi 2,2,(.TOC.-0b)@l\n\t" \
+ ".localentry " NAME ",.-" NAME "\n\t"
+#endif
#define WRAPPER(NAME) \
-__asm__ ("\t.globl\t" #NAME "_asm\n\t" \
- ".section \".opd\",\"aw\"\n\t" \
- ".align 3\n" \
- #NAME "_asm:\n\t" \
- ".quad .L." #NAME "_asm,.TOC.@tocbase,0\n\t" \
- ".text\n\t" \
- ".type " #NAME "_asm, @function\n" \
- ".L." #NAME "_asm:\n\t" \
+__asm__ (FUNC_START (#NAME "_asm") \
"ld 11,gparms@got(2)\n\t" \
"std 3,0(11)\n\t" \
"std 4,8(11)\n\t" \
@@ -75,8 +87,10 @@ typedef struct sf
long a1;
long a2;
long a3;
+#if _CALL_ELF != 2
long a4;
long a5;
+#endif
unsigned long slot[100];
} stack_frame_t;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57949-1.c b/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
index 253b2d89083..c2eecea1b84 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
/* { dg-options "-O2 -mcpu=power7" } */
/* Verify that vs is 16-byte aligned in the absence of -mcompat-align-parm. */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57949-2.c b/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
index aa6a0d9631a..e5ad212f3e3 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc_elfv2 } { "*" } { "" } } */
/* { dg-options "-O2 -mcpu=power7 -mcompat-align-parm" } */
/* Verify that vs is not 16-byte aligned with -mcompat-align-parm. */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr59054.c b/gcc/testsuite/gcc.target/powerpc/pr59054.c
new file mode 100644
index 00000000000..0379aeee635
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr59054.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O0 -m64" } */
+
+long foo (void) { return 0; }
+
+/* { dg-final { scan-assembler-not "xxlor" } } */
+/* { dg-final { scan-assembler-not "stfd" } } */
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O0 -m64" } */
+
+long foo (void) { return 0; }
+
+/* { dg-final { scan-assembler-not "xxlor" } } */
+/* { dg-final { scan-assembler-not "stfd" } } */
diff --git a/gcc/testsuite/gnat.dg/aggr21.adb b/gcc/testsuite/gnat.dg/aggr21.adb
new file mode 100644
index 00000000000..3dd332705ea
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr21.adb
@@ -0,0 +1,14 @@
+-- { dg-do run }
+
+with Aggr21_Pkg; use Aggr21_Pkg;
+
+procedure Aggr21 is
+ V : Rec;
+begin
+ V.A := 12;
+ V.S (1 .. 10) := "Hello init";
+ V.N := 123;
+ Init (V);
+ -- Probably not reliable, but the compiler is supposed not to modify V.S
+ pragma Assert (V.s (1 .. 5) = "Hello");
+end;
diff --git a/gcc/testsuite/gnat.dg/aggr21_pkg.adb b/gcc/testsuite/gnat.dg/aggr21_pkg.adb
new file mode 100644
index 00000000000..5cdd089cf1e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr21_pkg.adb
@@ -0,0 +1,8 @@
+package body Aggr21_Pkg is
+
+ procedure Init (R : out Rec) is
+ begin
+ R := (A => 5, S => <>, N => 7);
+ end;
+
+end Aggr21_Pkg;
diff --git a/gcc/testsuite/gnat.dg/aggr21_pkg.ads b/gcc/testsuite/gnat.dg/aggr21_pkg.ads
new file mode 100644
index 00000000000..3a14963b130
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr21_pkg.ads
@@ -0,0 +1,11 @@
+package Aggr21_Pkg is
+
+ type Rec is record
+ A : Integer;
+ S : String (1 .. 120);
+ N : Natural;
+ end record;
+
+ procedure Init (R : out Rec);
+
+end Aggr21_Pkg;
diff --git a/gcc/testsuite/gnat.dg/stack_usage1b.adb b/gcc/testsuite/gnat.dg/stack_usage1b.adb
new file mode 100644
index 00000000000..4129c0d34a7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/stack_usage1b.adb
@@ -0,0 +1,39 @@
+-- { dg-do compile }
+-- { dg-options "-O -fstack-usage" }
+
+with Stack_Usage1_Pkg; use Stack_Usage1_Pkg;
+
+procedure Stack_Usage1b is
+
+ A : Integer := Ident_Int (123);
+
+begin
+ case A is
+ when 0 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 1 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 2 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 3 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 4 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 5 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 6 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 7 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 8 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 9 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when others =>
+ null;
+ end case;
+
+end Stack_Usage1b;
+
+-- { dg-final { scan-stack-usage "\t\[0-9\]\[0-9\]\t" { target i?86-*-* x86_64-*-* } } }
+-- { dg-final { cleanup-stack-usage } }
diff --git a/gcc/testsuite/gnat.dg/stack_usage1c.adb b/gcc/testsuite/gnat.dg/stack_usage1c.adb
new file mode 100644
index 00000000000..41b7a60563a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/stack_usage1c.adb
@@ -0,0 +1,39 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -fstack-usage" }
+
+with Stack_Usage1_Pkg; use Stack_Usage1_Pkg;
+
+procedure Stack_Usage1c is
+
+ A : Integer := Ident_Int (123);
+
+begin
+ case A is
+ when 0 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 1 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 2 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 3 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 4 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 5 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 6 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 7 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 8 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when 9 =>
+ My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+ when others =>
+ null;
+ end case;
+
+end Stack_Usage1c;
+
+-- { dg-final { scan-stack-usage "\t\[0-9\]\[0-9\]\t" { target i?86-*-* x86_64-*-* } } }
+-- { dg-final { cleanup-stack-usage } }
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index ec6c7150121..2018ae57626 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -294,6 +294,11 @@ proc g++_target_compile { source dest type options } {
lappend options "ldflags=${wrap_flags}"
}
+ global TEST_EXTRA_LIBS
+ if [info exists TEST_EXTRA_LIBS] {
+ lappend options "ldflags=$TEST_EXTRA_LIBS"
+ }
+
lappend options "additional_flags=[libio_include_flags]"
lappend options "compiler=$GXX_UNDER_TEST"
lappend options "timeout=[timeout_value]"
diff --git a/gcc/testsuite/lib/gcc.exp b/gcc/testsuite/lib/gcc.exp
index ea7782df2a0..d9251ab44ab 100644
--- a/gcc/testsuite/lib/gcc.exp
+++ b/gcc/testsuite/lib/gcc.exp
@@ -134,6 +134,11 @@ proc gcc_target_compile { source dest type options } {
lappend options "ldflags=$wrap_flags"
}
+ global TEST_EXTRA_LIBS
+ if [info exists TEST_EXTRA_LIBS] {
+ lappend options "ldflags=$TEST_EXTRA_LIBS"
+ }
+
if [target_info exists gcc,stack_size] {
lappend options "additional_flags=-DSTACK_SIZE=[target_info gcc,stack_size]"
}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index c3d9712772e..104818d327e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1995,7 +1995,8 @@ proc check_effective_target_vect_cmdline_needed { } {
|| [check_effective_target_powerpc_altivec]))
|| ([istarget sparc*-*-*] && [check_effective_target_sparc_vis])
|| [istarget spu-*-*]
- || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
+ || [istarget aarch64*-*-*] } {
set et_vect_cmdline_needed_saved 0
}
}
@@ -3019,6 +3020,22 @@ proc check_effective_target_powerpc_405_nocache { } {
}
}
+# Return 1 if this is a PowerPC target using the ELFv2 ABI.
+
+proc check_effective_target_powerpc_elfv2 { } {
+ if { [istarget powerpc*-*-*] } {
+ return [check_no_compiler_messages powerpc_elfv2 object {
+ #if _CALL_ELF != 2
+ #error not ELF v2 ABI
+ #else
+ int dummy;
+ #endif
+ }]
+ } else {
+ return 0
+ }
+}
+
# Return 1 if this is a SPU target with a toolchain that
# supports automatic overlay generation.
diff --git a/gcc/testsuite/objc.dg/tls/diag-2.m b/gcc/testsuite/objc.dg/tls/diag-2.m
index 4f22281eb9c..58cca01494b 100644
--- a/gcc/testsuite/objc.dg/tls/diag-2.m
+++ b/gcc/testsuite/objc.dg/tls/diag-2.m
@@ -3,7 +3,7 @@
__thread extern int g1; /* { dg-error "'__thread' before 'extern'" } */
__thread static int g2; /* { dg-error "'__thread' before 'static'" } */
-__thread __thread int g3; /* { dg-error "duplicate '__thread'" } */
+__thread __thread int g3; /* { dg-error "duplicate" } */
typedef __thread int g4; /* { dg-error " '__thread' used with 'typedef'" } */
void foo()
diff --git a/gcc/toplev.c b/gcc/toplev.c
index ad6849996e1..66477b651dc 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1968,11 +1968,13 @@ toplev_main (int argc, char **argv)
if (warningcount || errorcount || werrorcount)
print_ignored_options ();
- diagnostic_finish (global_dc);
- /* Invoke registered plugin callbacks if any. */
+ /* Invoke registered plugin callbacks if any. Some plugins could
+ emit some diagnostics here. */
invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
+ diagnostic_finish (global_dc);
+
finalize_plugins ();
location_adhoc_data_fini (line_table);
if (seen_error () || werrorcount)
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 86557febab7..71a9201fd09 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -47,6 +47,7 @@
#include "coverage.h"
#include "tree-pass.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa.h"
#include "tree-inline.h"
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 02bb5590fff..31b4a0d190a 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -23,6 +23,10 @@
#include "hash-table.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -321,6 +325,22 @@ is_tm_ending_fndecl (tree fndecl)
return false;
}
+/* Return true if STMT is a built in function call that "ends" a
+ transaction. */
+
+bool
+is_tm_ending (gimple stmt)
+{
+ tree fndecl;
+
+ if (gimple_code (stmt) != GIMPLE_CALL)
+ return false;
+
+ fndecl = gimple_call_fndecl (stmt);
+ return (fndecl != NULL_TREE
+ && is_tm_ending_fndecl (fndecl));
+}
+
/* Return true if STMT is a TM load. */
static bool
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 07a5d2eda62..cb8fd60b118 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "tree-affine.h"
#include "gimple.h"
+#include "gimplify.h"
#include "flags.h"
#include "dumpfile.h"
#include "wide-int-print.h"
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 58065ad8377..58003612e63 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-ssanames.h"
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 6c551f4fe96..b981b944517 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -31,6 +31,9 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index c627d2cac57..e864eed94f8 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "langhooks.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 6439402ba75..130674e673f 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -24,6 +24,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "flags.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 0800b364d98..de472398895 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -845,6 +845,9 @@ struct GTY(()) tree_base {
VAR_DECL, FUNCTION_DECL
IDENTIFIER_NODE
+ CONSTRUCTOR_NO_CLEARING in
+ CONSTRUCTOR
+
ASM_VOLATILE_P in
ASM_EXPR
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 67528a8d7c5..84d54f735f4 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
#include "tree-ssa.h"
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 03e5bccd25e..b2084961a3f 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index a489b61c3f2..656ba6f5cb3 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "except.h"
#include "pointer-set.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index b5ca407d62e..11337c0c127 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "tree-pass.h"
#include "gimple-ssa.h"
#include "cgraph.h"
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index bb8de6d6ad7..81403f25aa0 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -89,6 +89,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 2796ff22362..29f7a7f2709 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -35,6 +35,10 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "intl.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -2351,6 +2355,29 @@ redirect_all_calls (copy_body_data * id, basic_block bb)
}
}
+/* Convert estimated frequencies into counts for NODE, scaling COUNT
+ with each bb's frequency. Used when NODE has a 0-weight entry
+ but we are about to inline it into a non-zero count call bb.
+ See the comments for handle_missing_profiles() in predict.c for
+ when this can happen for COMDATs. */
+
+void
+freqs_to_counts (struct cgraph_node *node, gcov_type count)
+{
+ basic_block bb;
+ edge_iterator ei;
+ edge e;
+ struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
+
+ FOR_ALL_BB_FN(bb, fn)
+ {
+ bb->count = apply_scale (count,
+ GCOV_COMPUTE_SCALE (bb->frequency, BB_FREQ_MAX));
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ e->count = apply_probability (e->src->count, e->probability);
+ }
+}
+
/* Make a copy of the body of FN so that it can be inserted inline in
another function. Walks FN via CFG, returns new fndecl. */
@@ -2371,6 +2398,24 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
int incoming_frequency = 0;
gcov_type incoming_count = 0;
+ /* This can happen for COMDAT routines that end up with 0 counts
+ despite being called (see the comments for handle_missing_profiles()
+ in predict.c as to why). Apply counts to the blocks in the callee
+ before inlining, using the guessed edge frequencies, so that we don't
+ end up with a 0-count inline body which can confuse downstream
+ optimizations such as function splitting. */
+ if (!ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count && count)
+ {
+ /* Apply the larger of the call bb count and the total incoming
+ call edge count to the callee. */
+ gcov_type in_count = 0;
+ struct cgraph_edge *in_edge;
+ for (in_edge = id->src_node->callers; in_edge;
+ in_edge = in_edge->next_caller)
+ in_count += in_edge->count;
+ freqs_to_counts (id->src_node, count > in_count ? count : in_count);
+ }
+
if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count)
count_scale
= GCOV_COMPUTE_SCALE (count,
@@ -4459,21 +4504,6 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
}
}
-/* Return true if BB has at least one abnormal outgoing edge. */
-
-static inline bool
-has_abnormal_outgoing_edge_p (basic_block bb)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_ABNORMAL)
- return true;
-
- return false;
-}
-
/* Expand calls to inline functions in the body of FN. */
unsigned int
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 981e9f4bfb4..e7c5d50da0c 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-iterator.c b/gcc/tree-iterator.c
index 53347b54dc6..71329089657 100644
--- a/gcc/tree-iterator.c
+++ b/gcc/tree-iterator.c
@@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h"
#include "tree-iterator.h"
#include "ggc.h"
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 45efad3f110..075487726f4 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -46,6 +46,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -1722,8 +1724,7 @@ tree_loop_distribution (void)
if (stmt_has_scalar_dependences_outside_loop (loop, stmt))
;
/* Otherwise only distribute stores for now. */
- else if (!gimple_assign_single_p (stmt)
- || is_gimple_reg (gimple_assign_lhs (stmt)))
+ else if (!gimple_vdef (stmt))
continue;
work_list.safe_push (stmt);
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index dc63ef6902e..9b4493bade0 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -27,6 +27,9 @@
#include "tree-dump.h"
#include "tree-inline.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "tree-iterator.h"
#include "bitmap.h"
#include "cgraph.h"
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index 1425d195252..b333abf3956 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-pass.h"
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index f983d2e451a..81a922bd26a 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-pass.h"
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 4dc3f9e4a8d..eb11c883fb4 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "sbitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index c357f1fe14c..867992b6bb9 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -24,6 +24,10 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
index 2cef1c4ab23..da7bf5be978 100644
--- a/gcc/tree-phinodes.c
+++ b/gcc/tree-phinodes.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
@@ -504,5 +505,18 @@ degenerate_phi_result (gimple phi)
return (i == gimple_phi_num_args (phi) ? val : NULL);
}
+/* Set PHI nodes of a basic block BB to SEQ. */
+
+void
+set_phi_nodes (basic_block bb, gimple_seq seq)
+{
+ gimple_stmt_iterator i;
+
+ gcc_checking_assert (!(bb->flags & BB_RTL));
+ bb->il.gimple.phi_nodes = seq;
+ if (seq)
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ gimple_set_bb (gsi_stmt (i), bb);
+}
#include "gt-tree-phinodes.h"
diff --git a/gcc/tree-phinodes.h b/gcc/tree-phinodes.h
index ae6222b336e..4dd5e1362d3 100644
--- a/gcc/tree-phinodes.h
+++ b/gcc/tree-phinodes.h
@@ -30,21 +30,7 @@ extern void remove_phi_args (edge);
extern void remove_phi_node (gimple_stmt_iterator *, bool);
extern void remove_phi_nodes (basic_block);
extern tree degenerate_phi_result (gimple);
-
-/* Set PHI nodes of a basic block BB to SEQ. */
-
-static inline void
-set_phi_nodes (basic_block bb, gimple_seq seq)
-{
- gimple_stmt_iterator i;
-
- gcc_checking_assert (!(bb->flags & BB_RTL));
- bb->il.gimple.phi_nodes = seq;
- if (seq)
- for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
- gimple_set_bb (gsi_stmt (i), bb);
-}
-
+extern void set_phi_nodes (basic_block, gimple_seq);
static inline use_operand_p
gimple_phi_arg_imm_use_ptr (gimple gs, int i)
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index c66192078ff..338b0ff2ea8 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -192,6 +192,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "cfgloop.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 14b5414e571..78db8e70f91 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -2394,6 +2394,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, "#pragma omp simd");
goto dump_omp_loop;
+ case CILK_SIMD:
+ pp_string (buffer, "#pragma simd");
+ goto dump_omp_loop;
+
case OMP_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
goto dump_omp_loop;
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index e98ea686fbc..f3f97b2e0dc 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -35,6 +35,9 @@ along with GCC; see the file COPYING3. If not see
#include "coverage.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -51,9 +54,10 @@ static GTY(()) tree tree_interval_profiler_fn;
static GTY(()) tree tree_pow2_profiler_fn;
static GTY(()) tree tree_one_value_profiler_fn;
static GTY(()) tree tree_indirect_call_profiler_fn;
+static GTY(()) tree tree_time_profiler_fn;
static GTY(()) tree tree_average_profiler_fn;
static GTY(()) tree tree_ior_profiler_fn;
-
+
static GTY(()) tree ic_void_ptr_var;
static GTY(()) tree ic_gcov_type_ptr_var;
@@ -63,7 +67,8 @@ static GTY(()) tree ptr_void;
/* Add code:
__thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
- __thread void* __gcov_indirect_call_callee; // actual callee address
+ __thread void* __gcov_indirect_call_callee; // actual callee address
+ __thread int __gcov_function_counter; // time profiler function counter
*/
static void
init_ic_make_global_vars (void)
@@ -145,6 +150,7 @@ gimple_init_edge_profiler (void)
tree gcov_type_ptr;
tree ic_profiler_fn_type;
tree average_profiler_fn_type;
+ tree time_profiler_fn_type;
if (!gcov_type_node)
{
@@ -222,6 +228,18 @@ gimple_init_edge_profiler (void)
= tree_cons (get_identifier ("leaf"), NULL,
DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
+ /* void (*) (gcov_type *, gcov_type, void *) */
+ time_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_ptr, NULL_TREE);
+ tree_time_profiler_fn
+ = build_fn_decl ("__gcov_time_profiler",
+ time_profiler_fn_type);
+ TREE_NOTHROW (tree_time_profiler_fn) = 1;
+ DECL_ATTRIBUTES (tree_time_profiler_fn)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (tree_time_profiler_fn));
+
/* void (*) (gcov_type *, gcov_type) */
average_profiler_fn_type
= build_function_type_list (void_type_node,
@@ -247,6 +265,7 @@ gimple_init_edge_profiler (void)
DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
+ DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
}
@@ -455,6 +474,23 @@ gimple_gen_ic_func_profiler (void)
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
}
+/* Output instructions as GIMPLE tree at the beginning for each function.
+ TAG is the tag of the section for counters, BASE is offset of the
+ counter position and GSI is the iterator we place the counter. */
+
+void
+gimple_gen_time_profiler (unsigned tag, unsigned base,
+ gimple_stmt_iterator &gsi)
+{
+ tree ref_ptr = tree_coverage_counter_addr (tag, base);
+ gimple call;
+
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
+ true, NULL_TREE, true, GSI_SAME_STMT);
+ call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
+ gsi_insert_before (&gsi, call, GSI_NEW_STMT);
+}
+
/* Output instructions as GIMPLE trees for code to find the most common value
of a difference between two evaluations of an expression.
VALUE is the expression whose value is profiled. TAG is the tag of the
@@ -612,6 +648,8 @@ tree_profiling (void)
pop_cfun ();
}
+ handle_missing_profiles ();
+
del_node_map ();
return 0;
}
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index cafc70cb54b..115683de833 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -260,6 +260,9 @@ along with GCC; see the file COPYING3. If not see
#include "hash-table.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 4f4d0a00648..bb83b42fd46 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -79,6 +79,10 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
#include "bitmap.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index a6b32b8b8d6..61579bc5ef5 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -29,6 +29,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "tree-ssanames.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-dfa.h"
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index a0c4ce3cb57..379d6d67dca 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -452,8 +452,18 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
{
fprintf (file, ", points-to vars: ");
dump_decl_set (file, pt->vars);
- if (pt->vars_contains_global)
- fprintf (file, " (includes global vars)");
+ if (pt->vars_contains_nonlocal
+ && pt->vars_contains_escaped_heap)
+ fprintf (file, " (nonlocal, escaped heap)");
+ else if (pt->vars_contains_nonlocal
+ && pt->vars_contains_escaped)
+ fprintf (file, " (nonlocal, escaped)");
+ else if (pt->vars_contains_nonlocal)
+ fprintf (file, " (nonlocal)");
+ else if (pt->vars_contains_escaped_heap)
+ fprintf (file, " (escaped heap)");
+ else if (pt->vars_contains_escaped)
+ fprintf (file, " (escaped)");
}
}
@@ -2010,9 +2020,10 @@ static bool
stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
{
/* For a must-alias check we need to be able to constrain
- the access properly. */
- ao_ref_base (ref);
- if (ref->max_size == -1)
+ the access properly.
+ FIXME: except for BUILTIN_FREE. */
+ if (!ao_ref_base (ref)
+ || ref->max_size == -1)
return false;
if (gimple_has_lhs (stmt)
@@ -2099,23 +2110,32 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
{
tree dest = gimple_call_arg (stmt, 0);
tree len = gimple_call_arg (stmt, 2);
- tree base = NULL_TREE;
- HOST_WIDE_INT offset = 0;
if (!tree_fits_shwi_p (len))
return false;
- if (TREE_CODE (dest) == ADDR_EXPR)
- base = get_addr_base_and_unit_offset (TREE_OPERAND (dest, 0),
- &offset);
- else if (TREE_CODE (dest) == SSA_NAME)
- base = dest;
- if (base
- && base == ao_ref_base (ref))
+ tree rbase = ref->base;
+ offset_int roffset = wi::to_offset (ref->offset);
+ ao_ref dref;
+ ao_ref_init_from_ptr_and_size (&dref, dest, len);
+ tree base = ao_ref_base (&dref);
+ offset_int offset = wi::to_offset (dref.offset);
+ offset_int bpu = wi::to_offset (BITS_PER_UNIT);
+ if (!base || dref.size == -1)
+ return false;
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ if (TREE_CODE (rbase) != MEM_REF)
+ return false;
+ // Compare pointers.
+ offset += bpu * mem_ref_offset (base);
+ roffset += bpu * mem_ref_offset (rbase);
+ base = TREE_OPERAND (base, 0);
+ rbase = TREE_OPERAND (rbase, 0);
+ }
+ if (base == rbase)
{
- HOST_WIDE_INT size = tree_to_hwi (len);
- if (offset <= ref->offset / BITS_PER_UNIT
- && (offset + size
- >= ((ref->offset + ref->max_size + BITS_PER_UNIT - 1)
- / BITS_PER_UNIT)))
+ wide_int size = bpu * tree_to_hwi (len);
+ if (wi::le_p (offset, roffset, SIGNED)
+ && wi::le_p (roffset + ref->max_size, offset + size, SIGNED))
return true;
}
break;
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 581cd82a5f3..44485bdd041 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -48,9 +48,13 @@ struct GTY(()) pt_solution
unsigned int null : 1;
- /* Nonzero if the pt_vars bitmap includes a global variable. */
- unsigned int vars_contains_global : 1;
-
+ /* Nonzero if the vars bitmap includes a variable included in 'nonlocal'. */
+ unsigned int vars_contains_nonlocal : 1;
+ /* Nonzero if the vars bitmap includes a variable included in 'escaped'. */
+ unsigned int vars_contains_escaped : 1;
+ /* Nonzero if the vars bitmap includes a anonymous heap variable that
+ escaped the function and thus became global. */
+ unsigned int vars_contains_escaped_heap : 1;
/* Set of variables that this pointer may point to. */
bitmap vars;
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 247e83a5dca..3648c2830fb 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -129,6 +129,8 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index c445c78626e..942602e5fe3 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "dumpfile.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
@@ -1256,8 +1257,8 @@ coalesce_ssa_name (void)
cl = create_coalesce_list ();
map = create_outofssa_var_map (cl, used_in_copies);
- /* We need to coalesce all names originating same SSA_NAME_VAR
- so debug info remains undisturbed. */
+ /* If optimization is disabled, we need to coalesce all the names originating
+ from the same SSA_NAME_VAR so debug info remains undisturbed. */
if (!optimize)
{
hash_table <ssa_name_var_hash> ssa_name_hash;
@@ -1278,8 +1279,16 @@ coalesce_ssa_name (void)
*slot = a;
else
{
- add_coalesce (cl, SSA_NAME_VERSION (a), SSA_NAME_VERSION (*slot),
- MUST_COALESCE_COST - 1);
+ /* If the variable is a PARM_DECL or a RESULT_DECL, we
+ _require_ that all the names originating from it be
+ coalesced, because there must be a single partition
+ containing all the names so that it can be assigned
+ the canonical RTL location of the DECL safely. */
+ const int cost
+ = TREE_CODE (SSA_NAME_VAR (a)) == VAR_DECL
+ ? MUST_COALESCE_COST - 1 : MUST_COALESCE_COST;
+ add_coalesce (cl, SSA_NAME_VERSION (a),
+ SSA_NAME_VERSION (*slot), cost);
bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (a));
bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (*slot));
}
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 15c6896e945..0f70372c80e 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index 30b339def7d..d71802e7a1c 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "flags.h"
#include "basic-block.h"
#include "function.h"
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 72e2fb8fa65..d138f92f195 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 6a6f027e90c..0ce24df2abe 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 202eb3e673b..42e2380a0c8 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 48b096cb277..40fee3376fd 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index 73ebfe8b24e..d3bb5b246cd 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 17849a21159..1657f6f6ca5 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "sbitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index b74c56de330..57c1555d28c 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 4a125968767..3b76447fb12 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 99abd9e480a..18e76435923 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 1ca3d0bb876..6b3aca381f5 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -70,6 +70,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -3608,30 +3611,13 @@ force_expr_to_var_cost (tree expr, bool speed)
op1 = TREE_OPERAND (expr, 1);
STRIP_NOPS (op0);
STRIP_NOPS (op1);
-
- if (is_gimple_val (op0))
- cost0 = no_cost;
- else
- cost0 = force_expr_to_var_cost (op0, speed);
-
- if (is_gimple_val (op1))
- cost1 = no_cost;
- else
- cost1 = force_expr_to_var_cost (op1, speed);
-
break;
+ CASE_CONVERT:
case NEGATE_EXPR:
op0 = TREE_OPERAND (expr, 0);
STRIP_NOPS (op0);
op1 = NULL_TREE;
-
- if (is_gimple_val (op0))
- cost0 = no_cost;
- else
- cost0 = force_expr_to_var_cost (op0, speed);
-
- cost1 = no_cost;
break;
default:
@@ -3639,6 +3625,18 @@ force_expr_to_var_cost (tree expr, bool speed)
return new_cost (target_spill_cost[speed], 0);
}
+ if (op0 == NULL_TREE
+ || TREE_CODE (op0) == SSA_NAME || CONSTANT_CLASS_P (op0))
+ cost0 = no_cost;
+ else
+ cost0 = force_expr_to_var_cost (op0, speed);
+
+ if (op1 == NULL_TREE
+ || TREE_CODE (op1) == SSA_NAME || CONSTANT_CLASS_P (op1))
+ cost1 = no_cost;
+ else
+ cost1 = force_expr_to_var_cost (op1, speed);
+
mode = TYPE_MODE (TREE_TYPE (expr));
switch (TREE_CODE (expr))
{
@@ -3664,6 +3662,16 @@ force_expr_to_var_cost (tree expr, bool speed)
}
break;
+ CASE_CONVERT:
+ {
+ tree inner_mode, outer_mode;
+ outer_mode = TREE_TYPE (expr);
+ inner_mode = TREE_TYPE (op0);
+ cost = new_cost (convert_cost (TYPE_MODE (outer_mode),
+ TYPE_MODE (inner_mode), speed), 0);
+ }
+ break;
+
case MULT_EXPR:
if (cst_fits_shwi_p (op0))
cost = new_cost (mult_by_coeff_cost (int_cst_value (op0),
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index 2bb225360dd..ae51ee66f07 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index ef3367c51c6..c4f4aef0bc4 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "intl.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index 6a84bdc0496..f5318887103 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-manip.h"
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index e2b1c0735ad..236b89b8a12 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimplify.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 9bb002868be..20454f2edf4 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index b338f63eb5f..77900876930 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -91,6 +91,8 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 5e8a7ce57a5..0384c3dbb2a 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -28,6 +28,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index e0e682e5dc2..070b8ed3f0b 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index f6a40a2b133..64e6866e7f6 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -28,6 +28,9 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "tree-inline.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 3456edbf5a0..078b04afdbc 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -31,6 +31,8 @@
#include "dumpfile.h"
#include "sbitmap.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index df34bc29ffc..d23eebd3cd6 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "tree-inline.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 5d7bcfc9ab6..6fbb493fe76 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "tree-inline.h"
#include "gimple.h"
+#include "gimplify.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index a8b149287c9..caf10bb522f 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "tree-inline.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 4d3acf303da..bf2a5fb61d5 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3. If not see
#include "hash-table.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 78d1a7c2e53..bbb77767d07 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -30,6 +30,7 @@
#include "basic-block.h"
#include "tree.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-ssanames.h"
@@ -2062,7 +2063,24 @@ condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
si->scc_stack.safe_push (n);
}
-/* Label pointer equivalences. */
+/* Label pointer equivalences.
+
+ This performs a value numbering of the constraint graph to
+ discover which variables will always have the same points-to sets
+ under the current set of constraints.
+
+ The way it value numbers is to store the set of points-to bits
+ generated by the constraints and graph edges. This is just used as a
+ hash and equality comparison. The *actual set of points-to bits* is
+ completely irrelevant, in that we don't care about being able to
+ extract them later.
+
+ The equality values (currently bitmaps) just have to satisfy a few
+ constraints, the main ones being:
+ 1. The combining operation must be order independent.
+ 2. The end result of a given set of operations must be unique iff the
+ combination of input values is unique
+ 3. Hashable. */
static void
label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
@@ -3977,8 +3995,8 @@ handle_lhs_call (gimple stmt, tree lhs, int flags, vec<ce_s> rhsc,
struct constraint_expr tmpc;
rhsc.create (0);
vi = make_heapvar ("HEAP");
- /* We delay marking allocated storage global until we know if
- it escapes. */
+ /* We marking allocated storage local, we deal with it becoming
+ global by escaping and setting of vars_contains_escaped_heap. */
DECL_EXTERNAL (vi->decl) = 0;
vi->is_global_var = 0;
/* If this is not a real malloc call assume the memory was
@@ -5981,6 +5999,9 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
{
unsigned int i;
bitmap_iterator bi;
+ varinfo_t escaped_vi = get_varinfo (find (escaped_id));
+ bool everything_escaped
+ = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id);
EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
{
@@ -5991,6 +6012,14 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
if (vi->is_artificial_var && !vi->is_heap_var)
continue;
+ if (everything_escaped
+ || (escaped_vi->solution
+ && bitmap_bit_p (escaped_vi->solution, i)))
+ {
+ pt->vars_contains_escaped = true;
+ pt->vars_contains_escaped_heap = vi->is_heap_var;
+ }
+
if (TREE_CODE (vi->decl) == VAR_DECL
|| TREE_CODE (vi->decl) == PARM_DECL
|| TREE_CODE (vi->decl) == RESULT_DECL)
@@ -6005,7 +6034,7 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
set contains global variables. */
bitmap_set_bit (into, DECL_PT_UID (vi->decl));
if (vi->is_global_var)
- pt->vars_contains_global = true;
+ pt->vars_contains_nonlocal = true;
}
}
}
@@ -6162,11 +6191,15 @@ pt_solution_reset (struct pt_solution *pt)
it contains restrict tag variables. */
void
-pt_solution_set (struct pt_solution *pt, bitmap vars, bool vars_contains_global)
+pt_solution_set (struct pt_solution *pt, bitmap vars,
+ bool vars_contains_nonlocal)
{
memset (pt, 0, sizeof (struct pt_solution));
pt->vars = vars;
- pt->vars_contains_global = vars_contains_global;
+ pt->vars_contains_nonlocal = vars_contains_nonlocal;
+ pt->vars_contains_escaped
+ = (cfun->gimple_df->escaped.anything
+ || bitmap_intersect_p (cfun->gimple_df->escaped.vars, vars));
}
/* Set the points-to solution *PT to point only to the variable VAR. */
@@ -6177,7 +6210,10 @@ pt_solution_set_var (struct pt_solution *pt, tree var)
memset (pt, 0, sizeof (struct pt_solution));
pt->vars = BITMAP_GGC_ALLOC ();
bitmap_set_bit (pt->vars, DECL_PT_UID (var));
- pt->vars_contains_global = is_global_var (var);
+ pt->vars_contains_nonlocal = is_global_var (var);
+ pt->vars_contains_escaped
+ = (cfun->gimple_df->escaped.anything
+ || bitmap_bit_p (cfun->gimple_df->escaped.vars, DECL_PT_UID (var)));
}
/* Computes the union of the points-to solutions *DEST and *SRC and
@@ -6200,7 +6236,9 @@ pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src)
dest->escaped |= src->escaped;
dest->ipa_escaped |= src->ipa_escaped;
dest->null |= src->null;
- dest->vars_contains_global |= src->vars_contains_global;
+ dest->vars_contains_nonlocal |= src->vars_contains_nonlocal;
+ dest->vars_contains_escaped |= src->vars_contains_escaped;
+ dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap;
if (!src->vars)
return;
@@ -6257,9 +6295,14 @@ pt_solution_includes_global (struct pt_solution *pt)
{
if (pt->anything
|| pt->nonlocal
- || pt->vars_contains_global)
+ || pt->vars_contains_nonlocal
+ /* The following is a hack to make the malloc escape hack work.
+ In reality we'd need different sets for escaped-through-return
+ and escaped-to-callees and passes would need to be updated. */
+ || pt->vars_contains_escaped_heap)
return true;
+ /* 'escaped' is also a placeholder so we have to look into it. */
if (pt->escaped)
return pt_solution_includes_global (&cfun->gimple_df->escaped);
@@ -6329,28 +6372,19 @@ pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2)
any global memory they alias. */
if ((pt1->nonlocal
&& (pt2->nonlocal
- || pt2->vars_contains_global))
+ || pt2->vars_contains_nonlocal))
|| (pt2->nonlocal
- && pt1->vars_contains_global))
+ && pt1->vars_contains_nonlocal))
return true;
- /* Check the escaped solution if required. */
- if ((pt1->escaped || pt2->escaped)
- && !pt_solution_empty_p (&cfun->gimple_df->escaped))
- {
- /* If both point to escaped memory and that solution
- is not empty they alias. */
- if (pt1->escaped && pt2->escaped)
- return true;
-
- /* If either points to escaped memory see if the escaped solution
- intersects with the other. */
- if ((pt1->escaped
- && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt2))
- || (pt2->escaped
- && pt_solutions_intersect_1 (&cfun->gimple_df->escaped, pt1)))
- return true;
- }
+ /* If either points to all escaped memory and the other points to
+ any escaped memory they alias. */
+ if ((pt1->escaped
+ && (pt2->escaped
+ || pt2->vars_contains_escaped))
+ || (pt2->escaped
+ && pt1->vars_contains_escaped))
+ return true;
/* Check the escaped solution if required.
??? Do we need to check the local against the IPA escaped sets? */
@@ -6798,14 +6832,6 @@ compute_points_to_sets (void)
points-to solution queries. */
cfun->gimple_df->escaped.escaped = 0;
- /* Mark escaped HEAP variables as global. */
- FOR_EACH_VEC_ELT (varmap, i, vi)
- if (vi
- && vi->is_heap_var
- && !vi->is_global_var)
- DECL_EXTERNAL (vi->decl) = vi->is_global_var
- = pt_solution_includes (&cfun->gimple_df->escaped, vi->decl);
-
/* Compute the points-to sets for pointer SSA_NAMEs. */
for (i = 0; i < num_ssa_names; ++i)
{
@@ -7052,7 +7078,7 @@ gate_ipa_pta (void)
/* IPA PTA solutions for ESCAPED. */
struct pt_solution ipa_escaped_pt
- = { true, false, false, false, false, false, NULL };
+ = { true, false, false, false, false, false, false, false, NULL };
/* Associate node with varinfo DATA. Worker for
cgraph_for_node_and_aliases. */
@@ -7410,7 +7436,7 @@ const pass_data pass_data_ipa_pta =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_update_ssa, /* todo_flags_finish */
+ 0, /* todo_flags_finish */
};
class pass_ipa_pta : public simple_ipa_opt_pass
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index db95ce1059c..c97da97f6d3 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -195,6 +195,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "function.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -1075,6 +1076,24 @@ set_cluster (basic_block bb1, basic_block bb2)
gcc_unreachable ();
}
+/* Return true if gimple operands T1 and T2 have the same value. */
+
+static bool
+gimple_operand_equal_value_p (tree t1, tree t2)
+{
+ if (t1 == t2)
+ return true;
+
+ if (t1 == NULL_TREE
+ || t2 == NULL_TREE)
+ return false;
+
+ if (operand_equal_p (t1, t2, 0))
+ return true;
+
+ return gvn_uses_equal (t1, t2);
+}
+
/* Return true if gimple statements S1 and S2 are equal. Gimple_bb (s1) and
gimple_bb (s2) are members of SAME_SUCC. */
@@ -1085,7 +1104,7 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
tree lhs1, lhs2;
basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
tree t1, t2;
- bool equal, inv_cond;
+ bool inv_cond;
enum tree_code code1, code2;
if (gimple_code (s1) != gimple_code (s2))
@@ -1099,28 +1118,14 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
if (!gimple_call_same_target_p (s1, s2))
return false;
- /* Eventually, we'll significantly complicate the CFG by adding
- back edges to properly model the effects of transaction restart.
- For the bulk of optimization this does not matter, but what we
- cannot recover from is tail merging blocks between two separate
- transactions. Avoid that by making commit not match. */
- if (gimple_call_builtin_p (s1, BUILT_IN_TM_COMMIT))
- return false;
-
- equal = true;
for (i = 0; i < gimple_call_num_args (s1); ++i)
{
t1 = gimple_call_arg (s1, i);
t2 = gimple_call_arg (s2, i);
- if (operand_equal_p (t1, t2, 0))
+ if (gimple_operand_equal_value_p (t1, t2))
continue;
- if (gvn_uses_equal (t1, t2))
- continue;
- equal = false;
- break;
+ return false;
}
- if (!equal)
- return false;
lhs1 = gimple_get_lhs (s1);
lhs2 = gimple_get_lhs (s2);
@@ -1137,8 +1142,17 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
lhs2 = gimple_get_lhs (s2);
if (TREE_CODE (lhs1) != SSA_NAME
&& TREE_CODE (lhs2) != SSA_NAME)
- return (vn_valueize (gimple_vdef (s1))
- == vn_valueize (gimple_vdef (s2)));
+ {
+ /* If the vdef is the same, it's the same statement. */
+ if (vn_valueize (gimple_vdef (s1))
+ == vn_valueize (gimple_vdef (s2)))
+ return true;
+
+ /* Test for structural equality. */
+ return (operand_equal_p (lhs1, lhs2, 0)
+ && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
+ gimple_assign_rhs1 (s2)));
+ }
else if (TREE_CODE (lhs1) == SSA_NAME
&& TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
@@ -1147,14 +1161,12 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
case GIMPLE_COND:
t1 = gimple_cond_lhs (s1);
t2 = gimple_cond_lhs (s2);
- if (!operand_equal_p (t1, t2, 0)
- && !gvn_uses_equal (t1, t2))
+ if (!gimple_operand_equal_value_p (t1, t2))
return false;
t1 = gimple_cond_rhs (s1);
t2 = gimple_cond_rhs (s2);
- if (!operand_equal_p (t1, t2, 0)
- && !gvn_uses_equal (t1, t2))
+ if (!gimple_operand_equal_value_p (t1, t2))
return false;
code1 = gimple_expr_code (s1);
@@ -1224,15 +1236,14 @@ find_duplicate (same_succ same_succ, basic_block bb1, basic_block bb2)
gimple stmt1 = gsi_stmt (gsi1);
gimple stmt2 = gsi_stmt (gsi2);
- if (!gimple_equal_p (same_succ, stmt1, stmt2))
+ /* What could be better than to this this here is to blacklist the bb
+ containing the stmt, when encountering the stmt f.i. in
+ same_succ_hash. */
+ if (is_tm_ending (stmt1)
+ || is_tm_ending (stmt2))
return;
- // We cannot tail-merge the builtins that end transactions.
- // ??? The alternative being unsharing of BBs in the tm_init pass.
- if (flag_tm
- && is_gimple_call (stmt1)
- && (gimple_call_flags (stmt1) & ECF_TM_BUILTIN)
- && is_tm_ending_fndecl (gimple_call_fndecl (stmt1)))
+ if (!gimple_equal_p (same_succ, stmt1, stmt2))
return;
gsi_prev_nondebug (&gsi1);
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 6090c5ff5f5..df0c458e019 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index cd2b34ae6ff..cabfc824c62 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "dumpfile.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -760,7 +761,8 @@ thread_around_empty_blocks (edge taken_edge,
bool handle_dominating_asserts,
tree (*simplify) (gimple, gimple),
bitmap visited,
- vec<jump_thread_edge *> *path)
+ vec<jump_thread_edge *> *path,
+ bool *backedge_seen_p)
{
basic_block bb = taken_edge->dest;
gimple_stmt_iterator gsi;
@@ -795,19 +797,20 @@ thread_around_empty_blocks (edge taken_edge,
if (single_succ_p (bb))
{
taken_edge = single_succ_edge (bb);
- if ((taken_edge->flags & EDGE_DFS_BACK) == 0
- && !bitmap_bit_p (visited, taken_edge->dest->index))
+ if (!bitmap_bit_p (visited, taken_edge->dest->index))
{
jump_thread_edge *x
= new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
path->safe_push (x);
bitmap_set_bit (visited, taken_edge->dest->index);
+ *backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
return thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
simplify,
visited,
- path);
+ path,
+ backedge_seen_p);
}
}
@@ -841,13 +844,15 @@ thread_around_empty_blocks (edge taken_edge,
jump_thread_edge *x
= new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
path->safe_push (x);
+ *backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
simplify,
visited,
- path);
+ path,
+ backedge_seen_p);
return true;
}
@@ -889,17 +894,16 @@ thread_through_normal_block (edge e,
vec<tree> *stack,
tree (*simplify) (gimple, gimple),
vec<jump_thread_edge *> *path,
- bitmap visited)
+ bitmap visited,
+ bool *backedge_seen_p)
{
- /* If E is a backedge, then we want to verify that the COND_EXPR,
+ /* If we have crossed a backedge, then we want to verify that the COND_EXPR,
SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected
by any statements in e->dest. If it is affected, then it is not
safe to thread this edge. */
- if (e->flags & EDGE_DFS_BACK)
- {
- if (cond_arg_set_in_bb (e, e->dest))
- return false;
- }
+ if (*backedge_seen_p
+ && cond_arg_set_in_bb (e, e->dest))
+ return false;
/* PHIs create temporary equivalences. */
if (!record_temporary_equivalences_from_phis (e, stack))
@@ -931,21 +935,31 @@ thread_through_normal_block (edge e,
/* DEST could be NULL for a computed jump to an absolute
address. */
- if (dest == NULL || dest == e->dest || bitmap_bit_p (visited, dest->index))
+ if (dest == NULL
+ || dest == e->dest
+ || bitmap_bit_p (visited, dest->index))
return false;
- jump_thread_edge *x
- = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
- path->safe_push (x);
+ /* Only push the EDGE_START_JUMP_THREAD marker if this is
+ first edge on the path. */
+ if (path->length () == 0)
+ {
+ jump_thread_edge *x
+ = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
+ path->safe_push (x);
+ *backedge_seen_p |= ((e->flags & EDGE_DFS_BACK) != 0);
+ }
- x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK);
+ jump_thread_edge *x
+ = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK);
path->safe_push (x);
+ *backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
/* See if we can thread through DEST as well, this helps capture
secondary effects of threading without having to re-run DOM or
VRP. */
- if ((e->flags & EDGE_DFS_BACK) == 0
- || ! cond_arg_set_in_bb (taken_edge, e->dest))
+ if (!*backedge_seen_p
+ || ! cond_arg_set_in_bb (taken_edge, e->dest))
{
/* We don't want to thread back to a block we have already
visited. This may be overly conservative. */
@@ -956,7 +970,8 @@ thread_through_normal_block (edge e,
handle_dominating_asserts,
simplify,
visited,
- path);
+ path,
+ backedge_seen_p);
}
return true;
}
@@ -999,6 +1014,7 @@ thread_across_edge (gimple dummy_cond,
tree (*simplify) (gimple, gimple))
{
bitmap visited = BITMAP_ALLOC (NULL);
+ bool backedge_seen;
stmt_count = 0;
@@ -1006,8 +1022,10 @@ thread_across_edge (gimple dummy_cond,
bitmap_clear (visited);
bitmap_set_bit (visited, e->src->index);
bitmap_set_bit (visited, e->dest->index);
+ backedge_seen = ((e->flags & EDGE_DFS_BACK) != 0);
if (thread_through_normal_block (e, dummy_cond, handle_dominating_asserts,
- stack, simplify, path, visited))
+ stack, simplify, path, visited,
+ &backedge_seen))
{
propagate_threaded_block_debug_into (path->last ()->e->dest,
e->dest);
@@ -1067,14 +1085,17 @@ thread_across_edge (gimple dummy_cond,
x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_JOINER_BLOCK);
path->safe_push (x);
found = false;
- if ((e->flags & EDGE_DFS_BACK) == 0
+ backedge_seen = ((e->flags & EDGE_DFS_BACK) != 0);
+ backedge_seen |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
+ if (!backedge_seen
|| ! cond_arg_set_in_bb (path->last ()->e, e->dest))
found = thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
simplify,
visited,
- path);
+ path,
+ &backedge_seen);
/* If we were able to thread through a successor of E->dest, then
record the jump threading opportunity. */
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 24e7767c3b7..e819d65e030 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "function.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "tree-ssa.h"
@@ -1269,46 +1270,6 @@ mark_threaded_blocks (bitmap threaded_blocks)
bitmap_set_bit (tmp, e->dest->index);
}
- /* If we have a joiner block (J) which has two successors S1 and S2 and
- we are threading though S1 and the final destination of the thread
- is S2, then we must verify that any PHI nodes in S2 have the same
- PHI arguments for the edge J->S2 and J->S1->...->S2.
-
- We used to detect this prior to registering the jump thread, but
- that prohibits propagation of edge equivalences into non-dominated
- PHI nodes as the equivalency test might occur before propagation.
-
- This works for now, but will need improvement as part of the FSA
- optimization.
-
- Note since we've moved the thread request data to the edges,
- we have to iterate on those rather than the threaded_edges vector. */
- EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
- {
- bb = BASIC_BLOCK (i);
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- if (e->aux)
- {
- vec<jump_thread_edge *> *path = THREAD_PATH (e);
- bool have_joiner = ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK);
-
- if (have_joiner)
- {
- basic_block joiner = e->dest;
- edge final_edge = path->last ()->e;
- basic_block final_dest = final_edge->dest;
- edge e2 = find_edge (joiner, final_dest);
-
- if (e2 && !phi_args_equal_on_edges (e2, final_edge))
- {
- delete_jump_thread_path (path);
- e->aux = NULL;
- }
- }
- }
- }
- }
/* If optimizing for size, only thread through block if we don't have
@@ -1398,6 +1359,50 @@ mark_threaded_blocks (bitmap threaded_blocks)
}
}
+ /* If we have a joiner block (J) which has two successors S1 and S2 and
+ we are threading though S1 and the final destination of the thread
+ is S2, then we must verify that any PHI nodes in S2 have the same
+ PHI arguments for the edge J->S2 and J->S1->...->S2.
+
+ We used to detect this prior to registering the jump thread, but
+ that prohibits propagation of edge equivalences into non-dominated
+ PHI nodes as the equivalency test might occur before propagation.
+
+ This must also occur after we truncate any jump threading paths
+ as this scenario may only show up after truncation.
+
+ This works for now, but will need improvement as part of the FSA
+ optimization.
+
+ Note since we've moved the thread request data to the edges,
+ we have to iterate on those rather than the threaded_edges vector. */
+ EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
+ {
+ bb = BASIC_BLOCK (i);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (e->aux)
+ {
+ vec<jump_thread_edge *> *path = THREAD_PATH (e);
+ bool have_joiner = ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK);
+
+ if (have_joiner)
+ {
+ basic_block joiner = e->dest;
+ edge final_edge = path->last ()->e;
+ basic_block final_dest = final_edge->dest;
+ edge e2 = find_edge (joiner, final_dest);
+
+ if (e2 && !phi_args_equal_on_edges (e2, final_edge))
+ {
+ delete_jump_thread_path (path);
+ e->aux = NULL;
+ }
+ }
+ }
+ }
+ }
+
BITMAP_FREE (tmp);
}
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 5255d7fb738..25f9f45b285 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "function.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 108da393234..ed5bdb4ac50 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "pointer-set.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 585df718221..da5bbe1bd9a 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -32,6 +32,9 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "pointer-set.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 622d8efe13d..5cd845c0d52 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -29,6 +29,8 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9486132a0b9..bb61f4f7113 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -32,6 +32,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "tree.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 70d167a58e9..185bf165149 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "function.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 2a203eb4e09..ab0aec58bac 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -31,6 +31,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
@@ -2620,7 +2623,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
}
-/* Operator == between two dr_addr_with_seg_len objects.
+/* Operator == between two dr_with_seg_len objects.
This equality operator is used to make sure two data refs
are the same one so that we will consider to combine the
@@ -2628,62 +2631,51 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
refs. */
static bool
-operator == (const dr_addr_with_seg_len& d1,
- const dr_addr_with_seg_len& d2)
+operator == (const dr_with_seg_len& d1,
+ const dr_with_seg_len& d2)
{
- return operand_equal_p (d1.basic_addr, d2.basic_addr, 0)
- && compare_tree (d1.offset, d2.offset) == 0
- && compare_tree (d1.seg_len, d2.seg_len) == 0;
+ return operand_equal_p (DR_BASE_ADDRESS (d1.dr),
+ DR_BASE_ADDRESS (d2.dr), 0)
+ && compare_tree (d1.offset, d2.offset) == 0
+ && compare_tree (d1.seg_len, d2.seg_len) == 0;
}
-/* Function comp_dr_addr_with_seg_len_pair.
+/* Function comp_dr_with_seg_len_pair.
- Comparison function for sorting objects of dr_addr_with_seg_len_pair_t
+ Comparison function for sorting objects of dr_with_seg_len_pair_t
so that we can combine aliasing checks in one scan. */
static int
-comp_dr_addr_with_seg_len_pair (const void *p1_, const void *p2_)
+comp_dr_with_seg_len_pair (const void *p1_, const void *p2_)
{
- const dr_addr_with_seg_len_pair_t* p1 =
- (const dr_addr_with_seg_len_pair_t *) p1_;
- const dr_addr_with_seg_len_pair_t* p2 =
- (const dr_addr_with_seg_len_pair_t *) p2_;
-
- const dr_addr_with_seg_len &p11 = p1->first,
- &p12 = p1->second,
- &p21 = p2->first,
- &p22 = p2->second;
-
- int comp_res = compare_tree (p11.basic_addr, p21.basic_addr);
- if (comp_res != 0)
+ const dr_with_seg_len_pair_t* p1 = (const dr_with_seg_len_pair_t *) p1_;
+ const dr_with_seg_len_pair_t* p2 = (const dr_with_seg_len_pair_t *) p2_;
+
+ const dr_with_seg_len &p11 = p1->first,
+ &p12 = p1->second,
+ &p21 = p2->first,
+ &p22 = p2->second;
+
+ /* For DR pairs (a, b) and (c, d), we only consider to merge the alias checks
+ if a and c have the same basic address snd step, and b and d have the same
+ address and step. Therefore, if any a&c or b&d don't have the same address
+ and step, we don't care the order of those two pairs after sorting. */
+ int comp_res;
+
+ if ((comp_res = compare_tree (DR_BASE_ADDRESS (p11.dr),
+ DR_BASE_ADDRESS (p21.dr))) != 0)
return comp_res;
-
- comp_res = compare_tree (p12.basic_addr, p22.basic_addr);
- if (comp_res != 0)
+ if ((comp_res = compare_tree (DR_BASE_ADDRESS (p12.dr),
+ DR_BASE_ADDRESS (p22.dr))) != 0)
+ return comp_res;
+ if ((comp_res = compare_tree (DR_STEP (p11.dr), DR_STEP (p21.dr))) != 0)
+ return comp_res;
+ if ((comp_res = compare_tree (DR_STEP (p12.dr), DR_STEP (p22.dr))) != 0)
+ return comp_res;
+ if ((comp_res = compare_tree (p11.offset, p21.offset)) != 0)
+ return comp_res;
+ if ((comp_res = compare_tree (p12.offset, p22.offset)) != 0)
return comp_res;
-
- if (TREE_CODE (p11.offset) != INTEGER_CST
- || TREE_CODE (p21.offset) != INTEGER_CST)
- {
- comp_res = compare_tree (p11.offset, p21.offset);
- if (comp_res != 0)
- return comp_res;
- }
- if (tree_int_cst_compare (p11.offset, p21.offset) < 0)
- return -1;
- if (tree_int_cst_compare (p11.offset, p21.offset) > 0)
- return 1;
- if (TREE_CODE (p12.offset) != INTEGER_CST
- || TREE_CODE (p22.offset) != INTEGER_CST)
- {
- comp_res = compare_tree (p12.offset, p22.offset);
- if (comp_res != 0)
- return comp_res;
- }
- if (tree_int_cst_compare (p12.offset, p22.offset) < 0)
- return -1;
- if (tree_int_cst_compare (p12.offset, p22.offset) > 0)
- return 1;
return 0;
}
@@ -2718,11 +2710,11 @@ vect_vfa_segment_size (struct data_reference *dr, tree length_factor)
segment_length = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
else
segment_length = size_binop (MULT_EXPR,
- fold_convert (sizetype, DR_STEP (dr)),
- fold_convert (sizetype, length_factor));
+ fold_convert (sizetype, DR_STEP (dr)),
+ fold_convert (sizetype, length_factor));
if (vect_supportable_dr_alignment (dr, false)
- == dr_explicit_realign_optimized)
+ == dr_explicit_realign_optimized)
{
tree vector_size = TYPE_SIZE_UNIT
(STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr))));
@@ -2744,7 +2736,7 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
{
vec<ddr_p> may_alias_ddrs =
LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
- vec<dr_addr_with_seg_len_pair_t>& comp_alias_ddrs =
+ vec<dr_with_seg_len_pair_t>& comp_alias_ddrs =
LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
@@ -2823,18 +2815,11 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
segment_length_a = vect_vfa_segment_size (dr_a, length_factor);
segment_length_b = vect_vfa_segment_size (dr_b, length_factor);
- dr_addr_with_seg_len_pair_t dr_with_seg_len_pair
- (dr_addr_with_seg_len
- (dr_a, DR_BASE_ADDRESS (dr_a),
- size_binop (PLUS_EXPR, DR_OFFSET (dr_a), DR_INIT (dr_a)),
- segment_length_a),
- dr_addr_with_seg_len
- (dr_b, DR_BASE_ADDRESS (dr_b),
- size_binop (PLUS_EXPR, DR_OFFSET (dr_b), DR_INIT (dr_b)),
- segment_length_b));
-
- if (compare_tree (dr_with_seg_len_pair.first.basic_addr,
- dr_with_seg_len_pair.second.basic_addr) > 0)
+ dr_with_seg_len_pair_t dr_with_seg_len_pair
+ (dr_with_seg_len (dr_a, segment_length_a),
+ dr_with_seg_len (dr_b, segment_length_b));
+
+ if (compare_tree (DR_BASE_ADDRESS (dr_a), DR_BASE_ADDRESS (dr_b)) > 0)
swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second);
comp_alias_ddrs.safe_push (dr_with_seg_len_pair);
@@ -2842,17 +2827,17 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
/* Second, we sort the collected data ref pairs so that we can scan
them once to combine all possible aliasing checks. */
- comp_alias_ddrs.qsort (comp_dr_addr_with_seg_len_pair);
+ comp_alias_ddrs.qsort (comp_dr_with_seg_len_pair);
/* Third, we scan the sorted dr pairs and check if we can combine
alias checks of two neighbouring dr pairs. */
for (size_t i = 1; i < comp_alias_ddrs.length (); ++i)
{
/* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */
- dr_addr_with_seg_len *dr_a1 = &comp_alias_ddrs[i-1].first,
- *dr_b1 = &comp_alias_ddrs[i-1].second,
- *dr_a2 = &comp_alias_ddrs[i].first,
- *dr_b2 = &comp_alias_ddrs[i].second;
+ dr_with_seg_len *dr_a1 = &comp_alias_ddrs[i-1].first,
+ *dr_b1 = &comp_alias_ddrs[i-1].second,
+ *dr_a2 = &comp_alias_ddrs[i].first,
+ *dr_b2 = &comp_alias_ddrs[i].second;
/* Remove duplicate data ref pairs. */
if (*dr_a1 == *dr_a2 && *dr_b1 == *dr_b2)
@@ -2889,7 +2874,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
swap (dr_a2, dr_b2);
}
- if (!operand_equal_p (dr_a1->basic_addr, dr_a2->basic_addr, 0)
+ if (!operand_equal_p (DR_BASE_ADDRESS (dr_a1->dr),
+ DR_BASE_ADDRESS (dr_a2->dr),
+ 0)
|| !tree_fits_shwi_p (dr_a1->offset)
|| !tree_fits_shwi_p (dr_a2->offset))
continue;
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index d58ddffb50b..205b16c6d07 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -24,6 +24,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "langhooks.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-ssanames.h"
@@ -425,7 +427,7 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
tree cst = VECTOR_CST_ELT (op1, i);
unsigned HOST_WIDE_INT ml;
- if (!tree_fits_hwi_p (cst, sign_p) || integer_zerop (cst))
+ if (TREE_CODE (cst) != INTEGER_CST || integer_zerop (cst))
return NULL_TREE;
pre_shifts[i] = 0;
post_shifts[i] = 0;
@@ -446,7 +448,7 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
if (sign_p == UNSIGNED)
{
unsigned HOST_WIDE_INT mh;
- unsigned HOST_WIDE_INT d = tree_to_uhwi (cst) & mask;
+ unsigned HOST_WIDE_INT d = tree_to_hwi (cst) & mask;
if (d >= ((unsigned HOST_WIDE_INT) 1 << (prec - 1)))
/* FIXME: Can transform this into op0 >= op1 ? 1 : 0. */
@@ -516,7 +518,7 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
}
else
{
- HOST_WIDE_INT d = tree_to_shwi (cst);
+ HOST_WIDE_INT d = tree_to_hwi (cst);
unsigned HOST_WIDE_INT abs_d;
if (d == -1)
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 1a3a9adbb7d..c31b6dbddb7 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -29,6 +29,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -2242,7 +2245,7 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
void
vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr)
{
- vec<dr_addr_with_seg_len_pair_t> comp_alias_ddrs =
+ vec<dr_with_seg_len_pair_t> comp_alias_ddrs =
LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
tree part_cond_expr;
@@ -2260,15 +2263,15 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr)
for (size_t i = 0, s = comp_alias_ddrs.length (); i < s; ++i)
{
- const dr_addr_with_seg_len& dr_a = comp_alias_ddrs[i].first;
- const dr_addr_with_seg_len& dr_b = comp_alias_ddrs[i].second;
+ const dr_with_seg_len& dr_a = comp_alias_ddrs[i].first;
+ const dr_with_seg_len& dr_b = comp_alias_ddrs[i].second;
tree segment_length_a = dr_a.seg_len;
tree segment_length_b = dr_b.seg_len;
tree addr_base_a
- = fold_build_pointer_plus (dr_a.basic_addr, dr_a.offset);
+ = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_a.dr), dr_a.offset);
tree addr_base_b
- = fold_build_pointer_plus (dr_b.basic_addr, dr_b.offset);
+ = fold_build_pointer_plus (DR_BASE_ADDRESS (dr_b.dr), dr_b.offset);
if (dump_enabled_p ())
{
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index a5bc9f757cc..934f14fffca 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -29,6 +29,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 5075246a19b..6a559ef390c 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
@@ -2063,9 +2065,8 @@ vect_recog_divmod_pattern (vec<gimple> *stmts,
return pattern_stmt;
}
- if (!tree_fits_hwi_p (oprnd1, TYPE_SIGN (itype))
- || integer_zerop (oprnd1)
- || prec > HOST_BITS_PER_WIDE_INT)
+ if (prec > HOST_BITS_PER_WIDE_INT
+ || integer_zerop (oprnd1))
return NULL;
if (!can_mult_highpart_p (TYPE_MODE (vectype), TYPE_UNSIGNED (itype)))
@@ -2077,7 +2078,7 @@ vect_recog_divmod_pattern (vec<gimple> *stmts,
{
unsigned HOST_WIDE_INT mh, ml;
int pre_shift, post_shift;
- unsigned HOST_WIDE_INT d = tree_to_uhwi (oprnd1)
+ unsigned HOST_WIDE_INT d = tree_to_hwi (oprnd1)
& GET_MODE_MASK (TYPE_MODE (itype));
tree t1, t2, t3, t4;
@@ -2194,7 +2195,7 @@ vect_recog_divmod_pattern (vec<gimple> *stmts,
{
unsigned HOST_WIDE_INT ml;
int post_shift;
- HOST_WIDE_INT d = tree_to_shwi (oprnd1);
+ HOST_WIDE_INT d = tree_to_hwi (oprnd1);
unsigned HOST_WIDE_INT abs_d;
bool add = false;
tree t1, t2, t3, t4;
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 825f73a429a..247bdfd6669 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index ad343b64b7a..292a7491b36 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -30,6 +30,9 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 8e3190fa2c1..9c2cf5d1ce2 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -63,6 +63,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tree-pretty-print.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index fa57b032aae..579ae05eb01 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -176,32 +176,33 @@ typedef struct _slp_oprnd_info
/* This struct is used to store the information of a data reference,
- including the data ref itself, its basic address, the access offset
- and the segment length for aliasing checks. This is used to generate
- alias checks. */
+ including the data ref itself, the access offset (calculated by summing its
+ offset and init) and the segment length for aliasing checks.
+ This is used to merge alias checks. */
-struct dr_addr_with_seg_len
+struct dr_with_seg_len
{
- dr_addr_with_seg_len (data_reference* d, tree addr, tree off, tree len)
- : dr (d), basic_addr (addr), offset (off), seg_len (len) {}
+ dr_with_seg_len (data_reference_p d, tree len)
+ : dr (d),
+ offset (size_binop (PLUS_EXPR, DR_OFFSET (d), DR_INIT (d))),
+ seg_len (len) {}
- data_reference *dr;
- tree basic_addr;
+ data_reference_p dr;
tree offset;
tree seg_len;
};
-/* This struct contains two dr_addr_with_seg_len objects with aliasing data
+/* This struct contains two dr_with_seg_len objects with aliasing data
refs. Two comparisons are generated from them. */
-struct dr_addr_with_seg_len_pair_t
+struct dr_with_seg_len_pair_t
{
- dr_addr_with_seg_len_pair_t (const dr_addr_with_seg_len& d1,
- const dr_addr_with_seg_len& d2)
+ dr_with_seg_len_pair_t (const dr_with_seg_len& d1,
+ const dr_with_seg_len& d2)
: first (d1), second (d2) {}
- dr_addr_with_seg_len first;
- dr_addr_with_seg_len second;
+ dr_with_seg_len first;
+ dr_with_seg_len second;
};
@@ -306,7 +307,7 @@ typedef struct _loop_vec_info {
/* Data Dependence Relations defining address ranges together with segment
lengths from which the run-time aliasing check is built. */
- vec<dr_addr_with_seg_len_pair_t> comp_alias_ddrs;
+ vec<dr_with_seg_len_pair_t> comp_alias_ddrs;
/* Statements in the loop that have data references that are candidates for a
runtime (loop versioning) misalignment check. */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index e66970b5103..634cdec4989 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
diff --git a/gcc/tree.c b/gcc/tree.c
index 3dbe6984fe7..2310c6e1dc0 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-phinodes.h"
@@ -1981,6 +1983,28 @@ make_tree_vec_stat (int len MEM_STAT_DECL)
return t;
}
+
+/* Grow a TREE_VEC node to new length LEN. */
+
+tree
+grow_tree_vec_stat (tree v, int len MEM_STAT_DECL)
+{
+ gcc_assert (TREE_CODE (v) == TREE_VEC);
+
+ int oldlen = TREE_VEC_LENGTH (v);
+ gcc_assert (len > oldlen);
+
+ int oldlength = (oldlen - 1) * sizeof (tree) + sizeof (struct tree_vec);
+ int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
+
+ record_node_allocation_statistics (TREE_VEC, length - oldlength);
+
+ v = (tree) ggc_realloc_stat (v, length PASS_MEM_STAT);
+
+ TREE_VEC_LENGTH (v) = len;
+
+ return v;
+}
/* Return 1 if EXPR is the integer constant zero or a complex constant
of zero. */
diff --git a/gcc/tree.def b/gcc/tree.def
index 47acd7b941d..bad9a6ab78d 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -456,10 +456,12 @@ DEFTREECODE (INDIRECT_REF, "indirect_ref", tcc_reference, 1)
OBJ_TYPE_REF_TOKEN: An integer index to the virtual method table. */
DEFTREECODE (OBJ_TYPE_REF, "obj_type_ref", tcc_expression, 3)
-/* Constructor: return an aggregate value made from specified components.
- In C, this is used only for structure and array initializers.
- The operand is a sequence of component values made out of a VEC of
- struct constructor_elt.
+/* Used to represent the brace-enclosed initializers for a structure or an
+ array. It contains a sequence of component values made out of a VEC of
+ constructor_elt.
+
+ For RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE:
+ The field INDEX of each constructor_elt is a FIELD_DECL.
For ARRAY_TYPE:
The field INDEX of each constructor_elt is the corresponding index.
@@ -468,8 +470,9 @@ DEFTREECODE (OBJ_TYPE_REF, "obj_type_ref", tcc_expression, 3)
has side-effects, they are evaluated once for each element. Wrap the
value in a SAVE_EXPR if you want to evaluate side effects only once.)
- For RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE:
- The field INDEX of each node is a FIELD_DECL. */
+ Components that aren't present are cleared as per the C semantics,
+ unless the CONSTRUCTOR_NO_CLEARING flag is set, in which case their
+ value becomes undefined. */
DEFTREECODE (CONSTRUCTOR, "constructor", tcc_exceptional, 0)
/* The expression types are mostly straightforward, with the fourth argument
@@ -1050,6 +1053,10 @@ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
Operands like for OMP_FOR. */
DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6)
+/* Cilk Plus - #pragma simd [clause1 ... clauseN]
+ Operands like for OMP_FOR. */
+DEFTREECODE (CILK_SIMD, "cilk_simd", tcc_statement, 6)
+
/* OpenMP - #pragma omp distribute [clause1 ... clauseN]
Operands like for OMP_FOR. */
DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6)
diff --git a/gcc/tree.h b/gcc/tree.h
index 8c5eb44fab1..97a774e047e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -959,6 +959,8 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
(&(*CONSTRUCTOR_ELTS (NODE))[IDX])
#define CONSTRUCTOR_NELTS(NODE) \
(vec_safe_length (CONSTRUCTOR_ELTS (NODE)))
+#define CONSTRUCTOR_NO_CLEARING(NODE) \
+ (CONSTRUCTOR_CHECK (NODE)->base.public_flag)
/* Iterate through the vector V of CONSTRUCTOR_ELT elements, yielding the
value of each element (stored within VAL). IX must be a scratch variable
@@ -3626,6 +3628,11 @@ extern tree make_int_cst_stat (int, int MEM_STAT_DECL);
extern tree make_tree_vec_stat (int MEM_STAT_DECL);
#define make_tree_vec(t) make_tree_vec_stat (t MEM_STAT_INFO)
+/* Grow a TREE_VEC. */
+
+extern tree grow_tree_vec_stat (tree v, int MEM_STAT_DECL);
+#define grow_tree_vec(v, t) grow_tree_vec_stat (v, t MEM_STAT_INFO)
+
/* Return the (unique) IDENTIFIER_NODE node for a given name.
The name is supplied as a char *. */
@@ -4461,10 +4468,6 @@ extern void cache_integer_cst (tree);
/* In cgraph.c */
extern void change_decl_assembler_name (tree, tree);
-/* In gimplify.c */
-extern tree unshare_expr (tree);
-extern tree unshare_expr_without_location (tree);
-
/* In stmt.c */
extern void expand_label (tree);
@@ -4941,7 +4944,6 @@ extern void set_decl_incoming_rtl (tree, rtx, bool);
/* In gimple.c. */
extern tree get_base_address (tree t);
-extern void mark_addressable (tree);
/* In tree.c. */
extern tree drop_tree_overflow (tree);
diff --git a/gcc/tsan.c b/gcc/tsan.c
index d273f168cef..8aac468a444 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "function.h"
#include "gimple-ssa.h"
#include "cgraph.h"
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 71766093367..c778c0eadea 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -34,6 +34,8 @@ along with GCC; see the file COPYING3. If not see
#include "regs.h"
#include "ggc.h"
#include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
@@ -196,6 +198,7 @@ gimple_add_histogram_value (struct function *fun, gimple stmt,
{
hist->hvalue.next = gimple_histogram_value (fun, stmt);
set_histogram_value (fun, stmt, hist);
+ hist->fun = fun;
}
@@ -338,6 +341,15 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
}
fprintf (dump_file, ".\n");
break;
+ case HIST_TYPE_TIME_PROFILE:
+ fprintf (dump_file, "Time profile ");
+ if (hist->hvalue.counters)
+ {
+ fprintf (dump_file, "time:"HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) hist->hvalue.counters[0]);
+ }
+ fprintf (dump_file, ".\n");
+ break;
case HIST_TYPE_MAX:
gcc_unreachable ();
}
@@ -411,6 +423,7 @@ stream_in_histogram_value (struct lto_input_block *ib, gimple stmt)
break;
case HIST_TYPE_IOR:
+ case HIST_TYPE_TIME_PROFILE:
ncounters = 1;
break;
case HIST_TYPE_MAX:
@@ -496,7 +509,9 @@ visit_hist (void **slot, void *data)
{
struct pointer_set_t *visited = (struct pointer_set_t *) data;
histogram_value hist = *(histogram_value *) slot;
- if (!pointer_set_contains (visited, hist))
+
+ if (!pointer_set_contains (visited, hist)
+ && hist->type != HIST_TYPE_TIME_PROFILE)
{
error ("dead histogram");
dump_histogram_value (stderr, hist);
@@ -1936,12 +1951,14 @@ gimple_find_values_to_profile (histogram_values *values)
gimple_stmt_iterator gsi;
unsigned i;
histogram_value hist = NULL;
-
values->create (0);
+
FOR_EACH_BB (bb)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
gimple_values_to_profile (gsi_stmt (gsi), values);
+ values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_TIME_PROFILE, 0, 0));
+
FOR_EACH_VEC_ELT (*values, i, hist)
{
switch (hist->type)
@@ -1966,6 +1983,10 @@ gimple_find_values_to_profile (histogram_values *values)
hist->n_counters = 3;
break;
+ case HIST_TYPE_TIME_PROFILE:
+ hist->n_counters = 1;
+ break;
+
case HIST_TYPE_AVERAGE:
hist->n_counters = 2;
break;
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index 57f249d56ef..ef77af4395e 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -34,6 +34,7 @@ enum hist_type
called in indirect call */
HIST_TYPE_AVERAGE, /* Compute average value (sum of all values). */
HIST_TYPE_IOR, /* Used to compute expected alignment. */
+ HIST_TYPE_TIME_PROFILE, /* Used for time profile */
HIST_TYPE_MAX
};
@@ -54,6 +55,7 @@ struct histogram_value_t
} hvalue;
enum hist_type type; /* Type of information to measure. */
unsigned n_counters; /* Number of required counters. */
+ struct function *fun;
union
{
struct
@@ -97,6 +99,8 @@ extern void gimple_gen_pow2_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_one_value_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_ic_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_ic_func_profiler (void);
+extern void gimple_gen_time_profiler (unsigned, unsigned,
+ gimple_stmt_iterator &);
extern void gimple_gen_const_delta_profiler (histogram_value,
unsigned, unsigned);
extern void gimple_gen_average_profiler (histogram_value, unsigned, unsigned);
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index fb26978d273..ecf1dc25e84 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -139,6 +139,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "basic-block.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
diff --git a/libada/ChangeLog b/libada/ChangeLog
index e8a85cf0bcc..cff46fbb93f 100644
--- a/libada/ChangeLog
+++ b/libada/ChangeLog
@@ -1,3 +1,7 @@
+2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ * configure: Regenerate.
+
2013-03-27 Kai Tietz <ktietz@redhat.com>
* configure: Regenerated.
diff --git a/libada/configure b/libada/configure
index 19d3e5e7e77..55d63fa1374 100755
--- a/libada/configure
+++ b/libada/configure
@@ -2867,9 +2867,6 @@ case "${host}" in
i[34567]86-*-* | x86_64-*-*)
PICFLAG=-fpic
;;
- m68k-*-*)
- PICFLAG=-fpic
- ;;
# FIXME: Override -fPIC default in libgcc only?
sh-*-linux* | sh[2346lbe]*-*-linux*)
PICFLAG=-fpic
diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog
index 900a6198e97..06aff7feb35 100644
--- a/libatomic/ChangeLog
+++ b/libatomic/ChangeLog
@@ -1,3 +1,7 @@
+2013-11-10 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/x86/fenv.c: New file.
+
2013-11-07 Joseph Myers <joseph@codesourcery.com>
* fenv.c: New file.
diff --git a/libatomic/config/x86/fenv.c b/libatomic/config/x86/fenv.c
new file mode 100644
index 00000000000..154983e5f45
--- /dev/null
+++ b/libatomic/config/x86/fenv.c
@@ -0,0 +1,116 @@
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+
+ This file is part of the GNU Atomic Library (libatomic).
+
+ Libatomic 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.
+
+ Libatomic is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libatomic_i.h"
+
+#define FE_INVALID 0x01
+#define FE_DENORM 0x02
+#define FE_DIVBYZERO 0x04
+#define FE_OVERFLOW 0x08
+#define FE_UNDERFLOW 0x10
+#define FE_INEXACT 0x20
+
+struct fenv
+{
+ unsigned short int __control_word;
+ unsigned short int __unused1;
+ unsigned short int __status_word;
+ unsigned short int __unused2;
+ unsigned short int __tags;
+ unsigned short int __unused3;
+ unsigned int __eip;
+ unsigned short int __cs_selector;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
+ unsigned int __data_offset;
+ unsigned short int __data_selector;
+ unsigned short int __unused5;
+};
+
+/* Raise the supported floating-point exceptions from EXCEPTS. Other
+ bits in EXCEPTS are ignored. */
+
+void
+__atomic_feraiseexcept (int excepts)
+{
+ if (excepts & FE_INVALID)
+ {
+ float f = 0.0f;
+#ifdef __x86_64__
+ volatile float r __attribute__ ((unused));
+ asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
+ r = f; /* Needed to trigger exception. */
+#else
+ asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
+ /* No need for fwait, exception is triggered by emitted fstp. */
+#endif
+ }
+ if (excepts & FE_DENORM)
+ {
+ struct fenv temp;
+ asm volatile ("fnstenv\t%0" : "=m" (temp));
+ temp.__status_word |= FE_DENORM;
+ asm volatile ("fldenv\t%0" : : "m" (temp));
+ asm volatile ("fwait");
+ }
+ if (excepts & FE_DIVBYZERO)
+ {
+ float f = 1.0f, g = 0.0f;
+#ifdef __x86_64__
+ volatile float r __attribute__ ((unused));
+ asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
+ r = f; /* Needed to trigger exception. */
+#else
+ asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
+ /* No need for fwait, exception is triggered by emitted fstp. */
+#endif
+ }
+ if (excepts & FE_OVERFLOW)
+ {
+ struct fenv temp;
+ asm volatile ("fnstenv\t%0" : "=m" (temp));
+ temp.__status_word |= FE_OVERFLOW;
+ asm volatile ("fldenv\t%0" : : "m" (temp));
+ asm volatile ("fwait");
+ }
+ if (excepts & FE_UNDERFLOW)
+ {
+ struct fenv temp;
+ asm volatile ("fnstenv\t%0" : "=m" (temp));
+ temp.__status_word |= FE_UNDERFLOW;
+ asm volatile ("fldenv\t%0" : : "m" (temp));
+ asm volatile ("fwait");
+ }
+ if (excepts & FE_INEXACT)
+ {
+ float f = 1.0f, g = 3.0f;
+#ifdef __x86_64__
+ volatile float r __attribute__ ((unused));
+ asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
+ r = f; /* Needed to trigger exception. */
+#else
+ asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
+ /* No need for fwait, exception is triggered by emitted fstp. */
+#endif
+ }
+}
diff --git a/libcilkrts/ChangeLog b/libcilkrts/ChangeLog
index 7f94aefb65f..dd447d85465 100644
--- a/libcilkrts/ChangeLog
+++ b/libcilkrts/ChangeLog
@@ -1,3 +1,11 @@
+2013-11-12 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * Makefile.am (libcilkrts_la_LDFLAGS): Added a check for availability
+ of "-ldl" flag.
+ * configure.ac: Likewise.
+ * configure: Regenerate
+ * Makefile.in: Likewise.
+
2013-11-08 Balaji V. Iyer <balaji.v.iyer@intel.com>
PR c/59039
diff --git a/libcilkrts/Makefile.am b/libcilkrts/Makefile.am
index 1a8bafaa1f3..56bc9ebb85d 100644
--- a/libcilkrts/Makefile.am
+++ b/libcilkrts/Makefile.am
@@ -91,7 +91,7 @@ include include/internal/rev.mk
#libcilkrts_la_LDFLAGS = -rpath '$(libdir)'
libcilkrts_la_LDFLAGS = -version-info 5:0:0
-libcilkrts_la_LDFLAGS += -lpthread -ldl
+libcilkrts_la_LDFLAGS += -lpthread @lt_cv_dlopen_libs@
# If we're building on Linux, use the Linux version script
if LINUX_LINKER_SCRIPT
diff --git a/libcilkrts/Makefile.in b/libcilkrts/Makefile.in
index a35eb7b63bc..5066bef3dcc 100644
--- a/libcilkrts/Makefile.in
+++ b/libcilkrts/Makefile.in
@@ -312,6 +312,7 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
+lt_cv_dlopen_libs = @lt_cv_dlopen_libs@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
@@ -395,8 +396,9 @@ CILK_REVISION = 3902
#libcilkrts_la_LDFLAGS = -rpath '$(libdir)'
# Hack for Cygwin
-libcilkrts_la_LDFLAGS = -version-info 5:0:0 -lpthread -ldl \
- $(am__append_1) $(am__append_2) -no-undefined
+libcilkrts_la_LDFLAGS = -version-info 5:0:0 -lpthread \
+ @lt_cv_dlopen_libs@ $(am__append_1) $(am__append_2) \
+ -no-undefined
# C/C++ header files for Cilk.
cilkincludedir = $(includedir)/cilk
diff --git a/libcilkrts/configure b/libcilkrts/configure
index 41deb9fcc46..2461b51f2db 100644
--- a/libcilkrts/configure
+++ b/libcilkrts/configure
@@ -604,6 +604,7 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+lt_cv_dlopen_libs
toolexeclibdir
toolexecdir
CXXCPP
@@ -4982,6 +4983,10 @@ else
fi
+enable_dlopen=yes
+
+
+
case `pwd` in
*\ * | *\ *)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
@@ -7587,8 +7592,6 @@ done
- enable_dlopen=no
-
enable_win32_dll=no
@@ -11057,7 +11060,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11060 "configure"
+#line 11063 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11163,7 +11166,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11166 "configure"
+#line 11169 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -14419,6 +14422,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
# Must be last
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
diff --git a/libcilkrts/configure.ac b/libcilkrts/configure.ac
index 4582d80c452..8af1bf042d2 100644
--- a/libcilkrts/configure.ac
+++ b/libcilkrts/configure.ac
@@ -146,9 +146,12 @@ case "${host}" in
esac
AM_CONDITIONAL(MAC_LINKER_SCRIPT, test "$mac_linker_script" = "yes")
+AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
+AC_SUBST(lt_cv_dlopen_libs)
+
# Must be last
AC_OUTPUT
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 64de79b287c..5e38c4b5dff 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,52 @@
+2013-11-15 Joseph Myers <joseph@codesourcery.com>
+
+ * ucnid.tab: Add C11 and C11NOSTART data.
+ * makeucnid.c (digit): Rename enum value to N99.
+ (C11, N11, all_languages): New enum values.
+ (NUM_CODE_POINTS, MAX_CODE_POINT): New macros.
+ (flags, decomp, combining_value): Use NUM_CODE_POINTS as array
+ size.
+ (decomp): Use unsigned int as element type.
+ (all_decomp): New array.
+ (read_ucnid): Handle C11 and C11NOSTART. Use MAX_CODE_POINT.
+ (read_table): Use MAX_CODE_POINT. Store all decompositions in
+ all_decomp.
+ (read_derived): Use MAX_CODE_POINT.
+ (write_table): Use NUM_CODE_POINTS. Print N99, C11 and N11
+ flags. Print whole array variable declaration rather than just
+ array contents.
+ (char_id_valid, write_context_switch): New functions.
+ (main): Call write_context_switch.
+ * ucnid.h: Regenerate.
+ * include/cpplib.h (struct cpp_options): Add c11_identifiers.
+ * init.c (struct lang_flags): Add c11_identifiers.
+ (cpp_set_lang): Set c11_identifiers option from selected language.
+ * internal.h (struct normalize_state): Document "previous" as
+ previous starter character.
+ (NORMALIZE_STATE_UPDATE_IDNUM): Take character as argument.
+ * charset.c (DIG): Rename enum value to N99.
+ (C11, N11): New enum values.
+ (struct ucnrange): Give name to struct. Use short for flags and
+ unsigned int for end of range. Include ucnid.h for whole variable
+ declaration.
+ (ucn_valid_in_identifier): Allow for characters up to 0x10FFFF.
+ Allow for C11 in determining valid characters and valid start
+ characters. Use check_nfc for non-Hangul context-dependent
+ checks. Only store starter characters in nst->previous.
+ (_cpp_valid_ucn): Pass new argument to
+ NORMALIZE_STATE_UPDATE_IDNUM.
+ * lex.c (lex_identifier): Pass new argument to
+ NORMALIZE_STATE_UPDATE_IDNUM. Call NORMALIZE_STATE_UPDATE_IDNUM
+ after initial non-UCN part of identifier.
+ (lex_number): Pass new argument to NORMALIZE_STATE_UPDATE_IDNUM.
+
+2013-11-15 Joseph Myers <joseph@codesourcery.com>
+
+ * ucnid.tab: Mark C99 digits as [C99DIG].
+ * makeucnid.c (read_ucnid): Handle [C99DIG].
+ (read_table): Don't check for digit characters.
+ * ucnid.h: Regenerate.
+
2013-11-06 Tobias Burnus <burnus@net-b.de>
* macro.c (_cpp_builtin_macro_text): Correct
diff --git a/libcpp/charset.c b/libcpp/charset.c
index ae56c5a7cf7..c48e64aa4b5 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -828,29 +828,32 @@ enum {
/* Valid in a C99 identifier? */
C99 = 1,
/* Valid in a C99 identifier, but not as the first character? */
- DIG = 2,
+ N99 = 2,
/* Valid in a C++ identifier? */
CXX = 4,
+ /* Valid in a C11/C++11 identifier? */
+ C11 = 8,
+ /* Valid in a C11/C++11 identifier, but not as the first character? */
+ N11 = 16,
/* NFC representation is not valid in an identifier? */
- CID = 8,
+ CID = 32,
/* Might be valid NFC form? */
- NFC = 16,
+ NFC = 64,
/* Might be valid NFKC form? */
- NKC = 32,
+ NKC = 128,
/* Certain preceding characters might make it not valid NFC/NKFC form? */
- CTX = 64
+ CTX = 256
};
-static const struct {
+struct ucnrange {
/* Bitmap of flags above. */
- unsigned char flags;
+ unsigned short flags;
/* Combining class of the character. */
unsigned char combine;
/* Last character in the range described by this entry. */
- unsigned short end;
-} ucnranges[] = {
-#include "ucnid.h"
+ unsigned int end;
};
+#include "ucnid.h"
/* Returns 1 if C is valid in an identifier, 2 if C is valid except at
the start of an identifier, and 0 if C is not valid in an
@@ -864,8 +867,9 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c,
struct normalize_state *nst)
{
int mn, mx, md;
+ unsigned short valid_flags, invalid_start_flags;
- if (c > 0xFFFF)
+ if (c > 0x10FFFF)
return 0;
mn = 0;
@@ -881,15 +885,25 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c,
/* When -pedantic, we require the character to have been listed by
the standard for the current language. Otherwise, we accept the
- union of the acceptable sets for C++98 and C99. */
- if (! (ucnranges[mn].flags & (C99 | CXX)))
+ union of the acceptable sets for all supported language versions. */
+ valid_flags = C99 | CXX | C11;
+ if (CPP_PEDANTIC (pfile))
+ {
+ if (CPP_OPTION (pfile, c11_identifiers))
+ valid_flags = C11;
+ else if (CPP_OPTION (pfile, c99))
+ valid_flags = C99;
+ else if (CPP_OPTION (pfile, cplusplus))
+ valid_flags = CXX;
+ }
+ if (! (ucnranges[mn].flags & valid_flags))
return 0;
-
- if (CPP_PEDANTIC (pfile)
- && ((CPP_OPTION (pfile, c99) && !(ucnranges[mn].flags & C99))
- || (CPP_OPTION (pfile, cplusplus)
- && !(ucnranges[mn].flags & CXX))))
- return 0;
+ if (CPP_OPTION (pfile, c11_identifiers))
+ invalid_start_flags = N11;
+ else if (CPP_OPTION (pfile, c99))
+ invalid_start_flags = N99;
+ else
+ invalid_start_flags = 0;
/* Update NST. */
if (ucnranges[mn].combine != 0 && ucnranges[mn].combine < nst->prev_class)
@@ -899,17 +913,6 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c,
bool safe;
cppchar_t p = nst->previous;
- /* Easy cases from Bengali, Oriya, Tamil, Jannada, and Malayalam. */
- if (c == 0x09BE)
- safe = p != 0x09C7; /* Use 09CB instead of 09C7 09BE. */
- else if (c == 0x0B3E)
- safe = p != 0x0B47; /* Use 0B4B instead of 0B47 0B3E. */
- else if (c == 0x0BBE)
- safe = p != 0x0BC6 && p != 0x0BC7; /* Use 0BCA/0BCB instead. */
- else if (c == 0x0CC2)
- safe = p != 0x0CC6; /* Use 0CCA instead of 0CC6 0CC2. */
- else if (c == 0x0D3E)
- safe = p != 0x0D46 && p != 0x0D47; /* Use 0D4A/0D4B instead. */
/* For Hangul, characters in the range AC00-D7A3 are NFC/NFKC,
and are combined algorithmically from a sequence of the form
1100-1112 1161-1175 11A8-11C2
@@ -917,20 +920,19 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c,
really a valid character).
Unfortunately, C99 allows (only) the NFC form, but C++ allows
only the combining characters. */
- else if (c >= 0x1161 && c <= 0x1175)
+ if (c >= 0x1161 && c <= 0x1175)
safe = p < 0x1100 || p > 0x1112;
else if (c >= 0x11A8 && c <= 0x11C2)
safe = (p < 0xAC00 || p > 0xD7A3 || (p - 0xAC00) % 28 != 0);
else
+ safe = check_nfc (pfile, c, p);
+ if (!safe)
{
- /* Uh-oh, someone updated ucnid.h without updating this code. */
- cpp_error (pfile, CPP_DL_ICE, "Character %x might not be NFKC", c);
- safe = true;
+ if ((c >= 0x1161 && c <= 0x1175) || (c >= 0x11A8 && c <= 0x11C2))
+ nst->level = MAX (nst->level, normalized_identifier_C);
+ else
+ nst->level = normalized_none;
}
- if (!safe && c < 0x1161)
- nst->level = normalized_none;
- else if (!safe)
- nst->level = MAX (nst->level, normalized_identifier_C);
}
else if (ucnranges[mn].flags & NKC)
;
@@ -940,11 +942,13 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c,
nst->level = MAX (nst->level, normalized_identifier_C);
else
nst->level = normalized_none;
- nst->previous = c;
+ if (ucnranges[mn].combine == 0)
+ nst->previous = c;
nst->prev_class = ucnranges[mn].combine;
- /* In C99, UCN digits may not begin identifiers. */
- if (CPP_OPTION (pfile, c99) && (ucnranges[mn].flags & DIG))
+ /* In C99, UCN digits may not begin identifiers. In C11 and C++11,
+ UCN combining characters may not begin identifiers. */
+ if (ucnranges[mn].flags & invalid_start_flags)
return 2;
return 1;
@@ -1054,7 +1058,7 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
CPP_OPTION (pfile, warn_dollars) = 0;
cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number");
}
- NORMALIZE_STATE_UPDATE_IDNUM (nst);
+ NORMALIZE_STATE_UPDATE_IDNUM (nst, result);
}
else if (identifier_pos)
{
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 02927d4c6cb..7540e05383f 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -437,6 +437,10 @@ struct cpp_options
literal number suffixes as user-defined literal number suffixes. */
unsigned char ext_numeric_literals;
+ /* Nonzero means extended identifiers allow the characters specified
+ in C11 and C++11. */
+ unsigned char c11_identifiers;
+
/* Nonzero for C++ 2014 Standard binary constants. */
unsigned char binary_constants;
diff --git a/libcpp/init.c b/libcpp/init.c
index 67444301590..aba295cd1be 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -77,6 +77,7 @@ struct lang_flags
char cplusplus;
char extended_numbers;
char extended_identifiers;
+ char c11_identifiers;
char std;
char cplusplus_comments;
char digraphs;
@@ -88,21 +89,21 @@ struct lang_flags
};
static const struct lang_flags lang_defaults[] =
-{ /* c99 c++ xnum xid std // digr ulit rlit udlit bin_cst dig_sep */
- /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
- /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
- /* GNUC11 */ { 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
- /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
- /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
- /* STDC11 */ { 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
- /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
- /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
- /* GNUCXX11 */ { 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0 },
- /* CXX11 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 },
- /* GNUCXX1Y */ { 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
- /* CXX1Y */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
- /* ASM */ { 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }
+{ /* c99 c++ xnum xid c11 std // digr ulit rlit udlit bin_cst dig_sep */
+ /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
+ /* GNUC99 */ { 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
+ /* GNUC11 */ { 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0 },
+ /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+ /* STDC94 */ { 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
+ /* STDC99 */ { 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ /* STDC11 */ { 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ /* GNUCXX */ { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
+ /* CXX98 */ { 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ /* GNUCXX11 */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0 },
+ /* CXX11 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ /* GNUCXX1Y */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
+ /* CXX1Y */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ /* ASM */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }
/* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX11, CXX11,
GNUCXX1Y, and CXX1Y when no longer experimental (when all uses of
identifiers in the compiler have been audited for correct handling
@@ -121,6 +122,7 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
CPP_OPTION (pfile, cplusplus) = l->cplusplus;
CPP_OPTION (pfile, extended_numbers) = l->extended_numbers;
CPP_OPTION (pfile, extended_identifiers) = l->extended_identifiers;
+ CPP_OPTION (pfile, c11_identifiers) = l->c11_identifiers;
CPP_OPTION (pfile, std) = l->std;
CPP_OPTION (pfile, trigraphs) = l->std;
CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 6de44ed3556..532145824c8 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -713,9 +713,10 @@ extern size_t _cpp_replacement_text_len (const cpp_macro *);
struct normalize_state
{
- /* The previous character. */
+ /* The previous starter character. */
cppchar_t previous;
- /* The combining class of the previous character. */
+ /* The combining class of the previous character (whether or not a
+ starter). */
unsigned char prev_class;
/* The lowest normalization level so far. */
enum cpp_normalize_level level;
@@ -723,10 +724,10 @@ struct normalize_state
#define INITIAL_NORMALIZE_STATE { 0, 0, normalized_KC }
#define NORMALIZE_STATE_RESULT(st) ((st)->level)
-/* We saw a character that matches ISIDNUM(), update a
+/* We saw a character C that matches ISIDNUM(), update a
normalize_state appropriately. */
-#define NORMALIZE_STATE_UPDATE_IDNUM(st) \
- ((st)->previous = 0, (st)->prev_class = 0)
+#define NORMALIZE_STATE_UPDATE_IDNUM(st, c) \
+ ((st)->previous = (c), (st)->prev_class = 0)
extern cppchar_t _cpp_valid_ucn (cpp_reader *, const unsigned char **,
const unsigned char *, int,
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 95995edca33..99c2140c357 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1204,11 +1204,14 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
cur = pfile->buffer->cur;
if (! starts_ucn)
- while (ISIDNUM (*cur))
- {
- hash = HT_HASHSTEP (hash, *cur);
- cur++;
- }
+ {
+ while (ISIDNUM (*cur))
+ {
+ hash = HT_HASHSTEP (hash, *cur);
+ cur++;
+ }
+ NORMALIZE_STATE_UPDATE_IDNUM (nst, *(cur - 1));
+ }
pfile->buffer->cur = cur;
if (starts_ucn || forms_identifier_p (pfile, false, nst))
{
@@ -1216,8 +1219,8 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
do {
while (ISIDNUM (*pfile->buffer->cur))
{
+ NORMALIZE_STATE_UPDATE_IDNUM (nst, *pfile->buffer->cur);
pfile->buffer->cur++;
- NORMALIZE_STATE_UPDATE_IDNUM (nst);
}
} while (forms_identifier_p (pfile, false, nst));
result = _cpp_interpret_identifier (pfile, base,
@@ -1277,8 +1280,8 @@ lex_number (cpp_reader *pfile, cpp_string *number,
while (ISIDNUM (*cur) || *cur == '.' || DIGIT_SEP (*cur)
|| VALID_SIGN (*cur, cur[-1]))
{
+ NORMALIZE_STATE_UPDATE_IDNUM (nst, *cur);
cur++;
- NORMALIZE_STATE_UPDATE_IDNUM (nst);
}
pfile->buffer->cur = cur;
diff --git a/libcpp/makeucnid.c b/libcpp/makeucnid.c
index 4e3f76d551d..2697c6b7cac 100644
--- a/libcpp/makeucnid.c
+++ b/libcpp/makeucnid.c
@@ -29,15 +29,22 @@ along with this program; see the file COPYING3. If not see
enum {
C99 = 1,
CXX = 2,
- digit = 4,
- not_NFC = 8,
- not_NFKC = 16,
- maybe_not_NFC = 32
+ N99 = 4,
+ C11 = 8,
+ N11 = 16,
+ all_languages = C99 | CXX | C11,
+ not_NFC = 32,
+ not_NFKC = 64,
+ maybe_not_NFC = 128
};
-static unsigned flags[65536];
-static unsigned short decomp[65536][2];
-static unsigned char combining_value[65536];
+#define NUM_CODE_POINTS 0x110000
+#define MAX_CODE_POINT 0x10ffff
+
+static unsigned flags[NUM_CODE_POINTS];
+static unsigned int all_decomp[NUM_CODE_POINTS][2];
+static unsigned int decomp[NUM_CODE_POINTS][2];
+static unsigned char combining_value[NUM_CODE_POINTS];
/* Die! */
@@ -48,7 +55,7 @@ fail (const char *s)
exit (1);
}
-/* Read ucnid.tab and set the C99 and CXX flags in header[]. */
+/* Read ucnid.tab and set the flags for language versions in header[]. */
static void
read_ucnid (const char *fname)
@@ -66,8 +73,14 @@ read_ucnid (const char *fname)
break;
if (strcmp (line, "[C99]\n") == 0)
fl = C99;
+ else if (strcmp (line, "[C99DIG]\n") == 0)
+ fl = C99|N99;
else if (strcmp (line, "[CXX]\n") == 0)
fl = CXX;
+ else if (strcmp (line, "[C11]\n") == 0)
+ fl = C11;
+ else if (strcmp (line, "[C11NOSTART]\n") == 0)
+ fl = C11|N11;
else if (isxdigit (line[0]))
{
char *l = line;
@@ -92,7 +105,7 @@ read_ucnid (const char *fname)
}
while (isspace (*l))
l++;
- if (end > 0xFFFF)
+ if (end > MAX_CODE_POINT)
fail ("parsing ucnid.tab, end too large");
while (start <= end)
flags[start++] |= fl;
@@ -104,10 +117,12 @@ read_ucnid (const char *fname)
fclose (f);
}
-/* Read UnicodeData.txt and set the 'digit' flag, and
- also fill in the 'decomp' table to be the decompositions of
- characters for which both the character decomposed and all the code
- points in the decomposition are either C99 or CXX. */
+/* Read UnicodeData.txt and fill in the 'decomp' table to be the
+ decompositions of characters for which both the character
+ decomposed and all the code points in the decomposition are valid
+ for some supported language version, and the 'all_decomp' table to
+ be the decompositions of all characters without those
+ constraints. */
static void
read_table (char *fname)
@@ -121,7 +136,7 @@ read_table (char *fname)
char line[256];
unsigned long codepoint, this_decomp[4];
char *l;
- int i;
+ int i, j;
int decomp_useful;
if (!fgets (line, sizeof (line), f))
@@ -129,17 +144,13 @@ read_table (char *fname)
codepoint = strtoul (line, &l, 16);
if (l == line || *l != ';')
fail ("parsing UnicodeData.txt, reading code point");
- if (codepoint > 0xffff || ! (flags[codepoint] & (C99 | CXX)))
- continue;
+ if (codepoint > MAX_CODE_POINT)
+ fail ("parsing UnicodeData.txt, code point too large");
do {
l++;
} while (*l != ';');
- /* Category value; things starting with 'N' are numbers of some
- kind. */
- if (*++l == 'N')
- flags[codepoint] |= digit;
-
+ /* Category value. */
do {
l++;
} while (*l != ';');
@@ -173,7 +184,9 @@ read_table (char *fname)
}
if (i > 2) /* Decomposition too long. */
fail ("parsing UnicodeData.txt, decomposition too long");
- if (decomp_useful)
+ for (j = 0; j < i; j++)
+ all_decomp[codepoint][j] = this_decomp[j];
+ if ((flags[codepoint] & all_languages) && decomp_useful)
while (--i >= 0)
decomp[codepoint][i] = this_decomp[i];
}
@@ -210,8 +223,8 @@ read_derived (const char *fname)
start = strtoul (line, &l, 16);
if (l == line)
fail ("parsing DerivedNormalizationProps.txt, reading start");
- if (start > 0xffff)
- continue;
+ if (start > MAX_CODE_POINT)
+ fail ("parsing DerivedNormalizationProps.txt, code point too large");
if (*l == '.' && l[1] == '.')
end = strtoul (l + 2, &l, 16);
else
@@ -239,17 +252,21 @@ write_table (void)
unsigned last_flag = flags[0];
bool really_safe = decomp[0][0] == 0;
unsigned char last_combine = combining_value[0];
+
+ printf ("static const struct ucnrange ucnranges[] = {\n");
- for (i = 1; i <= 65536; i++)
- if (i == 65536
- || (flags[i] != last_flag && ((flags[i] | last_flag) & (C99 | CXX)))
+ for (i = 1; i <= NUM_CODE_POINTS; i++)
+ if (i == NUM_CODE_POINTS
+ || (flags[i] != last_flag && ((flags[i] | last_flag) & all_languages))
|| really_safe != (decomp[i][0] == 0)
|| combining_value[i] != last_combine)
{
- printf ("{ %s|%s|%s|%s|%s|%s|%s, %3d, %#06x },\n",
+ printf ("{ %s|%s|%s|%s|%s|%s|%s|%s|%s, %3d, %#06x },\n",
last_flag & C99 ? "C99" : " 0",
- last_flag & digit ? "DIG" : " 0",
+ last_flag & N99 ? "N99" : " 0",
last_flag & CXX ? "CXX" : " 0",
+ last_flag & C11 ? "C11" : " 0",
+ last_flag & N11 ? "N11" : " 0",
really_safe ? "CID" : " 0",
last_flag & not_NFC ? " 0" : "NFC",
last_flag & not_NFKC ? " 0" : "NKC",
@@ -260,6 +277,98 @@ write_table (void)
last_combine = combining_value[0];
really_safe = decomp[i][0] == 0;
}
+
+ printf ("};\n");
+}
+
+/* Return whether a given character is valid in an identifier for some
+ supported language, either as itself or as a UCN. */
+
+static bool
+char_id_valid (unsigned int c)
+{
+ return ((flags[c] & all_languages)
+ || (c == 0x24)
+ || (c >= 0x30 && c <= 0x39)
+ || (c >= 0x41 && c <= 0x5a)
+ || (c >= 0x61 && c <= 0x7a));
+}
+
+/* Write out the switch statement over characters for which it is
+ context-dependent whether they are in NFC. */
+
+static void
+write_context_switch (void)
+{
+ unsigned i;
+ printf ("static bool\n"
+ "check_nfc (cpp_reader *pfile, cppchar_t c, cppchar_t p)\n"
+ "{\n"
+ " switch (c)\n"
+ " {\n");
+ for (i = 0; i < NUM_CODE_POINTS; i++)
+ {
+ bool found_case = false;
+ unsigned j;
+ if (!(flags[i] & all_languages) || !(flags[i] & maybe_not_NFC))
+ continue;
+ if ((i >= 0x1161 && i <= 0x1175) || (i >= 0x11A8 && i <= 0x11C2))
+ continue; /* Hangul handled algorithmically. */
+ printf (" case %#06x:\n"
+ " switch (p)\n"
+ "\t{\n", i);
+ /* If an NFC starter character decomposes with this character I
+ as the second character and an NFC starter character S as the
+ first character, that latter character as a previous
+ character means this character is not NFC. Furthermore, any
+ NFC starter character K made by a series of compositions of S
+ with combining characters whose combining class is greater
+ than that of I also means this character is not NFC. */
+ for (j = 0; j < NUM_CODE_POINTS; j++)
+ {
+ unsigned s, k;
+ if (all_decomp[j][1] != i)
+ continue;
+ s = all_decomp[j][0];
+ if (combining_value[s] != 0 || (flags[s] & not_NFC) != 0)
+ continue;
+ if (char_id_valid (s))
+ {
+ found_case = true;
+ printf ("\tcase %#06x:\n", s);
+ }
+ for (k = 0; k < NUM_CODE_POINTS; k++)
+ {
+ unsigned t = k;
+ if (k == s || !char_id_valid (k))
+ continue;
+ while (all_decomp[t][1] != 0
+ && combining_value[all_decomp[t][1]] > combining_value[i])
+ {
+ if (combining_value[t] != 0 || (flags[t] & not_NFC) != 0)
+ break;
+ t = all_decomp[t][0];
+ }
+ if (t == s)
+ {
+ found_case = true;
+ printf ("\tcase %#06x:\n", k);
+ }
+ }
+ }
+ if (found_case)
+ printf ("\t return false;\n");
+ else
+ printf ("\t/* Non-NFC cases not applicable to C/C++. */\n");
+ printf ("\tdefault:\n"
+ "\t return true;\n"
+ "\t}\n\n");
+ }
+ printf (" default:\n"
+ " cpp_error (pfile, CPP_DL_ICE, \"Character %%x might not be NFKC\", c);\n"
+ " return true;\n"
+ " }\n"
+ "}\n");
}
/* Print out the huge copyright notice. */
@@ -338,5 +447,6 @@ main(int argc, char ** argv)
write_copyright ();
write_table ();
+ write_context_switch ();
return 0;
}
diff --git a/libcpp/ucnid.h b/libcpp/ucnid.h
index 8d6434a569a..352e95cb206 100644
--- a/libcpp/ucnid.h
+++ b/libcpp/ucnid.h
@@ -52,750 +52,4473 @@
use or other dealings in these Data Files or Software without prior
written authorization of the copyright holder. */
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00a9 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x00aa },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b4 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x00b5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b6 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x00b7 },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x00b9 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x00ba },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00bf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x00d6 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00d7 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x00f6 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00f7 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0131 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0133 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x013e },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0140 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0148 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0149 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x017e },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x017f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x01c3 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x01cc },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x01f0 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x01f3 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x01f5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x01f9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0217 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x024f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x02a8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02af },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x02b8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02ba },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x02bb },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02bc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x02c1 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02cf },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x02d1 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02df },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x02e4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0379 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x037a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0383 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0x0384 },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x0385 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0386 },
-{ 0| 0| 0|CID| 0| 0| 0, 0, 0x0387 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x038a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x038b },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x038c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x038d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03a1 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03a2 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03ce },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03cf },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x03d6 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03d9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03da },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03db },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03dc },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03dd },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03de },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03df },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03e0 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03e1 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03ef },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x03f2 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03f3 },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x0400 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x040c },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x040d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x040e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x044f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0450 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x045c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x045d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0481 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x048f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04c4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04c6 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04c8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04ca },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04cc },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04cf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04eb },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04ed },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04f5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04f7 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04f9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0530 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0556 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0558 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0559 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0560 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0586 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0587 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05af },
-{ C99| 0| 0|CID|NFC|NKC| 0, 10, 0x05b0 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 11, 0x05b1 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 12, 0x05b2 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 13, 0x05b3 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 14, 0x05b4 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 15, 0x05b5 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 16, 0x05b6 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 17, 0x05b7 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 18, 0x05b8 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 19, 0x05b9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05ba },
-{ C99| 0| 0|CID|NFC|NKC| 0, 20, 0x05bb },
-{ C99| 0| 0|CID|NFC|NKC| 0, 21, 0x05bc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 22, 0x05bd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05be },
-{ C99| 0| 0|CID|NFC|NKC| 0, 23, 0x05bf },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05c0 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 24, 0x05c1 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 25, 0x05c2 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05cf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x05ea },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05ef },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x05f2 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x05f4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0620 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x063a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x063f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x064a },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 27, 0x064b },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 28, 0x064c },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 29, 0x064d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 30, 0x064e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 31, 0x064f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 32, 0x0650 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 33, 0x0651 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 34, 0x0652 },
-{ 0| 0| 0|CID|NFC|NKC|CTX, 0, 0x065f },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0669 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x066f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0674 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0678 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06b7 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06b9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06be },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06bf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06ce },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06cf },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x06d5 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d6 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d7 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d8 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d9 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06da },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06db },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06dc },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06e4 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06e6 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 230, 0x06e7 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06e8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06e9 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x06ea },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06eb },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06ec },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x06ed },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06ef },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x06f9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0900 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0903 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0904 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0939 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x093c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x094c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x094d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x094f },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0950 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0951 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0952 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0957 },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x095f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0962 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0963 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0965 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x096f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0980 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0983 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0984 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x098c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x098e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0990 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0992 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09a8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09a9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09b0 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09b1 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09b2 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09b5 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09b9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09bd },
-{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x09be },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09c4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09c6 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09c8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09ca },
-{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x09cb },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09cc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x09cd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09db },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x09dd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09de },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x09df },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09e1 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09e3 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09e5 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x09ef },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09f1 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a01 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a02 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a04 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a0a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a0e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a10 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a12 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a28 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a29 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a30 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a31 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a32 },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a33 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a34 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a35 },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a36 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a37 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a39 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a3d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a42 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a46 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a48 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a4a },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a4c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0a4d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a58 },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a5b },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a5c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a5d },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a5e },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a65 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0a6f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a73 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a74 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a80 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a83 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a84 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a8b },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a8c },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a8d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a8e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a91 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a92 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0aa8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0aa9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ab0 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ab1 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ab3 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ab4 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ab9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0abc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac6 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0aca },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0acc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0acd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0acf },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ad0 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0adf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ae0 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ae5 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0aef },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b00 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b03 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b04 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b0c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b0e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b10 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b12 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b28 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b29 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b30 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b31 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b33 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b35 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b39 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b3c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b3d },
-{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0b3e },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b43 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b46 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b48 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b4a },
-{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0b4b },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b4c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0b4d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b5b },
-{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0b5d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b5e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b61 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b65 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0b6f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b81 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b83 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b84 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b8a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b8d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b90 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b91 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b95 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b98 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b9a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b9b },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b9c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b9d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b9f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ba2 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ba4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ba7 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0baa },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bad },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0bb5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bb6 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0bb9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bbd },
-{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0bbe },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc2 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc5 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc9 },
-{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0bcb },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0bcc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0bcd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0be6 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0bef },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c00 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c03 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c04 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c0c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c0d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c10 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c11 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c28 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c29 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c33 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c34 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c39 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c3d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c44 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c45 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c48 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c49 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c4c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0c4d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c5f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c61 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c65 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0c6f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c81 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c83 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c84 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c8c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c8d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c90 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c91 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ca8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ca9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0cb3 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cb4 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0cb9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cbd },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc1 },
-{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0cc2 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc5 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc8 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc9 },
-{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0cca },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ccc },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0ccd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cdd },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cde },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cdf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ce1 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ce5 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0cef },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d01 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d03 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d04 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d0c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d0d },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d10 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d11 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d28 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d29 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d39 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d3d },
-{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0d3e },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d43 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d45 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d48 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d49 },
-{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0d4b },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d4c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0d4d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d5f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d61 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d65 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0d6f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e00 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e30 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0e31 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e32 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0e33 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0e37 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 103, 0x0e38 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 103, 0x0e39 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0e3a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e3f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e46 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0e47 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 107, 0x0e48 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 107, 0x0e49 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e4e },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e4f },
-{ C99|DIG|CXX|CID|NFC|NKC| 0, 0, 0x0e59 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e5b },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e80 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e82 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e83 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e84 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e86 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e88 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e89 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e8a },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e8c },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e8d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e93 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e97 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e98 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e9f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea0 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ea3 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea4 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ea5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea6 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ea7 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eab },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eac },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eae },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eaf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eb0 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0eb1 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eb2 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0eb3 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0eb7 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 118, 0x0eb8 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 118, 0x0eb9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eba },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ebc },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ebd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ebf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ec4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ec5 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ec6 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ec7 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 122, 0x0ec8 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 122, 0x0ec9 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 122, 0x0eca },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ecd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ecf },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0ed9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0edb },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x0edd },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eff },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f00 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f17 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f18 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f19 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f1f },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0f33 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f34 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f35 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f36 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f37 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f38 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 216, 0x0f39 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f3d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f42 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f43 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f47 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f48 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f4c },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f4d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f51 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f52 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f56 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f57 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f5b },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f5c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f68 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f69 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f70 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 129, 0x0f71 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f72 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f73 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 132, 0x0f74 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f76 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x0f77 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f78 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x0f79 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f7a },
-{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f7b },
-{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f7c },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f7f },
-{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f80 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f81 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0f82 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0f83 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0f84 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f85 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0f86 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f8b },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f8f },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f92 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f93 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f95 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f96 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f97 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f98 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f9c },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f9d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fa1 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fa2 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fa6 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fa7 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fab },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fac },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fad },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0fb0 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fb7 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0fb8 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fb9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x109f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x10c5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10cf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x10f6 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10ff },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x1159 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1160 },
-{ 0| 0|CXX|CID|NFC|NKC|CTX, 0, 0x1175 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x11a2 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11a7 },
-{ 0| 0|CXX|CID|NFC|NKC|CTX, 0, 0x11c2 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x11f9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1dff },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1e99 },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x1e9a },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x1e9b },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e9f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ef9 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1eff },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f15 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f17 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f1d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f1f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f45 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f47 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f4d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f4f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f57 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f58 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f59 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5a },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f5b },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5c },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f5d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5e },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f70 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f71 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f72 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f73 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f74 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f75 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f76 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f77 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f78 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f79 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f7a },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f7b },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f7c },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f7d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f7f },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fb4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fb5 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fba },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fbb },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fbc },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fbd },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x1fbe },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fc1 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fc4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fc5 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fc8 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fc9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fca },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fcb },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fcc },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fcf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fd2 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fd3 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fd5 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fda },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fdb },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fdf },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fe2 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fe3 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fea },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1feb },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fec },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1ff1 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ff4 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ff5 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ff8 },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1ff9 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ffa },
-{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1ffb },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ffc },
-{ 0| 0| 0|CID| 0| 0| 0, 0, 0x203e },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x2040 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x207e },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x207f },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x2101 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2102 },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x2106 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2107 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2109 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2113 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2114 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2115 },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x2117 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x2118 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x211d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2123 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2124 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2125 },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x2126 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2127 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2128 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2129 },
-{ C99| 0| 0|CID| 0| 0| 0, 0, 0x212a },
-{ C99| 0| 0| 0| 0| 0| 0, 0, 0x212b },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x212d },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x212e },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2131 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2132 },
-{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2138 },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x215f },
-{ C99|DIG| 0|CID|NFC| 0| 0, 0, 0x217f },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x2182 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3004 },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x3006 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x3007 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3020 },
-{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x3029 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3040 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x3093 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x3094 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x309a },
-{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x309c },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x309e },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x30a0 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x30f6 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x30fa },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x30fc },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x30fe },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x3104 },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x312c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x4dff },
-{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x9fa5 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xabff },
-{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0xd7a3 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xf8ff },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa0d },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa0f },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa10 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa11 },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa12 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa14 },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa1e },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa1f },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa20 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa21 },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa22 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa24 },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa26 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa29 },
-{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa2d },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb1e },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb1f },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfb29 },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb36 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb37 },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb3c },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb3d },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb3e },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb3f },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb41 },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfb42 },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb44 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb45 },
-{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb4e },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfbb1 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfbd2 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfd3d },
-{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfd3f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd4f },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfd8f },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd91 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfdc7 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfdef },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfdfb },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe6f },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfe72 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe73 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfe74 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe75 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfefc },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xff20 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xff3a },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0xff40 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xff5a },
-{ 0| 0| 0|CID|NFC| 0| 0, 0, 0xff65 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffbe },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffc1 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffc7 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffc9 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffcf },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffd1 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffd7 },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffd9 },
-{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffdc },
-{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffff },
+static const struct ucnrange ucnranges[] = {
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00a7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00a8 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00a9 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00aa },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00ac },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x00ad },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00ae },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00af },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b1 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00b4 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00b5 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b6 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x00b7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00b9 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00ba },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00bb },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x00be },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00bf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x00d6 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00d7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x00f6 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00f7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0131 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0133 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x013e },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0140 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0148 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0149 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x017e },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x017f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x01c3 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x01cc },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x01d4 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x01dc },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x01dd },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x01e3 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x01eb },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x01ef },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x01f0 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x01f3 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x01f5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x01f9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x01ff },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0217 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0229 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x022d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x022f },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0231 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x024f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x02a8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02af },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x02b8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02ba },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02bb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02bc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02c1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02cf },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02d1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02d7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x02dd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02df },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x02e4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x02ff },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0300 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0301 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0302 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0303 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0304 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0305 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0306 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0307 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0308 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0309 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x030a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x030b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x030c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x030d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x030e },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x030f },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0310 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0311 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0312 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0313 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0314 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 232, 0x0315 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0316 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0317 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0318 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0319 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 232, 0x031a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 216, 0x031b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x031c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x031d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x031e },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x031f },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0320 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 202, 0x0321 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 202, 0x0322 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x0323 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x0324 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x0325 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x0326 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 202, 0x0327 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 202, 0x0328 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0329 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x032a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x032b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x032c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x032d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x032e },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x032f },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x0330 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 220, 0x0331 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0332 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0333 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x0334 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x0335 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x0336 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x0337 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 1, 0x0338 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0339 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x033a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x033b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x033c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x033d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x033e },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x033f },
+{ 0| 0| 0|C11|N11| 0| 0| 0| 0, 230, 0x0340 },
+{ 0| 0| 0|C11|N11| 0| 0| 0| 0, 230, 0x0341 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 230, 0x0342 },
+{ 0| 0| 0|C11|N11| 0| 0| 0| 0, 230, 0x0343 },
+{ 0| 0| 0|C11|N11| 0| 0| 0| 0, 230, 0x0344 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC|CTX, 240, 0x0345 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0346 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0347 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0348 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0349 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x034a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x034b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x034c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x034d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 0, 0x034f },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0350 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0351 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0352 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0353 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0354 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0355 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0356 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0357 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 232, 0x0358 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x0359 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x035a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x035b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 233, 0x035c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 234, 0x035d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 234, 0x035e },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 233, 0x035f },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 234, 0x0360 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 234, 0x0361 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 233, 0x0362 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0363 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0364 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0365 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0366 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0367 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0368 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x0369 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x036a },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x036b },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x036c },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x036d },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x036e },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x036f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0373 },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0374 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0379 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x037a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x037d },
+{ 0| 0| 0|C11| 0|CID| 0| 0| 0, 0, 0x037e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0383 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0384 },
+{ 0| 0| 0|C11| 0| 0|NFC| 0| 0, 0, 0x0385 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0386 },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0387 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x038a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x038b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x038c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x038d },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0390 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03a1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03a2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03a9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x03b0 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03c9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x03ce },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03cf },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x03d2 },
+{ C99| 0|CXX|C11| 0| 0|NFC| 0| 0, 0, 0x03d4 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x03d6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03d9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03da },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03db },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03dc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03dd },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03de },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03df },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03e0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03e1 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03ef },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x03f2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x03f3 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x03f5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03f8 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x03f9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x03ff },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0400 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0401 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0402 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0403 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0406 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0407 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x040b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x040c },
+{ 0| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x040d },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x040e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0418 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0419 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0438 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0439 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x044f },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0450 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0451 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0452 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0453 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0456 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0457 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x045b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x045c },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x045d },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x045e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0475 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0477 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0481 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0482 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0483 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0484 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0485 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0486 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x048f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04c0 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04c2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04c4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x04c6 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04c8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x04ca },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04cc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x04cf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04d3 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04d5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04d7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04d9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04df },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04e1 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04e7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x04e9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04eb },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x04ed },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04f5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x04f7 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x04f9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0530 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0556 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0558 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0559 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0560 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0586 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0587 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0590 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0591 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0592 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0593 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0594 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0595 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0596 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0597 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0598 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0599 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 222, 0x059a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x059b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x059c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x059d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x059e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x059f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05a0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05a1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05a2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05a3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05a4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05a5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05a6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05a7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05a8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05a9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x05aa },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05ab },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05ac },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 222, 0x05ad },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 228, 0x05ae },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05af },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 10, 0x05b0 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 11, 0x05b1 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 12, 0x05b2 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 13, 0x05b3 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 14, 0x05b4 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 15, 0x05b5 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 16, 0x05b6 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 17, 0x05b7 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 18, 0x05b8 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 19, 0x05b9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 19, 0x05ba },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 20, 0x05bb },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 21, 0x05bc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 22, 0x05bd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x05be },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 23, 0x05bf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x05c0 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 24, 0x05c1 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 25, 0x05c2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x05c3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x05c4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x05c6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x05cf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x05ea },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x05ef },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x05f2 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x05f4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x060f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0610 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0611 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0612 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0613 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0614 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0615 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0616 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0617 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 30, 0x0618 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 31, 0x0619 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0620 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0621 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0626 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x063a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x063f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x064a },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 27, 0x064b },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 28, 0x064c },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 29, 0x064d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 30, 0x064e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 31, 0x064f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 32, 0x0650 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 33, 0x0651 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 34, 0x0652 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 230, 0x0653 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 230, 0x0654 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 220, 0x0655 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0656 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0657 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0658 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0659 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x065a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x065b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x065c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x065d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x065e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x065f },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0669 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x066f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0674 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0678 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x06b7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06b9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x06be },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06bf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x06c0 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x06c1 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x06c2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x06ce },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06cf },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06d2 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x06d3 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06d5 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06d6 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06d7 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06d8 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06d9 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06da },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06db },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06dc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06de },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06df },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06e0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06e1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06e2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x06e3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06e4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x06e6 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 230, 0x06e7 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06e8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06e9 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x06ea },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06eb },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x06ec },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x06ed },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06ef },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x06f9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0710 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x072f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0730 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0731 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0732 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0733 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0734 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0735 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0736 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0737 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0738 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0739 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x073a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x073b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x073c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x073d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x073e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x073f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0740 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0741 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0742 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0743 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0744 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0745 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0746 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0747 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0748 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0749 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x07ea },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07eb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07ec },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07ed },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07ee },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07ef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07f0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x07f1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x07f2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0815 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0816 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0817 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0818 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x081a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x081b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x081c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x081d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x081e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x081f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0820 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0821 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0822 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0824 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0825 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0826 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0828 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0829 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x082a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x082b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x082c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0858 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0859 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x085a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x08e3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08e4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08e5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08e6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08e7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08e8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08e9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08ea },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08eb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08ec },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08ed },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08ee },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08ef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 27, 0x08f0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 28, 0x08f1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 29, 0x08f2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08f3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08f4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08f5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08f6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08f7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08f8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08f9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x08fa },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08fb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08fc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x08fd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0900 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0903 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0904 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0928 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0929 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0930 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0931 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0933 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0934 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0939 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x093b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 7, 0x093c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x094c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x094d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x094f },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0950 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0951 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0952 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0953 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0957 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x095f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0962 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0963 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0965 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x096f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0980 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0983 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0984 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x098c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x098e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0990 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0992 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x09a8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09a9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x09b0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09b1 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x09b2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09b5 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x09b9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09bb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09bd },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x09be },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09c4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09c6 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09c8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09ca },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x09cc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x09cd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09d6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x09d7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09db },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x09dd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09de },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x09df },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x09e1 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09e3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09e5 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x09ef },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x09f1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a01 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a02 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a04 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a0a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a0e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a10 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a12 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a28 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a29 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a30 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a31 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a32 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x0a33 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a34 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a35 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x0a36 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a37 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a3b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a3d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a42 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a46 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a48 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a4a },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a4c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0a4d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a58 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x0a5b },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a5c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a5d },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x0a5e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a65 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a6f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a73 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a74 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a80 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a83 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a84 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a8b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a8c },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a8d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a8e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0a91 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0a92 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0aa8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0aa9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ab0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ab1 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ab3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ab4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ab9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0abb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 7, 0x0abc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ac5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ac6 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ac9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0aca },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0acc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0acd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0acf },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ad0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0adf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ae0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ae5 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0aef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b00 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b03 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b04 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b0c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b0e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b10 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b12 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b28 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b29 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b30 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b31 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b33 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b35 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b3b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 7, 0x0b3c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b3d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0b3e },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b43 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b46 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b47 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0b48 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b4a },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0b4c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0b4d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b55 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0b57 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b5b },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x0b5d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b5e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b61 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b65 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b6f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b81 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b83 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b84 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b8a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b8d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b90 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b91 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b93 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x0b94 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b95 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b98 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b9a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b9b },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b9c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0b9d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0b9f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ba2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ba4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ba7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0baa },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bad },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0bb5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bb6 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0bb9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bbd },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0bbe },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bc2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bc5 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bc8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bc9 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0bcc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0bcd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bd6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0bd7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0be6 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0bef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c00 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c03 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c04 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c0c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c0d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c10 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c11 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c28 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c29 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c33 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c34 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c3d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c44 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c45 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c47 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0c48 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c49 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c4c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0c4d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c54 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 84, 0x0c55 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 91, 0x0c56 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c5f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c61 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c65 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c6f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c81 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c83 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c84 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c8c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c8d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0c90 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0c91 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ca8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ca9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0cb3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cb4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0cb9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cbb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cbd },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cbf },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0cc0 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cc1 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0cc2 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cc4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cc5 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cc6 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0cc8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cc9 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0ccb },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ccc },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0ccd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cd4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0cd6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cdd },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cde },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cdf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ce1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ce5 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0cef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d01 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d03 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d04 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0d0c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d0d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0d10 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d11 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0d28 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d29 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0d39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d3d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0d3e },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d43 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d45 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d48 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d49 },
+{ C99| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0d4c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0d4d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d56 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0d57 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d5f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0d61 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d65 },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0d6f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0dc9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 9, 0x0dca },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0dce },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0dcf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0dd9 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0dda },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ddb },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x0dde },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x0ddf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e00 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e30 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e31 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e32 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0e33 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e37 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 103, 0x0e38 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 103, 0x0e39 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0e3a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e3f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e46 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e47 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 107, 0x0e48 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 107, 0x0e49 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 107, 0x0e4a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e4e },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e4f },
+{ C99|N99|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e59 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e5b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e80 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e82 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e83 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e84 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e86 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e88 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e89 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e8a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e8c },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e8d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e93 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e97 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0e98 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0e9f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea0 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea6 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ea9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0eab },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0eac },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0eae },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0eaf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0eb0 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0eb1 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0eb2 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x0eb3 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0eb7 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 118, 0x0eb8 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 118, 0x0eb9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0eba },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ebc },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ebd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ebf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ec4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ec5 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x0ec6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ec7 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 122, 0x0ec8 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 122, 0x0ec9 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 122, 0x0eca },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ecd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ecf },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0ed9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0edb },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x0edd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0eff },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f00 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f0b },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x0f0c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f17 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0f18 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0f19 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f1f },
+{ C99|N99| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f33 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f34 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0f35 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f36 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x0f37 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f38 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x0f39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f3d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f42 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f43 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f47 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f48 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f4c },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f4d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f51 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f52 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f56 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f57 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f5b },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f5c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f68 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f69 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f70 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 129, 0x0f71 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 130, 0x0f72 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f73 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 132, 0x0f74 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f76 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x0f77 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f78 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x0f79 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 130, 0x0f7a },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 130, 0x0f7b },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 130, 0x0f7c },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f7f },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 130, 0x0f80 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f81 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0f82 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0f83 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x0f84 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f85 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x0f86 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f8b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f8f },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f92 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f93 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f95 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f96 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f97 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f98 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0f9c },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0f9d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fa1 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0fa2 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fa6 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0fa7 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fab },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0fac },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fad },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fb0 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fb7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fb8 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x0fb9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x0fc5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1025 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1026 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x102d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x102e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1036 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1038 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x1039 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x108c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x109f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x10c5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10cf },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x10f6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10fb },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x10fc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10ff },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1159 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1160 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC|CTX, 0, 0x1175 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x11a2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x11a7 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC|CTX, 0, 0x11c2 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x11f9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x135c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x135d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x135e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x167f },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1680 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1713 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1733 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x17d1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x17dc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x180d },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x180e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x18a8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1938 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 222, 0x1939 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x193a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1a16 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a17 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1a5f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1a74 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a75 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a76 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a77 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a78 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a79 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a7a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1a7b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1a7e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b05 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b06 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b07 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b08 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b09 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b0a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b0b },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b0c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b0d },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b0e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b11 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b12 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b33 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 7, 0x1b34 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x1b35 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b3a },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b3b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b3c },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b3d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b3f },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b41 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b42 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1b43 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1b6a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b6b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1b6c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b6d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b6e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b6f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b70 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b71 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1b72 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ba9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x1baa },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1be5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1bf1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x1bf2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1c36 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ccf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1cd0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1cd1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1cd3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1cd4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cd5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cd6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cd7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cd8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cd9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1cda },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1cdb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cdc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cdd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cde },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1cdf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ce1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1ce2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1ce3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1ce4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1ce5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1ce6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1ce7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1cec },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1cf3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d2b },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d2e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d2f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d3a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d3b },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4e },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d6a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d77 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d78 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d9a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1dbf },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc0 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc1 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x1dc2 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc3 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc4 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc5 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc6 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc7 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc8 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dc9 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x1dca },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dcb },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dcc },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 234, 0x1dcd },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 214, 0x1dce },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x1dcf },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 202, 0x1dd0 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd1 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd2 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd3 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd4 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd5 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd6 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd7 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd8 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dd9 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dda },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1ddb },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1ddc },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1ddd },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dde },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1ddf },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1de0 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1de1 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1de2 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1de3 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1de4 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1de5 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 0, 0x1dfb },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 233, 0x1dfc },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x1dfd },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x1dfe },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x1dff },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e07 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e09 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e13 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e17 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e1b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e1d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e2d },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e2f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e37 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e39 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e4b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e53 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e5b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e5d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e63 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e69 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e77 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1e7b },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1e99 },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x1e9a },
+{ C99| 0| 0|C11| 0| 0|NFC| 0| 0, 0, 0x1e9b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1e9f },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1ea3 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1eb7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1ebd },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ec7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1ecf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ee3 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee7 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ef1 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x1ef9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1eff },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f15 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f17 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f1d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f1f },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f45 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f47 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f4d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f4f },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f57 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f58 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f59 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f5a },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f5b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f5c },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f5d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f5e },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f70 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f71 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f72 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f73 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f74 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f75 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f76 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f77 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f78 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f79 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f7a },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f7b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1f7c },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1f7d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f7f },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fb4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1fb5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fba },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1fbb },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fbc },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1fbd },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x1fbe },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1fc0 },
+{ 0| 0| 0|C11| 0| 0|NFC| 0| 0, 0, 0x1fc1 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fc4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1fc5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fc8 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1fc9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fca },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1fcb },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fcc },
+{ 0| 0| 0|C11| 0| 0|NFC| 0| 0, 0, 0x1fcf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fd2 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1fd3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1fd5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fda },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1fdb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1fdc },
+{ 0| 0| 0|C11| 0| 0|NFC| 0| 0, 0, 0x1fdf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fe2 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1fe3 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fea },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1feb },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1fec },
+{ 0| 0| 0|C11| 0| 0|NFC| 0| 0, 0, 0x1fed },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x1fee },
+{ 0| 0| 0|C11| 0|CID| 0| 0| 0, 0, 0x1fef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ff1 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ff4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ff5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ff8 },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1ff9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ffa },
+{ C99| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0x1ffb },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x1ffc },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x1ffd },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ffe },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1fff },
+{ 0| 0| 0| 0| 0|CID| 0| 0| 0, 0, 0x200a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x200d },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2029 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x202e },
+{ 0| 0| 0| 0| 0|CID|NFC| 0| 0, 0, 0x203e },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2040 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2053 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2054 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x205f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x206f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2071 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2073 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x207e },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x207f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x208e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x208f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x209c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x20a7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x20a8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x20cf },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20d0 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20d1 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20d2 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20d3 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20d4 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20d5 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20d6 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20d7 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20d8 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20d9 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20da },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20db },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 0, 0x20e0 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 0, 0x20e4 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20e5 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20e6 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20e7 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x20e8 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0x20e9 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20ea },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 1, 0x20eb },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x20ec },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x20ed },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x20ee },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 220, 0x20ef },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 0, 0x20ff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2101 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2102 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2103 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2104 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2106 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2107 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2108 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2109 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2113 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2114 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2115 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2116 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2117 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2118 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x211d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x211f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2122 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2123 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2124 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2125 },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x2126 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2127 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2128 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2129 },
+{ C99| 0| 0|C11| 0|CID| 0| 0| 0, 0, 0x212a },
+{ C99| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x212b },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x212d },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x212e },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2131 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2132 },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2138 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2139 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x213a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2140 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2144 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2149 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x214f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x215f },
+{ C99| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x217f },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2182 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2188 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2189 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x218f },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x245f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x24ea },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x24ff },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2775 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2793 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2bff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2c7b },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2c7d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2cee },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2cef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2cf0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2d6e },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2d6f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2d7e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2ddf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2de9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dea },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2deb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dec },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2ded },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dee },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2def },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2df9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dfa },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dfb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dfc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dfd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dfe },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x2dff },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2e7f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2e9e },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2e9f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2ef2 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2ef3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2eff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x2fd5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2fff },
+{ 0| 0| 0| 0| 0|CID|NFC| 0| 0, 0, 0x3003 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3004 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3007 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3020 },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3029 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 218, 0x302a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 228, 0x302b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 232, 0x302c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 222, 0x302d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 224, 0x302e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 224, 0x302f },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3030 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3035 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x3036 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3037 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x303a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3040 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x304b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x304c },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x304d },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x304e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x304f },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3050 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3051 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3052 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3053 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3054 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3055 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3056 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3057 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3058 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3059 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x305a },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x305b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x305c },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x305d },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x305e },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x305f },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3060 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3061 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3062 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3064 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3065 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3066 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3067 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3068 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3069 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x306f },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3071 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3072 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3074 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3075 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3077 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3078 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x307a },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x307b },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x307d },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x3093 },
+{ 0| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x3094 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3098 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 8, 0x3099 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 8, 0x309a },
+{ C99| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0x309c },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x309d },
+{ 0| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x309e },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x309f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x30a0 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30ab },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30ac },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30ad },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30ae },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30af },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30b0 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30b1 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30b2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30b3 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30b4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30b5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30b6 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30b7 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30b8 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30b9 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30ba },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30bb },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30bc },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30bd },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30be },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30bf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30c0 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30c1 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30c2 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30c4 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30c5 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30c6 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30c7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30c8 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30c9 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30cf },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30d1 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30d2 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30d4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30d5 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30d7 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30d8 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30da },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30db },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30dd },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30f3 },
+{ C99| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30f4 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30f6 },
+{ 0| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30fa },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30fc },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x30fd },
+{ 0| 0|CXX|C11| 0| 0|NFC|NKC| 0, 0, 0x30fe },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x30ff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3104 },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x312c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3130 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x318e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3191 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x319f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x31ff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x321e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x321f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x3247 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x324f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x327e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x327f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x32fe },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x32ff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x33ff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x4dff },
+{ C99| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0x9fa5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa66e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa673 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa674 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa675 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa676 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa677 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa678 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa679 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa67a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa67b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa67c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa69e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa6ef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa6f0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa76f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xa770 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa7f7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xa7f9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa805 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa8c3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa8df },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e4 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8e9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8ea },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8eb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8ec },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8ed },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8ee },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8ef },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xa8f0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa92a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0xa92b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0xa92c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa952 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa9b2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xa9bf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xaaaf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xaab1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xaab2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xaab3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xaab6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xaab7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xaabd },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0xaabe },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xaac0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xaaf5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xabec },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xabff },
+{ C99| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xd7a3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xd7ff },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xf8ff },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa0d },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa0f },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa10 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa11 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa12 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa14 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa1e },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa1f },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa20 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa21 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa22 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa24 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa26 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfa29 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfa2d },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0xfa6d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfa6f },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0xfad9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfaff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfb06 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfb12 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfb17 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfb1c },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0xfb1d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 26, 0xfb1e },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb1f },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfb29 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb36 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfb37 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb3c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfb3d },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb3e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfb3f },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb41 },
+{ 0| 0|CXX|C11| 0|CID|NFC|NKC| 0, 0, 0xfb42 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb44 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfb45 },
+{ 0| 0|CXX|C11| 0| 0| 0| 0| 0, 0, 0xfb4e },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfbb1 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfbd2 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfd3d },
+{ 0| 0|CXX| 0| 0|CID|NFC|NKC| 0, 0, 0xfd3f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfd4f },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfd8f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfd91 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfdc7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfdcf },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfdef },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfdfb },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfdfc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe0f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfe19 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe1f },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0xfe20 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0xfe21 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0xfe22 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0xfe23 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0xfe24 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 230, 0xfe25 },
+{ 0| 0| 0|C11|N11|CID|NFC|NKC| 0, 0, 0xfe2f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfe44 },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe46 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfe52 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe53 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfe66 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe67 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xfe6b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe6f },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfe72 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe73 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfe74 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfe75 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xfefc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xff00 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xff20 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xff3a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xff40 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xff5a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xff65 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xffbe },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xffc1 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xffc7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xffc9 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xffcf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xffd1 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xffd7 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xffd9 },
+{ 0| 0|CXX|C11| 0|CID|NFC| 0| 0, 0, 0xffdc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xffdf },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xffe6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xffe7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0xffee },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xfffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x101fc },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10a0c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10a0e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10a37 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x10a38 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x10a39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x10a3e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x11045 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x11099 },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1109a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1109b },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1109c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x110aa },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x110ab },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x110b8 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x110b9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 7, 0x110ba },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x110ff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x11100 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x11101 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x11126 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC|CTX, 0, 0x11127 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1112d },
+{ 0| 0| 0|C11| 0| 0|NFC|NKC| 0, 0, 0x1112f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x11132 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x11133 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x111bf },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x116b5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 9, 0x116b6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d15d },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x1d164 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x1d165 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x1d166 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1d167 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 1, 0x1d168 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d16c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 226, 0x1d16d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x1d16e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x1d16f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x1d170 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 216, 0x1d171 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d17a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d17b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d17c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d17d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d17e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d17f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d180 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d181 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d184 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d185 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d186 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d187 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d188 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d189 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 220, 0x1d18a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d1a9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d1aa },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d1ab },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d1ac },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d1ba },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x1d1c0 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d241 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d242 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 230, 0x1d243 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d3ff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d454 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d455 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d49c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d49d },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d49f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4a1 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4a2 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4a4 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4a6 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4a8 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4ac },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4ad },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4b9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4ba },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4bb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4bc },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d4c3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d4c4 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d505 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d506 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d50a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d50c },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d514 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d515 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d51c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d51d },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d539 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d53a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d53e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d53f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d544 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d545 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d546 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d549 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d550 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d551 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d6a5 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d6a7 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d7cb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1d7cd },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1d7ff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1edff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee03 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee04 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee1f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee20 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee22 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee23 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee24 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee26 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee27 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee28 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee32 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee33 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee37 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee38 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee39 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee3a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee3b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee41 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee42 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee46 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee47 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee48 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee49 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee4a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee4b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee4c },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee4f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee50 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee52 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee53 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee54 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee56 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee57 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee58 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee59 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee5a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee5b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee5c },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee5d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee5e },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee5f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee60 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee62 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee63 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee64 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee66 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee6a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee6b },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee72 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee73 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee77 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee78 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee7c },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee7d },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee7e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee7f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee89 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1ee8a },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1ee9b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1eea0 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1eea3 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1eea4 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1eea9 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1eeaa },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1eebb },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f0ff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f10a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f10f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f12e },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f12f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f14f },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f169 },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f16b },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f18f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f190 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f1ff },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f202 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f20f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f23a },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f23f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f248 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1f24f },
+{ 0| 0| 0|C11| 0|CID|NFC| 0| 0, 0, 0x1f251 },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x1fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2f7ff },
+{ 0| 0| 0|C11| 0| 0| 0| 0| 0, 0, 0x2fa1d },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x2fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x3fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x4fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x4ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x5fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x5ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x6fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x6ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x7fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x7ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x8fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x8ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0x9fffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x9ffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xafffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xbfffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xbffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xcfffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xcffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xdfffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xdffff },
+{ 0| 0| 0|C11| 0|CID|NFC|NKC| 0, 0, 0xefffd },
+{ 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10ffff },
+};
+static bool
+check_nfc (cpp_reader *pfile, cppchar_t c, cppchar_t p)
+{
+ switch (c)
+ {
+ case 0x0300:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0045:
+ case 0x0049:
+ case 0x004f:
+ case 0x0055:
+ case 0x0061:
+ case 0x0065:
+ case 0x0069:
+ case 0x006f:
+ case 0x0075:
+ case 0x00dc:
+ case 0x00fc:
+ case 0x004e:
+ case 0x006e:
+ case 0x0415:
+ case 0x0418:
+ case 0x0435:
+ case 0x0438:
+ case 0x0112:
+ case 0x0113:
+ case 0x014c:
+ case 0x014d:
+ case 0x0057:
+ case 0x0077:
+ case 0x00c2:
+ case 0x00e2:
+ case 0x0102:
+ case 0x0103:
+ case 0x00ca:
+ case 0x00ea:
+ case 0x00d4:
+ case 0x00f4:
+ case 0x01a0:
+ case 0x01a1:
+ case 0x01af:
+ case 0x01b0:
+ case 0x0059:
+ case 0x0079:
+ case 0x1f00:
+ case 0x1f80:
+ case 0x1f01:
+ case 0x1f81:
+ case 0x1f08:
+ case 0x1f88:
+ case 0x1f09:
+ case 0x1f89:
+ case 0x1f10:
+ case 0x1f11:
+ case 0x1f18:
+ case 0x1f19:
+ case 0x1f20:
+ case 0x1f90:
+ case 0x1f21:
+ case 0x1f91:
+ case 0x1f28:
+ case 0x1f98:
+ case 0x1f29:
+ case 0x1f99:
+ case 0x1f30:
+ case 0x1f31:
+ case 0x1f38:
+ case 0x1f39:
+ case 0x1f40:
+ case 0x1f41:
+ case 0x1f48:
+ case 0x1f49:
+ case 0x1f50:
+ case 0x1f51:
+ case 0x1f59:
+ case 0x1f60:
+ case 0x1fa0:
+ case 0x1f61:
+ case 0x1fa1:
+ case 0x1f68:
+ case 0x1fa8:
+ case 0x1f69:
+ case 0x1fa9:
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x03b5:
+ case 0x03b7:
+ case 0x1fc3:
+ case 0x03b9:
+ case 0x03bf:
+ case 0x03c5:
+ case 0x03c9:
+ case 0x1ff3:
+ case 0x0391:
+ case 0x1fbc:
+ case 0x0395:
+ case 0x0397:
+ case 0x1fcc:
+ case 0x1fbf:
+ case 0x03ca:
+ case 0x0399:
+ case 0x1ffe:
+ case 0x03cb:
+ case 0x03a5:
+ case 0x00a8:
+ case 0x039f:
+ case 0x03a9:
+ case 0x1ffc:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0301:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0045:
+ case 0x0049:
+ case 0x004f:
+ case 0x0055:
+ case 0x0059:
+ case 0x0061:
+ case 0x0065:
+ case 0x0069:
+ case 0x006f:
+ case 0x0075:
+ case 0x0079:
+ case 0x0043:
+ case 0x0063:
+ case 0x004c:
+ case 0x006c:
+ case 0x004e:
+ case 0x006e:
+ case 0x0052:
+ case 0x0072:
+ case 0x0053:
+ case 0x0073:
+ case 0x005a:
+ case 0x007a:
+ case 0x00dc:
+ case 0x00fc:
+ case 0x0047:
+ case 0x0067:
+ case 0x00c5:
+ case 0x00e5:
+ case 0x00c6:
+ case 0x00e6:
+ case 0x00d8:
+ case 0x00f8:
+ case 0x00a8:
+ case 0x0391:
+ case 0x1fbc:
+ case 0x0395:
+ case 0x0397:
+ case 0x1fcc:
+ case 0x0399:
+ case 0x039f:
+ case 0x03a5:
+ case 0x03a9:
+ case 0x1ffc:
+ case 0x03ca:
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x03b5:
+ case 0x03b7:
+ case 0x1fc3:
+ case 0x03b9:
+ case 0x03cb:
+ case 0x03bf:
+ case 0x03c5:
+ case 0x03c9:
+ case 0x1ff3:
+ case 0x03d2:
+ case 0x0413:
+ case 0x041a:
+ case 0x0433:
+ case 0x043a:
+ case 0x00c7:
+ case 0x00e7:
+ case 0x0112:
+ case 0x0113:
+ case 0x00cf:
+ case 0x00ef:
+ case 0x004b:
+ case 0x006b:
+ case 0x004d:
+ case 0x006d:
+ case 0x00d5:
+ case 0x00f5:
+ case 0x014c:
+ case 0x014d:
+ case 0x0050:
+ case 0x0070:
+ case 0x0168:
+ case 0x0169:
+ case 0x0057:
+ case 0x0077:
+ case 0x00c2:
+ case 0x00e2:
+ case 0x0102:
+ case 0x0103:
+ case 0x00ca:
+ case 0x00ea:
+ case 0x00d4:
+ case 0x00f4:
+ case 0x01a0:
+ case 0x01a1:
+ case 0x01af:
+ case 0x01b0:
+ case 0x1f00:
+ case 0x1f80:
+ case 0x1f01:
+ case 0x1f81:
+ case 0x1f08:
+ case 0x1f88:
+ case 0x1f09:
+ case 0x1f89:
+ case 0x1f10:
+ case 0x1f11:
+ case 0x1f18:
+ case 0x1f19:
+ case 0x1f20:
+ case 0x1f90:
+ case 0x1f21:
+ case 0x1f91:
+ case 0x1f28:
+ case 0x1f98:
+ case 0x1f29:
+ case 0x1f99:
+ case 0x1f30:
+ case 0x1f31:
+ case 0x1f38:
+ case 0x1f39:
+ case 0x1f40:
+ case 0x1f41:
+ case 0x1f48:
+ case 0x1f49:
+ case 0x1f50:
+ case 0x1f51:
+ case 0x1f59:
+ case 0x1f60:
+ case 0x1fa0:
+ case 0x1f61:
+ case 0x1fa1:
+ case 0x1f68:
+ case 0x1fa8:
+ case 0x1f69:
+ case 0x1fa9:
+ case 0x1fbf:
+ case 0x1ffe:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0302:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0045:
+ case 0x0049:
+ case 0x004f:
+ case 0x0055:
+ case 0x0061:
+ case 0x0065:
+ case 0x0069:
+ case 0x006f:
+ case 0x0075:
+ case 0x0043:
+ case 0x0063:
+ case 0x0047:
+ case 0x0067:
+ case 0x0048:
+ case 0x0068:
+ case 0x004a:
+ case 0x006a:
+ case 0x0053:
+ case 0x0073:
+ case 0x0057:
+ case 0x0077:
+ case 0x0059:
+ case 0x0079:
+ case 0x005a:
+ case 0x007a:
+ case 0x1ea0:
+ case 0x1ea1:
+ case 0x1eb8:
+ case 0x1eb9:
+ case 0x1ecc:
+ case 0x1ecd:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0303:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x004e:
+ case 0x004f:
+ case 0x0061:
+ case 0x006e:
+ case 0x006f:
+ case 0x0049:
+ case 0x0069:
+ case 0x0055:
+ case 0x0075:
+ case 0x0056:
+ case 0x0076:
+ case 0x00c2:
+ case 0x00e2:
+ case 0x0102:
+ case 0x0103:
+ case 0x0045:
+ case 0x0065:
+ case 0x00ca:
+ case 0x00ea:
+ case 0x00d4:
+ case 0x00f4:
+ case 0x01a0:
+ case 0x01a1:
+ case 0x01af:
+ case 0x01b0:
+ case 0x0059:
+ case 0x0079:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0304:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0061:
+ case 0x0045:
+ case 0x0065:
+ case 0x0049:
+ case 0x0069:
+ case 0x004f:
+ case 0x006f:
+ case 0x0055:
+ case 0x0075:
+ case 0x00dc:
+ case 0x00fc:
+ case 0x00c4:
+ case 0x00e4:
+ case 0x0226:
+ case 0x0227:
+ case 0x00c6:
+ case 0x00e6:
+ case 0x01ea:
+ case 0x01eb:
+ case 0x00d6:
+ case 0x00f6:
+ case 0x00d5:
+ case 0x00f5:
+ case 0x022e:
+ case 0x022f:
+ case 0x0059:
+ case 0x0079:
+ case 0x0418:
+ case 0x0438:
+ case 0x0423:
+ case 0x0443:
+ case 0x0047:
+ case 0x0067:
+ case 0x1e36:
+ case 0x1e37:
+ case 0x1e5a:
+ case 0x1e5b:
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x0391:
+ case 0x1fbc:
+ case 0x03b9:
+ case 0x0399:
+ case 0x03c5:
+ case 0x03a5:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0306:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0061:
+ case 0x0045:
+ case 0x0065:
+ case 0x0047:
+ case 0x0067:
+ case 0x0049:
+ case 0x0069:
+ case 0x004f:
+ case 0x006f:
+ case 0x0055:
+ case 0x0075:
+ case 0x0423:
+ case 0x0418:
+ case 0x0438:
+ case 0x0443:
+ case 0x0416:
+ case 0x0436:
+ case 0x0410:
+ case 0x0430:
+ case 0x0415:
+ case 0x0435:
+ case 0x0228:
+ case 0x0229:
+ case 0x1ea0:
+ case 0x1ea1:
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x0391:
+ case 0x1fbc:
+ case 0x03b9:
+ case 0x0399:
+ case 0x03c5:
+ case 0x03a5:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0307:
+ switch (p)
+ {
+ case 0x0043:
+ case 0x0063:
+ case 0x0045:
+ case 0x0065:
+ case 0x0047:
+ case 0x0067:
+ case 0x0049:
+ case 0x005a:
+ case 0x007a:
+ case 0x0041:
+ case 0x0061:
+ case 0x004f:
+ case 0x006f:
+ case 0x0042:
+ case 0x0062:
+ case 0x0044:
+ case 0x0064:
+ case 0x0046:
+ case 0x0066:
+ case 0x0048:
+ case 0x0068:
+ case 0x004d:
+ case 0x006d:
+ case 0x004e:
+ case 0x006e:
+ case 0x0050:
+ case 0x0070:
+ case 0x0052:
+ case 0x0072:
+ case 0x0053:
+ case 0x0073:
+ case 0x015a:
+ case 0x015b:
+ case 0x0160:
+ case 0x0161:
+ case 0x1e62:
+ case 0x1e63:
+ case 0x0054:
+ case 0x0074:
+ case 0x0057:
+ case 0x0077:
+ case 0x0058:
+ case 0x0078:
+ case 0x0059:
+ case 0x0079:
+ case 0x017f:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0308:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0045:
+ case 0x0049:
+ case 0x004f:
+ case 0x0055:
+ case 0x0061:
+ case 0x0065:
+ case 0x0069:
+ case 0x006f:
+ case 0x0075:
+ case 0x0079:
+ case 0x0059:
+ case 0x0399:
+ case 0x03a5:
+ case 0x03b9:
+ case 0x03c5:
+ case 0x03d2:
+ case 0x0415:
+ case 0x0406:
+ case 0x0435:
+ case 0x0456:
+ case 0x0410:
+ case 0x0430:
+ case 0x04d8:
+ case 0x04d9:
+ case 0x0416:
+ case 0x0436:
+ case 0x0417:
+ case 0x0437:
+ case 0x0418:
+ case 0x0438:
+ case 0x041e:
+ case 0x043e:
+ case 0x04e8:
+ case 0x04e9:
+ case 0x042d:
+ case 0x044d:
+ case 0x0423:
+ case 0x0443:
+ case 0x0427:
+ case 0x0447:
+ case 0x042b:
+ case 0x044b:
+ case 0x0048:
+ case 0x0068:
+ case 0x00d5:
+ case 0x00f5:
+ case 0x016a:
+ case 0x016b:
+ case 0x0057:
+ case 0x0077:
+ case 0x0058:
+ case 0x0078:
+ case 0x0074:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0309:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0061:
+ case 0x00c2:
+ case 0x00e2:
+ case 0x0102:
+ case 0x0103:
+ case 0x0045:
+ case 0x0065:
+ case 0x00ca:
+ case 0x00ea:
+ case 0x0049:
+ case 0x0069:
+ case 0x004f:
+ case 0x006f:
+ case 0x00d4:
+ case 0x00f4:
+ case 0x01a0:
+ case 0x01a1:
+ case 0x0055:
+ case 0x0075:
+ case 0x01af:
+ case 0x01b0:
+ case 0x0059:
+ case 0x0079:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x030a:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0061:
+ case 0x0055:
+ case 0x0075:
+ case 0x0077:
+ case 0x0079:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x030b:
+ switch (p)
+ {
+ case 0x004f:
+ case 0x006f:
+ case 0x0055:
+ case 0x0075:
+ case 0x0423:
+ case 0x0443:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x030c:
+ switch (p)
+ {
+ case 0x0043:
+ case 0x0063:
+ case 0x0044:
+ case 0x0064:
+ case 0x0045:
+ case 0x0065:
+ case 0x004c:
+ case 0x006c:
+ case 0x004e:
+ case 0x006e:
+ case 0x0052:
+ case 0x0072:
+ case 0x0053:
+ case 0x0073:
+ case 0x0054:
+ case 0x0074:
+ case 0x005a:
+ case 0x007a:
+ case 0x0041:
+ case 0x0061:
+ case 0x0049:
+ case 0x0069:
+ case 0x004f:
+ case 0x006f:
+ case 0x0055:
+ case 0x0075:
+ case 0x00dc:
+ case 0x00fc:
+ case 0x0047:
+ case 0x0067:
+ case 0x004b:
+ case 0x006b:
+ case 0x01b7:
+ case 0x0292:
+ case 0x006a:
+ case 0x0048:
+ case 0x0068:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x030f:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0061:
+ case 0x0045:
+ case 0x0065:
+ case 0x0049:
+ case 0x0069:
+ case 0x004f:
+ case 0x006f:
+ case 0x0052:
+ case 0x0072:
+ case 0x0055:
+ case 0x0075:
+ case 0x0474:
+ case 0x0475:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0311:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x0061:
+ case 0x0045:
+ case 0x0065:
+ case 0x0049:
+ case 0x0069:
+ case 0x004f:
+ case 0x006f:
+ case 0x0052:
+ case 0x0072:
+ case 0x0055:
+ case 0x0075:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0313:
+ switch (p)
+ {
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x0391:
+ case 0x1fbc:
+ case 0x03b5:
+ case 0x0395:
+ case 0x03b7:
+ case 0x1fc3:
+ case 0x0397:
+ case 0x1fcc:
+ case 0x03b9:
+ case 0x0399:
+ case 0x03bf:
+ case 0x039f:
+ case 0x03c5:
+ case 0x03c9:
+ case 0x1ff3:
+ case 0x03a9:
+ case 0x1ffc:
+ case 0x03c1:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0314:
+ switch (p)
+ {
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x0391:
+ case 0x1fbc:
+ case 0x03b5:
+ case 0x0395:
+ case 0x03b7:
+ case 0x1fc3:
+ case 0x0397:
+ case 0x1fcc:
+ case 0x03b9:
+ case 0x0399:
+ case 0x03bf:
+ case 0x039f:
+ case 0x03c5:
+ case 0x03a5:
+ case 0x03c9:
+ case 0x1ff3:
+ case 0x03a9:
+ case 0x1ffc:
+ case 0x03c1:
+ case 0x03a1:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x031b:
+ switch (p)
+ {
+ case 0x004f:
+ case 0x00d2:
+ case 0x00d3:
+ case 0x00d4:
+ case 0x00d5:
+ case 0x00d6:
+ case 0x014c:
+ case 0x014e:
+ case 0x0150:
+ case 0x01d1:
+ case 0x020c:
+ case 0x020e:
+ case 0x022a:
+ case 0x022c:
+ case 0x022e:
+ case 0x0230:
+ case 0x1e4c:
+ case 0x1e4e:
+ case 0x1e50:
+ case 0x1e52:
+ case 0x1ecc:
+ case 0x1ece:
+ case 0x1ed0:
+ case 0x1ed2:
+ case 0x1ed4:
+ case 0x1ed6:
+ case 0x1ed8:
+ case 0x006f:
+ case 0x00f2:
+ case 0x00f3:
+ case 0x00f4:
+ case 0x00f5:
+ case 0x00f6:
+ case 0x014d:
+ case 0x014f:
+ case 0x0151:
+ case 0x01d2:
+ case 0x020d:
+ case 0x020f:
+ case 0x022b:
+ case 0x022d:
+ case 0x022f:
+ case 0x0231:
+ case 0x1e4d:
+ case 0x1e4f:
+ case 0x1e51:
+ case 0x1e53:
+ case 0x1ecd:
+ case 0x1ecf:
+ case 0x1ed1:
+ case 0x1ed3:
+ case 0x1ed5:
+ case 0x1ed7:
+ case 0x1ed9:
+ case 0x0055:
+ case 0x00d9:
+ case 0x00da:
+ case 0x00db:
+ case 0x00dc:
+ case 0x0168:
+ case 0x016a:
+ case 0x016c:
+ case 0x016e:
+ case 0x0170:
+ case 0x01d3:
+ case 0x01d5:
+ case 0x01d7:
+ case 0x01d9:
+ case 0x01db:
+ case 0x0214:
+ case 0x0216:
+ case 0x1e72:
+ case 0x1e74:
+ case 0x1e76:
+ case 0x1e78:
+ case 0x1e7a:
+ case 0x1ee4:
+ case 0x1ee6:
+ case 0x0075:
+ case 0x00f9:
+ case 0x00fa:
+ case 0x00fb:
+ case 0x00fc:
+ case 0x0169:
+ case 0x016b:
+ case 0x016d:
+ case 0x016f:
+ case 0x0171:
+ case 0x01d4:
+ case 0x01d6:
+ case 0x01d8:
+ case 0x01da:
+ case 0x01dc:
+ case 0x0215:
+ case 0x0217:
+ case 0x1e73:
+ case 0x1e75:
+ case 0x1e77:
+ case 0x1e79:
+ case 0x1e7b:
+ case 0x1ee5:
+ case 0x1ee7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0323:
+ switch (p)
+ {
+ case 0x0042:
+ case 0x1e02:
+ case 0x0062:
+ case 0x1e03:
+ case 0x0044:
+ case 0x010e:
+ case 0x1e0a:
+ case 0x0064:
+ case 0x010f:
+ case 0x1e0b:
+ case 0x0048:
+ case 0x0124:
+ case 0x021e:
+ case 0x1e22:
+ case 0x1e26:
+ case 0x0068:
+ case 0x0125:
+ case 0x021f:
+ case 0x1e23:
+ case 0x1e27:
+ case 0x004b:
+ case 0x01e8:
+ case 0x1e30:
+ case 0x006b:
+ case 0x01e9:
+ case 0x1e31:
+ case 0x004c:
+ case 0x0139:
+ case 0x013d:
+ case 0x006c:
+ case 0x013a:
+ case 0x013e:
+ case 0x004d:
+ case 0x1e3e:
+ case 0x1e40:
+ case 0x006d:
+ case 0x1e3f:
+ case 0x1e41:
+ case 0x004e:
+ case 0x00d1:
+ case 0x0143:
+ case 0x0147:
+ case 0x01f8:
+ case 0x1e44:
+ case 0x006e:
+ case 0x00f1:
+ case 0x0144:
+ case 0x0148:
+ case 0x01f9:
+ case 0x1e45:
+ case 0x0052:
+ case 0x0154:
+ case 0x0158:
+ case 0x0210:
+ case 0x0212:
+ case 0x1e58:
+ case 0x0072:
+ case 0x0155:
+ case 0x0159:
+ case 0x0211:
+ case 0x0213:
+ case 0x1e59:
+ case 0x0053:
+ case 0x015a:
+ case 0x015c:
+ case 0x0160:
+ case 0x1e60:
+ case 0x1e64:
+ case 0x1e66:
+ case 0x0073:
+ case 0x015b:
+ case 0x015d:
+ case 0x0161:
+ case 0x1e61:
+ case 0x1e65:
+ case 0x1e67:
+ case 0x0054:
+ case 0x0164:
+ case 0x1e6a:
+ case 0x0074:
+ case 0x0165:
+ case 0x1e6b:
+ case 0x1e97:
+ case 0x0056:
+ case 0x1e7c:
+ case 0x0076:
+ case 0x1e7d:
+ case 0x0057:
+ case 0x0174:
+ case 0x1e80:
+ case 0x1e82:
+ case 0x1e84:
+ case 0x1e86:
+ case 0x0077:
+ case 0x0175:
+ case 0x1e81:
+ case 0x1e83:
+ case 0x1e85:
+ case 0x1e87:
+ case 0x1e98:
+ case 0x005a:
+ case 0x0179:
+ case 0x017b:
+ case 0x017d:
+ case 0x1e90:
+ case 0x007a:
+ case 0x017a:
+ case 0x017c:
+ case 0x017e:
+ case 0x1e91:
+ case 0x0041:
+ case 0x00c0:
+ case 0x00c1:
+ case 0x00c2:
+ case 0x00c3:
+ case 0x00c4:
+ case 0x00c5:
+ case 0x0100:
+ case 0x0102:
+ case 0x01cd:
+ case 0x01de:
+ case 0x01e0:
+ case 0x01fa:
+ case 0x0200:
+ case 0x0202:
+ case 0x0226:
+ case 0x1ea2:
+ case 0x1ea4:
+ case 0x1ea6:
+ case 0x1ea8:
+ case 0x1eaa:
+ case 0x1eae:
+ case 0x1eb0:
+ case 0x1eb2:
+ case 0x1eb4:
+ case 0x0061:
+ case 0x00e0:
+ case 0x00e1:
+ case 0x00e2:
+ case 0x00e3:
+ case 0x00e4:
+ case 0x00e5:
+ case 0x0101:
+ case 0x0103:
+ case 0x01ce:
+ case 0x01df:
+ case 0x01e1:
+ case 0x01fb:
+ case 0x0201:
+ case 0x0203:
+ case 0x0227:
+ case 0x1ea3:
+ case 0x1ea5:
+ case 0x1ea7:
+ case 0x1ea9:
+ case 0x1eab:
+ case 0x1eaf:
+ case 0x1eb1:
+ case 0x1eb3:
+ case 0x1eb5:
+ case 0x0045:
+ case 0x00c8:
+ case 0x00c9:
+ case 0x00ca:
+ case 0x00cb:
+ case 0x0112:
+ case 0x0114:
+ case 0x0116:
+ case 0x011a:
+ case 0x0204:
+ case 0x0206:
+ case 0x1e14:
+ case 0x1e16:
+ case 0x1eba:
+ case 0x1ebc:
+ case 0x1ebe:
+ case 0x1ec0:
+ case 0x1ec2:
+ case 0x1ec4:
+ case 0x0065:
+ case 0x00e8:
+ case 0x00e9:
+ case 0x00ea:
+ case 0x00eb:
+ case 0x0113:
+ case 0x0115:
+ case 0x0117:
+ case 0x011b:
+ case 0x0205:
+ case 0x0207:
+ case 0x1e15:
+ case 0x1e17:
+ case 0x1ebb:
+ case 0x1ebd:
+ case 0x1ebf:
+ case 0x1ec1:
+ case 0x1ec3:
+ case 0x1ec5:
+ case 0x0049:
+ case 0x00cc:
+ case 0x00cd:
+ case 0x00ce:
+ case 0x00cf:
+ case 0x0128:
+ case 0x012a:
+ case 0x012c:
+ case 0x0130:
+ case 0x01cf:
+ case 0x0208:
+ case 0x020a:
+ case 0x1e2e:
+ case 0x1ec8:
+ case 0x0069:
+ case 0x00ec:
+ case 0x00ed:
+ case 0x00ee:
+ case 0x00ef:
+ case 0x0129:
+ case 0x012b:
+ case 0x012d:
+ case 0x01d0:
+ case 0x0209:
+ case 0x020b:
+ case 0x1e2f:
+ case 0x1ec9:
+ case 0x004f:
+ case 0x00d2:
+ case 0x00d3:
+ case 0x00d4:
+ case 0x00d5:
+ case 0x00d6:
+ case 0x014c:
+ case 0x014e:
+ case 0x0150:
+ case 0x01d1:
+ case 0x020c:
+ case 0x020e:
+ case 0x022a:
+ case 0x022c:
+ case 0x022e:
+ case 0x0230:
+ case 0x1e4c:
+ case 0x1e4e:
+ case 0x1e50:
+ case 0x1e52:
+ case 0x1ece:
+ case 0x1ed0:
+ case 0x1ed2:
+ case 0x1ed4:
+ case 0x1ed6:
+ case 0x006f:
+ case 0x00f2:
+ case 0x00f3:
+ case 0x00f4:
+ case 0x00f5:
+ case 0x00f6:
+ case 0x014d:
+ case 0x014f:
+ case 0x0151:
+ case 0x01d2:
+ case 0x020d:
+ case 0x020f:
+ case 0x022b:
+ case 0x022d:
+ case 0x022f:
+ case 0x0231:
+ case 0x1e4d:
+ case 0x1e4f:
+ case 0x1e51:
+ case 0x1e53:
+ case 0x1ecf:
+ case 0x1ed1:
+ case 0x1ed3:
+ case 0x1ed5:
+ case 0x1ed7:
+ case 0x01a0:
+ case 0x1eda:
+ case 0x1edc:
+ case 0x1ede:
+ case 0x1ee0:
+ case 0x01a1:
+ case 0x1edb:
+ case 0x1edd:
+ case 0x1edf:
+ case 0x1ee1:
+ case 0x0055:
+ case 0x00d9:
+ case 0x00da:
+ case 0x00db:
+ case 0x00dc:
+ case 0x0168:
+ case 0x016a:
+ case 0x016c:
+ case 0x016e:
+ case 0x0170:
+ case 0x01d3:
+ case 0x01d5:
+ case 0x01d7:
+ case 0x01d9:
+ case 0x01db:
+ case 0x0214:
+ case 0x0216:
+ case 0x1e78:
+ case 0x1e7a:
+ case 0x1ee6:
+ case 0x0075:
+ case 0x00f9:
+ case 0x00fa:
+ case 0x00fb:
+ case 0x00fc:
+ case 0x0169:
+ case 0x016b:
+ case 0x016d:
+ case 0x016f:
+ case 0x0171:
+ case 0x01d4:
+ case 0x01d6:
+ case 0x01d8:
+ case 0x01da:
+ case 0x01dc:
+ case 0x0215:
+ case 0x0217:
+ case 0x1e79:
+ case 0x1e7b:
+ case 0x1ee7:
+ case 0x01af:
+ case 0x1ee8:
+ case 0x1eea:
+ case 0x1eec:
+ case 0x1eee:
+ case 0x01b0:
+ case 0x1ee9:
+ case 0x1eeb:
+ case 0x1eed:
+ case 0x1eef:
+ case 0x0059:
+ case 0x00dd:
+ case 0x0176:
+ case 0x0178:
+ case 0x0232:
+ case 0x1e8e:
+ case 0x1ef2:
+ case 0x1ef6:
+ case 0x1ef8:
+ case 0x0079:
+ case 0x00fd:
+ case 0x00ff:
+ case 0x0177:
+ case 0x0233:
+ case 0x1e8f:
+ case 0x1e99:
+ case 0x1ef3:
+ case 0x1ef7:
+ case 0x1ef9:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0324:
+ switch (p)
+ {
+ case 0x0055:
+ case 0x00d9:
+ case 0x00da:
+ case 0x00db:
+ case 0x00dc:
+ case 0x0168:
+ case 0x016a:
+ case 0x016c:
+ case 0x016e:
+ case 0x0170:
+ case 0x01d3:
+ case 0x01d5:
+ case 0x01d7:
+ case 0x01d9:
+ case 0x01db:
+ case 0x0214:
+ case 0x0216:
+ case 0x1e78:
+ case 0x1e7a:
+ case 0x1ee6:
+ case 0x0075:
+ case 0x00f9:
+ case 0x00fa:
+ case 0x00fb:
+ case 0x00fc:
+ case 0x0169:
+ case 0x016b:
+ case 0x016d:
+ case 0x016f:
+ case 0x0171:
+ case 0x01d4:
+ case 0x01d6:
+ case 0x01d8:
+ case 0x01da:
+ case 0x01dc:
+ case 0x0215:
+ case 0x0217:
+ case 0x1e79:
+ case 0x1e7b:
+ case 0x1ee7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0325:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x00c0:
+ case 0x00c1:
+ case 0x00c2:
+ case 0x00c3:
+ case 0x00c4:
+ case 0x00c5:
+ case 0x0100:
+ case 0x0102:
+ case 0x01cd:
+ case 0x01de:
+ case 0x01e0:
+ case 0x01fa:
+ case 0x0200:
+ case 0x0202:
+ case 0x0226:
+ case 0x1ea2:
+ case 0x1ea4:
+ case 0x1ea6:
+ case 0x1ea8:
+ case 0x1eaa:
+ case 0x1eae:
+ case 0x1eb0:
+ case 0x1eb2:
+ case 0x1eb4:
+ case 0x0061:
+ case 0x00e0:
+ case 0x00e1:
+ case 0x00e2:
+ case 0x00e3:
+ case 0x00e4:
+ case 0x00e5:
+ case 0x0101:
+ case 0x0103:
+ case 0x01ce:
+ case 0x01df:
+ case 0x01e1:
+ case 0x01fb:
+ case 0x0201:
+ case 0x0203:
+ case 0x0227:
+ case 0x1ea3:
+ case 0x1ea5:
+ case 0x1ea7:
+ case 0x1ea9:
+ case 0x1eab:
+ case 0x1eaf:
+ case 0x1eb1:
+ case 0x1eb3:
+ case 0x1eb5:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0326:
+ switch (p)
+ {
+ case 0x0053:
+ case 0x015a:
+ case 0x015c:
+ case 0x0160:
+ case 0x1e60:
+ case 0x1e64:
+ case 0x1e66:
+ case 0x0073:
+ case 0x015b:
+ case 0x015d:
+ case 0x0161:
+ case 0x1e61:
+ case 0x1e65:
+ case 0x1e67:
+ case 0x0054:
+ case 0x0164:
+ case 0x1e6a:
+ case 0x0074:
+ case 0x0165:
+ case 0x1e6b:
+ case 0x1e97:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0327:
+ switch (p)
+ {
+ case 0x0043:
+ case 0x0106:
+ case 0x0108:
+ case 0x010a:
+ case 0x010c:
+ case 0x0063:
+ case 0x0107:
+ case 0x0109:
+ case 0x010b:
+ case 0x010d:
+ case 0x0047:
+ case 0x011c:
+ case 0x011e:
+ case 0x0120:
+ case 0x01e6:
+ case 0x01f4:
+ case 0x1e20:
+ case 0x0067:
+ case 0x011d:
+ case 0x011f:
+ case 0x0121:
+ case 0x01e7:
+ case 0x01f5:
+ case 0x1e21:
+ case 0x004b:
+ case 0x01e8:
+ case 0x1e30:
+ case 0x1e32:
+ case 0x1e34:
+ case 0x006b:
+ case 0x01e9:
+ case 0x1e31:
+ case 0x1e33:
+ case 0x1e35:
+ case 0x004c:
+ case 0x0139:
+ case 0x013d:
+ case 0x1e36:
+ case 0x1e38:
+ case 0x1e3a:
+ case 0x1e3c:
+ case 0x006c:
+ case 0x013a:
+ case 0x013e:
+ case 0x1e37:
+ case 0x1e39:
+ case 0x1e3b:
+ case 0x1e3d:
+ case 0x004e:
+ case 0x00d1:
+ case 0x0143:
+ case 0x0147:
+ case 0x01f8:
+ case 0x1e44:
+ case 0x1e46:
+ case 0x1e48:
+ case 0x1e4a:
+ case 0x006e:
+ case 0x00f1:
+ case 0x0144:
+ case 0x0148:
+ case 0x01f9:
+ case 0x1e45:
+ case 0x1e47:
+ case 0x1e49:
+ case 0x1e4b:
+ case 0x0052:
+ case 0x0154:
+ case 0x0158:
+ case 0x0210:
+ case 0x0212:
+ case 0x1e58:
+ case 0x1e5a:
+ case 0x1e5c:
+ case 0x1e5e:
+ case 0x0072:
+ case 0x0155:
+ case 0x0159:
+ case 0x0211:
+ case 0x0213:
+ case 0x1e59:
+ case 0x1e5b:
+ case 0x1e5d:
+ case 0x1e5f:
+ case 0x0053:
+ case 0x015a:
+ case 0x015c:
+ case 0x0160:
+ case 0x0218:
+ case 0x1e60:
+ case 0x1e62:
+ case 0x1e64:
+ case 0x1e66:
+ case 0x1e68:
+ case 0x0073:
+ case 0x015b:
+ case 0x015d:
+ case 0x0161:
+ case 0x0219:
+ case 0x1e61:
+ case 0x1e63:
+ case 0x1e65:
+ case 0x1e67:
+ case 0x1e69:
+ case 0x0054:
+ case 0x0164:
+ case 0x021a:
+ case 0x1e6a:
+ case 0x1e6c:
+ case 0x1e6e:
+ case 0x1e70:
+ case 0x0074:
+ case 0x0165:
+ case 0x021b:
+ case 0x1e6b:
+ case 0x1e6d:
+ case 0x1e6f:
+ case 0x1e71:
+ case 0x1e97:
+ case 0x0045:
+ case 0x00c8:
+ case 0x00c9:
+ case 0x00ca:
+ case 0x00cb:
+ case 0x0112:
+ case 0x0114:
+ case 0x0116:
+ case 0x011a:
+ case 0x0204:
+ case 0x0206:
+ case 0x1e14:
+ case 0x1e16:
+ case 0x1e18:
+ case 0x1e1a:
+ case 0x1eb8:
+ case 0x1eba:
+ case 0x1ebc:
+ case 0x1ebe:
+ case 0x1ec0:
+ case 0x1ec2:
+ case 0x1ec4:
+ case 0x1ec6:
+ case 0x0065:
+ case 0x00e8:
+ case 0x00e9:
+ case 0x00ea:
+ case 0x00eb:
+ case 0x0113:
+ case 0x0115:
+ case 0x0117:
+ case 0x011b:
+ case 0x0205:
+ case 0x0207:
+ case 0x1e15:
+ case 0x1e17:
+ case 0x1e19:
+ case 0x1e1b:
+ case 0x1eb9:
+ case 0x1ebb:
+ case 0x1ebd:
+ case 0x1ebf:
+ case 0x1ec1:
+ case 0x1ec3:
+ case 0x1ec5:
+ case 0x1ec7:
+ case 0x0044:
+ case 0x010e:
+ case 0x1e0a:
+ case 0x1e0c:
+ case 0x1e0e:
+ case 0x1e12:
+ case 0x0064:
+ case 0x010f:
+ case 0x1e0b:
+ case 0x1e0d:
+ case 0x1e0f:
+ case 0x1e13:
+ case 0x0048:
+ case 0x0124:
+ case 0x021e:
+ case 0x1e22:
+ case 0x1e24:
+ case 0x1e26:
+ case 0x1e2a:
+ case 0x0068:
+ case 0x0125:
+ case 0x021f:
+ case 0x1e23:
+ case 0x1e25:
+ case 0x1e27:
+ case 0x1e2b:
+ case 0x1e96:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0328:
+ switch (p)
+ {
+ case 0x0041:
+ case 0x00c0:
+ case 0x00c1:
+ case 0x00c2:
+ case 0x00c3:
+ case 0x00c4:
+ case 0x00c5:
+ case 0x0100:
+ case 0x0102:
+ case 0x01cd:
+ case 0x01de:
+ case 0x01e0:
+ case 0x01fa:
+ case 0x0200:
+ case 0x0202:
+ case 0x0226:
+ case 0x1e00:
+ case 0x1ea0:
+ case 0x1ea2:
+ case 0x1ea4:
+ case 0x1ea6:
+ case 0x1ea8:
+ case 0x1eaa:
+ case 0x1eac:
+ case 0x1eae:
+ case 0x1eb0:
+ case 0x1eb2:
+ case 0x1eb4:
+ case 0x1eb6:
+ case 0x0061:
+ case 0x00e0:
+ case 0x00e1:
+ case 0x00e2:
+ case 0x00e3:
+ case 0x00e4:
+ case 0x00e5:
+ case 0x0101:
+ case 0x0103:
+ case 0x01ce:
+ case 0x01df:
+ case 0x01e1:
+ case 0x01fb:
+ case 0x0201:
+ case 0x0203:
+ case 0x0227:
+ case 0x1e01:
+ case 0x1ea1:
+ case 0x1ea3:
+ case 0x1ea5:
+ case 0x1ea7:
+ case 0x1ea9:
+ case 0x1eab:
+ case 0x1ead:
+ case 0x1eaf:
+ case 0x1eb1:
+ case 0x1eb3:
+ case 0x1eb5:
+ case 0x1eb7:
+ case 0x0045:
+ case 0x00c8:
+ case 0x00c9:
+ case 0x00ca:
+ case 0x00cb:
+ case 0x0112:
+ case 0x0114:
+ case 0x0116:
+ case 0x011a:
+ case 0x0204:
+ case 0x0206:
+ case 0x1e14:
+ case 0x1e16:
+ case 0x1e18:
+ case 0x1e1a:
+ case 0x1eb8:
+ case 0x1eba:
+ case 0x1ebc:
+ case 0x1ebe:
+ case 0x1ec0:
+ case 0x1ec2:
+ case 0x1ec4:
+ case 0x1ec6:
+ case 0x0065:
+ case 0x00e8:
+ case 0x00e9:
+ case 0x00ea:
+ case 0x00eb:
+ case 0x0113:
+ case 0x0115:
+ case 0x0117:
+ case 0x011b:
+ case 0x0205:
+ case 0x0207:
+ case 0x1e15:
+ case 0x1e17:
+ case 0x1e19:
+ case 0x1e1b:
+ case 0x1eb9:
+ case 0x1ebb:
+ case 0x1ebd:
+ case 0x1ebf:
+ case 0x1ec1:
+ case 0x1ec3:
+ case 0x1ec5:
+ case 0x1ec7:
+ case 0x0049:
+ case 0x00cc:
+ case 0x00cd:
+ case 0x00ce:
+ case 0x00cf:
+ case 0x0128:
+ case 0x012a:
+ case 0x012c:
+ case 0x0130:
+ case 0x01cf:
+ case 0x0208:
+ case 0x020a:
+ case 0x1e2c:
+ case 0x1e2e:
+ case 0x1ec8:
+ case 0x1eca:
+ case 0x0069:
+ case 0x00ec:
+ case 0x00ed:
+ case 0x00ee:
+ case 0x00ef:
+ case 0x0129:
+ case 0x012b:
+ case 0x012d:
+ case 0x01d0:
+ case 0x0209:
+ case 0x020b:
+ case 0x1e2d:
+ case 0x1e2f:
+ case 0x1ec9:
+ case 0x1ecb:
+ case 0x0055:
+ case 0x00d9:
+ case 0x00da:
+ case 0x00db:
+ case 0x00dc:
+ case 0x0168:
+ case 0x016a:
+ case 0x016c:
+ case 0x016e:
+ case 0x0170:
+ case 0x01af:
+ case 0x01d3:
+ case 0x01d5:
+ case 0x01d7:
+ case 0x01d9:
+ case 0x01db:
+ case 0x0214:
+ case 0x0216:
+ case 0x1e72:
+ case 0x1e74:
+ case 0x1e76:
+ case 0x1e78:
+ case 0x1e7a:
+ case 0x1ee4:
+ case 0x1ee6:
+ case 0x1ee8:
+ case 0x1eea:
+ case 0x1eec:
+ case 0x1eee:
+ case 0x1ef0:
+ case 0x0075:
+ case 0x00f9:
+ case 0x00fa:
+ case 0x00fb:
+ case 0x00fc:
+ case 0x0169:
+ case 0x016b:
+ case 0x016d:
+ case 0x016f:
+ case 0x0171:
+ case 0x01b0:
+ case 0x01d4:
+ case 0x01d6:
+ case 0x01d8:
+ case 0x01da:
+ case 0x01dc:
+ case 0x0215:
+ case 0x0217:
+ case 0x1e73:
+ case 0x1e75:
+ case 0x1e77:
+ case 0x1e79:
+ case 0x1e7b:
+ case 0x1ee5:
+ case 0x1ee7:
+ case 0x1ee9:
+ case 0x1eeb:
+ case 0x1eed:
+ case 0x1eef:
+ case 0x1ef1:
+ case 0x004f:
+ case 0x00d2:
+ case 0x00d3:
+ case 0x00d4:
+ case 0x00d5:
+ case 0x00d6:
+ case 0x014c:
+ case 0x014e:
+ case 0x0150:
+ case 0x01a0:
+ case 0x01d1:
+ case 0x020c:
+ case 0x020e:
+ case 0x022a:
+ case 0x022c:
+ case 0x022e:
+ case 0x0230:
+ case 0x1e4c:
+ case 0x1e4e:
+ case 0x1e50:
+ case 0x1e52:
+ case 0x1ecc:
+ case 0x1ece:
+ case 0x1ed0:
+ case 0x1ed2:
+ case 0x1ed4:
+ case 0x1ed6:
+ case 0x1ed8:
+ case 0x1eda:
+ case 0x1edc:
+ case 0x1ede:
+ case 0x1ee0:
+ case 0x1ee2:
+ case 0x006f:
+ case 0x00f2:
+ case 0x00f3:
+ case 0x00f4:
+ case 0x00f5:
+ case 0x00f6:
+ case 0x014d:
+ case 0x014f:
+ case 0x0151:
+ case 0x01a1:
+ case 0x01d2:
+ case 0x020d:
+ case 0x020f:
+ case 0x022b:
+ case 0x022d:
+ case 0x022f:
+ case 0x0231:
+ case 0x1e4d:
+ case 0x1e4f:
+ case 0x1e51:
+ case 0x1e53:
+ case 0x1ecd:
+ case 0x1ecf:
+ case 0x1ed1:
+ case 0x1ed3:
+ case 0x1ed5:
+ case 0x1ed7:
+ case 0x1ed9:
+ case 0x1edb:
+ case 0x1edd:
+ case 0x1edf:
+ case 0x1ee1:
+ case 0x1ee3:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x032d:
+ switch (p)
+ {
+ case 0x0044:
+ case 0x010e:
+ case 0x1e0a:
+ case 0x0064:
+ case 0x010f:
+ case 0x1e0b:
+ case 0x0045:
+ case 0x00c8:
+ case 0x00c9:
+ case 0x00ca:
+ case 0x00cb:
+ case 0x0112:
+ case 0x0114:
+ case 0x0116:
+ case 0x011a:
+ case 0x0204:
+ case 0x0206:
+ case 0x1e14:
+ case 0x1e16:
+ case 0x1eba:
+ case 0x1ebc:
+ case 0x1ebe:
+ case 0x1ec0:
+ case 0x1ec2:
+ case 0x1ec4:
+ case 0x0065:
+ case 0x00e8:
+ case 0x00e9:
+ case 0x00ea:
+ case 0x00eb:
+ case 0x0113:
+ case 0x0115:
+ case 0x0117:
+ case 0x011b:
+ case 0x0205:
+ case 0x0207:
+ case 0x1e15:
+ case 0x1e17:
+ case 0x1ebb:
+ case 0x1ebd:
+ case 0x1ebf:
+ case 0x1ec1:
+ case 0x1ec3:
+ case 0x1ec5:
+ case 0x004c:
+ case 0x0139:
+ case 0x013d:
+ case 0x006c:
+ case 0x013a:
+ case 0x013e:
+ case 0x004e:
+ case 0x00d1:
+ case 0x0143:
+ case 0x0147:
+ case 0x01f8:
+ case 0x1e44:
+ case 0x006e:
+ case 0x00f1:
+ case 0x0144:
+ case 0x0148:
+ case 0x01f9:
+ case 0x1e45:
+ case 0x0054:
+ case 0x0164:
+ case 0x1e6a:
+ case 0x0074:
+ case 0x0165:
+ case 0x1e6b:
+ case 0x1e97:
+ case 0x0055:
+ case 0x00d9:
+ case 0x00da:
+ case 0x00db:
+ case 0x00dc:
+ case 0x0168:
+ case 0x016a:
+ case 0x016c:
+ case 0x016e:
+ case 0x0170:
+ case 0x01d3:
+ case 0x01d5:
+ case 0x01d7:
+ case 0x01d9:
+ case 0x01db:
+ case 0x0214:
+ case 0x0216:
+ case 0x1e78:
+ case 0x1e7a:
+ case 0x1ee6:
+ case 0x0075:
+ case 0x00f9:
+ case 0x00fa:
+ case 0x00fb:
+ case 0x00fc:
+ case 0x0169:
+ case 0x016b:
+ case 0x016d:
+ case 0x016f:
+ case 0x0171:
+ case 0x01d4:
+ case 0x01d6:
+ case 0x01d8:
+ case 0x01da:
+ case 0x01dc:
+ case 0x0215:
+ case 0x0217:
+ case 0x1e79:
+ case 0x1e7b:
+ case 0x1ee7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x032e:
+ switch (p)
+ {
+ case 0x0048:
+ case 0x0124:
+ case 0x021e:
+ case 0x1e22:
+ case 0x1e26:
+ case 0x0068:
+ case 0x0125:
+ case 0x021f:
+ case 0x1e23:
+ case 0x1e27:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0330:
+ switch (p)
+ {
+ case 0x0045:
+ case 0x00c8:
+ case 0x00c9:
+ case 0x00ca:
+ case 0x00cb:
+ case 0x0112:
+ case 0x0114:
+ case 0x0116:
+ case 0x011a:
+ case 0x0204:
+ case 0x0206:
+ case 0x1e14:
+ case 0x1e16:
+ case 0x1eba:
+ case 0x1ebc:
+ case 0x1ebe:
+ case 0x1ec0:
+ case 0x1ec2:
+ case 0x1ec4:
+ case 0x0065:
+ case 0x00e8:
+ case 0x00e9:
+ case 0x00ea:
+ case 0x00eb:
+ case 0x0113:
+ case 0x0115:
+ case 0x0117:
+ case 0x011b:
+ case 0x0205:
+ case 0x0207:
+ case 0x1e15:
+ case 0x1e17:
+ case 0x1ebb:
+ case 0x1ebd:
+ case 0x1ebf:
+ case 0x1ec1:
+ case 0x1ec3:
+ case 0x1ec5:
+ case 0x0049:
+ case 0x00cc:
+ case 0x00cd:
+ case 0x00ce:
+ case 0x00cf:
+ case 0x0128:
+ case 0x012a:
+ case 0x012c:
+ case 0x0130:
+ case 0x01cf:
+ case 0x0208:
+ case 0x020a:
+ case 0x1e2e:
+ case 0x1ec8:
+ case 0x0069:
+ case 0x00ec:
+ case 0x00ed:
+ case 0x00ee:
+ case 0x00ef:
+ case 0x0129:
+ case 0x012b:
+ case 0x012d:
+ case 0x01d0:
+ case 0x0209:
+ case 0x020b:
+ case 0x1e2f:
+ case 0x1ec9:
+ case 0x0055:
+ case 0x00d9:
+ case 0x00da:
+ case 0x00db:
+ case 0x00dc:
+ case 0x0168:
+ case 0x016a:
+ case 0x016c:
+ case 0x016e:
+ case 0x0170:
+ case 0x01d3:
+ case 0x01d5:
+ case 0x01d7:
+ case 0x01d9:
+ case 0x01db:
+ case 0x0214:
+ case 0x0216:
+ case 0x1e78:
+ case 0x1e7a:
+ case 0x1ee6:
+ case 0x0075:
+ case 0x00f9:
+ case 0x00fa:
+ case 0x00fb:
+ case 0x00fc:
+ case 0x0169:
+ case 0x016b:
+ case 0x016d:
+ case 0x016f:
+ case 0x0171:
+ case 0x01d4:
+ case 0x01d6:
+ case 0x01d8:
+ case 0x01da:
+ case 0x01dc:
+ case 0x0215:
+ case 0x0217:
+ case 0x1e79:
+ case 0x1e7b:
+ case 0x1ee7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0331:
+ switch (p)
+ {
+ case 0x0042:
+ case 0x1e02:
+ case 0x0062:
+ case 0x1e03:
+ case 0x0044:
+ case 0x010e:
+ case 0x1e0a:
+ case 0x0064:
+ case 0x010f:
+ case 0x1e0b:
+ case 0x004b:
+ case 0x01e8:
+ case 0x1e30:
+ case 0x006b:
+ case 0x01e9:
+ case 0x1e31:
+ case 0x004c:
+ case 0x0139:
+ case 0x013d:
+ case 0x006c:
+ case 0x013a:
+ case 0x013e:
+ case 0x004e:
+ case 0x00d1:
+ case 0x0143:
+ case 0x0147:
+ case 0x01f8:
+ case 0x1e44:
+ case 0x006e:
+ case 0x00f1:
+ case 0x0144:
+ case 0x0148:
+ case 0x01f9:
+ case 0x1e45:
+ case 0x0052:
+ case 0x0154:
+ case 0x0158:
+ case 0x0210:
+ case 0x0212:
+ case 0x1e58:
+ case 0x0072:
+ case 0x0155:
+ case 0x0159:
+ case 0x0211:
+ case 0x0213:
+ case 0x1e59:
+ case 0x0054:
+ case 0x0164:
+ case 0x1e6a:
+ case 0x0074:
+ case 0x0165:
+ case 0x1e6b:
+ case 0x1e97:
+ case 0x005a:
+ case 0x0179:
+ case 0x017b:
+ case 0x017d:
+ case 0x1e90:
+ case 0x007a:
+ case 0x017a:
+ case 0x017c:
+ case 0x017e:
+ case 0x1e91:
+ case 0x0068:
+ case 0x0125:
+ case 0x021f:
+ case 0x1e23:
+ case 0x1e27:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0338:
+ switch (p)
+ {
+ /* Non-NFC cases not applicable to C/C++. */
+ default:
+ return true;
+ }
+
+ case 0x0342:
+ switch (p)
+ {
+ case 0x1f00:
+ case 0x1f80:
+ case 0x1f01:
+ case 0x1f81:
+ case 0x1f08:
+ case 0x1f88:
+ case 0x1f09:
+ case 0x1f89:
+ case 0x1f20:
+ case 0x1f90:
+ case 0x1f21:
+ case 0x1f91:
+ case 0x1f28:
+ case 0x1f98:
+ case 0x1f29:
+ case 0x1f99:
+ case 0x1f30:
+ case 0x1f31:
+ case 0x1f38:
+ case 0x1f39:
+ case 0x1f50:
+ case 0x1f51:
+ case 0x1f59:
+ case 0x1f60:
+ case 0x1fa0:
+ case 0x1f61:
+ case 0x1fa1:
+ case 0x1f68:
+ case 0x1fa8:
+ case 0x1f69:
+ case 0x1fa9:
+ case 0x03b1:
+ case 0x1fb3:
+ case 0x00a8:
+ case 0x03b7:
+ case 0x1fc3:
+ case 0x1fbf:
+ case 0x03b9:
+ case 0x03ca:
+ case 0x1ffe:
+ case 0x03c5:
+ case 0x03cb:
+ case 0x03c9:
+ case 0x1ff3:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0345:
+ switch (p)
+ {
+ case 0x1f00:
+ case 0x1f01:
+ case 0x1f02:
+ case 0x1f03:
+ case 0x1f04:
+ case 0x1f05:
+ case 0x1f06:
+ case 0x1f07:
+ case 0x1f08:
+ case 0x1f09:
+ case 0x1f0a:
+ case 0x1f0b:
+ case 0x1f0c:
+ case 0x1f0d:
+ case 0x1f0e:
+ case 0x1f0f:
+ case 0x1f20:
+ case 0x1f21:
+ case 0x1f22:
+ case 0x1f23:
+ case 0x1f24:
+ case 0x1f25:
+ case 0x1f26:
+ case 0x1f27:
+ case 0x1f28:
+ case 0x1f29:
+ case 0x1f2a:
+ case 0x1f2b:
+ case 0x1f2c:
+ case 0x1f2d:
+ case 0x1f2e:
+ case 0x1f2f:
+ case 0x1f60:
+ case 0x1f61:
+ case 0x1f62:
+ case 0x1f63:
+ case 0x1f64:
+ case 0x1f65:
+ case 0x1f66:
+ case 0x1f67:
+ case 0x1f68:
+ case 0x1f69:
+ case 0x1f6a:
+ case 0x1f6b:
+ case 0x1f6c:
+ case 0x1f6d:
+ case 0x1f6e:
+ case 0x1f6f:
+ case 0x1f70:
+ case 0x03b1:
+ case 0x03ac:
+ case 0x1fb6:
+ case 0x0391:
+ case 0x1f74:
+ case 0x03b7:
+ case 0x03ae:
+ case 0x1fc6:
+ case 0x0397:
+ case 0x1f7c:
+ case 0x03c9:
+ case 0x03ce:
+ case 0x1ff6:
+ case 0x03a9:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0653:
+ switch (p)
+ {
+ case 0x0627:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0654:
+ switch (p)
+ {
+ case 0x0627:
+ case 0x0648:
+ case 0x064a:
+ case 0x06d5:
+ case 0x06c1:
+ case 0x06d2:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0655:
+ switch (p)
+ {
+ case 0x0627:
+ case 0x0622:
+ case 0x0623:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x093c:
+ switch (p)
+ {
+ case 0x0928:
+ case 0x0930:
+ case 0x0933:
+ case 0x0915:
+ case 0x0916:
+ case 0x0917:
+ case 0x091c:
+ case 0x0921:
+ case 0x0922:
+ case 0x092b:
+ case 0x092f:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x09be:
+ switch (p)
+ {
+ case 0x09c7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x09d7:
+ switch (p)
+ {
+ case 0x09c7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0b3e:
+ switch (p)
+ {
+ case 0x0b47:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0b56:
+ switch (p)
+ {
+ case 0x0b47:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0b57:
+ switch (p)
+ {
+ case 0x0b47:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0bbe:
+ switch (p)
+ {
+ case 0x0bc6:
+ case 0x0bc7:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0bd7:
+ switch (p)
+ {
+ case 0x0b92:
+ case 0x0bc6:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0c56:
+ switch (p)
+ {
+ case 0x0c46:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0cc2:
+ switch (p)
+ {
+ case 0x0cc6:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0cd5:
+ switch (p)
+ {
+ case 0x0cbf:
+ case 0x0cc6:
+ case 0x0cca:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0cd6:
+ switch (p)
+ {
+ case 0x0cc6:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0d3e:
+ switch (p)
+ {
+ case 0x0d46:
+ case 0x0d47:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0d57:
+ switch (p)
+ {
+ case 0x0d46:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0dca:
+ switch (p)
+ {
+ case 0x0dd9:
+ case 0x0ddc:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0dcf:
+ switch (p)
+ {
+ case 0x0dd9:
+ case 0x0dda:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x0ddf:
+ switch (p)
+ {
+ case 0x0dd9:
+ case 0x0dda:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x102e:
+ switch (p)
+ {
+ case 0x1025:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x1b35:
+ switch (p)
+ {
+ case 0x1b05:
+ case 0x1b07:
+ case 0x1b09:
+ case 0x1b0b:
+ case 0x1b0d:
+ case 0x1b11:
+ case 0x1b3a:
+ case 0x1b3c:
+ case 0x1b3e:
+ case 0x1b3f:
+ case 0x1b42:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x3099:
+ switch (p)
+ {
+ case 0x304b:
+ case 0x304d:
+ case 0x304f:
+ case 0x3051:
+ case 0x3053:
+ case 0x3055:
+ case 0x3057:
+ case 0x3059:
+ case 0x305b:
+ case 0x305d:
+ case 0x305f:
+ case 0x3061:
+ case 0x3064:
+ case 0x3066:
+ case 0x3068:
+ case 0x306f:
+ case 0x3072:
+ case 0x3075:
+ case 0x3078:
+ case 0x307b:
+ case 0x3046:
+ case 0x309d:
+ case 0x30ab:
+ case 0x30ad:
+ case 0x30af:
+ case 0x30b1:
+ case 0x30b3:
+ case 0x30b5:
+ case 0x30b7:
+ case 0x30b9:
+ case 0x30bb:
+ case 0x30bd:
+ case 0x30bf:
+ case 0x30c1:
+ case 0x30c4:
+ case 0x30c6:
+ case 0x30c8:
+ case 0x30cf:
+ case 0x30d2:
+ case 0x30d5:
+ case 0x30d8:
+ case 0x30db:
+ case 0x30a6:
+ case 0x30ef:
+ case 0x30f0:
+ case 0x30f1:
+ case 0x30f2:
+ case 0x30fd:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x309a:
+ switch (p)
+ {
+ case 0x306f:
+ case 0x3072:
+ case 0x3075:
+ case 0x3078:
+ case 0x307b:
+ case 0x30cf:
+ case 0x30d2:
+ case 0x30d5:
+ case 0x30d8:
+ case 0x30db:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x110ba:
+ switch (p)
+ {
+ case 0x11099:
+ case 0x1109b:
+ case 0x110a5:
+ return false;
+ default:
+ return true;
+ }
+
+ case 0x11127:
+ switch (p)
+ {
+ case 0x11131:
+ case 0x11132:
+ return false;
+ default:
+ return true;
+ }
+
+ default:
+ cpp_error (pfile, CPP_DL_ICE, "Character %x might not be NFKC", c);
+ return true;
+ }
+}
diff --git a/libcpp/ucnid.tab b/libcpp/ucnid.tab
index ea228826123..68d9e068b31 100644
--- a/libcpp/ucnid.tab
+++ b/libcpp/ucnid.tab
@@ -19,7 +19,8 @@
; D, which is itself a reproduction from ISO/IEC TR 10176:1998, and
; the similar table from ISO/IEC 14882:1988 (C++98) Annex E, which is
; a reproduction of ISO/IEC PDTR 10176. Unfortunately these tables
-; are not identical.
+; are not identical. It also reproduces the somewhat different tables
+; in C11 and C++11, which are identical to each other.
[C99]
@@ -119,7 +120,7 @@ ac00-d7a3
0b3d 1fbe 203f-2040 2102 2107 210a-2113 2115 2118-211d 2124 2126 2128
212a-2131 2133-2138 2160-2182 3005-3007 3021-3029
-; Digits
+[C99DIG]
0660-0669 06f0-06f9 0966-096f 09e6-09ef 0a66-0a6f 0ae6-0aef 0b66-0b6f
0be7-0bef 0c66-0c6f 0ce6-0cef 0d66-0d6f 0e50-0e59 0ed0-0ed9 0f20-0f33
@@ -209,3 +210,34 @@ fbd3-fd3f fd50-fd8f fd92-fdc7 fdf0-fdfb fe70-fe72 fe74 fe76-fefc
ff21-ff3a ff41-ff5a ff66-ffbe ffc2-ffc7 ffca-ffcf ffd2-ffd7
ffda-ffdc 4e00-9fa5
+[C11]
+; Group 1
+00a8 00aa 00ad 00af 00b2-00b5 00b7-00ba 00bc-00be 00c0-00d6 00d8-00f6
+00f8-00ff
+
+; Group 2, minus characters under C11NOSTART
+0100-02ff 0370-167f 1681-180d 180f-1dbf 1e00-1fff
+
+; Group 3
+200b-200d 202a-202e 203f-2040 2054 2060-206f
+
+; Group 4, minus characters under C11NOSTART
+2070-20cf 2100-218f 2460-24ff 2776-2793 2c00-2dff 2e80-2fff
+
+; Group 5
+3004-3007 3021-302f 3031-303f
+
+; Group 6
+3040-d7ff
+
+; Group 7, minus characters under C11NOSTART
+f900-fd3d fd40-fdcf fdf0-fe1f fe30-fe44 fe47-fffd
+
+; Group 8
+10000-1fffd 20000-2fffd 30000-3fffd 40000-4fffd 50000-5fffd
+60000-6fffd 70000-7fffd 80000-8fffd 90000-9fffd a0000-afffd
+b0000-bfffd c0000-cfffd d0000-dfffd e0000-efffd
+
+[C11NOSTART]
+; Group 1
+0300-036f 1dc0-1dff 20d0-20ff fe20-fe2f
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 0bfba640e21..311cd23a57a 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,52 @@
+2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ * configure: Regenerate.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/linux-unwind.h (TOC_SAVE_SLOT): Define.
+ (frob_update_context): Use it.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/tramp.S [__powerpc64__ && _CALL_ELF == 2]:
+ (trampoline_initial): Provide ELFv2 variant.
+ (__trampoline_setup): Likewise.
+
+ * config/rs6000/linux-unwind.h (frob_update_context): Do not
+ check for AIX indirect function call sequence if _CALL_ELF == 2.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/linux-unwind.h (get_regs): Do not support
+ old kernel versions if _CALL_ELF == 2.
+ (frob_update_context): Do not support PLT stub variants only
+ generated by old linkers if _CALL_ELF == 2.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Correct
+ location of CR save area for 64-bit little-endian systems.
+
+2013-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config.host (arm-wrs-vxworks): Replace arm/t-vxworks with arm/t-elf
+ in tmake_file.
+ * config/arm/t-vxworks: Delete.
+
+2013-11-10 Kai Tietz <ktietz@redhat.com>
+
+ * config/i386/cygming-crtbegin.c (__gcc_register_frame):
+ Increment load-count on use of LIBGCC_SONAME DLL.
+ (hmod_libgcc): New static variable to hold handle of
+ LIBGCC_SONAME DLL.
+ (__gcc_deregister_frame): Decrement load-count of
+ LIBGCC_SONAME DLL.
+
2013-11-08 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
* configure.ac (libgcc_cv_dfp): Extend check to probe fenv.h
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 354fb72d984..f040bad6e5b 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -852,18 +852,31 @@ include $(iterator)
# Build libgcov components.
-# Defined in libgcov.c, included only in gcov library
-LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \
- _gcov_fork _gcov_execl _gcov_execlp _gcov_execle \
- _gcov_execv _gcov_execvp _gcov_execve _gcov_reset _gcov_dump \
- _gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \
+LIBGCOV_MERGE = _gcov_merge_add _gcov_merge_single _gcov_merge_delta _gcov_merge_ior \
+ _gcov_merge_time_profile
+LIBGCOV_PROFILER = _gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \
_gcov_indirect_call_profiler _gcov_average_profiler _gcov_ior_profiler \
- _gcov_merge_ior _gcov_indirect_call_profiler_v2
-
-libgcov-objects = $(patsubst %,%$(objext),$(LIBGCOV))
-
-$(libgcov-objects): %$(objext): $(srcdir)/libgcov.c
- $(gcc_compile) -DL$* -c $(srcdir)/libgcov.c
+ _gcov_indirect_call_profiler_v2 _gcov_time_profiler
+LIBGCOV_INTERFACE = _gcov_flush _gcov_fork _gcov_execl _gcov_execlp _gcov_execle \
+ _gcov_execv _gcov_execvp _gcov_execve _gcov_reset _gcov_dump
+LIBGCOV_DRIVER = _gcov
+
+libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE))
+libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER))
+libgcov-interface-objects = $(patsubst %,%$(objext),$(LIBGCOV_INTERFACE))
+libgcov-driver-objects = $(patsubst %,%$(objext),$(LIBGCOV_DRIVER))
+libgcov-objects = $(libgcov-merge-objects) $(libgcov-profiler-objects) \
+ $(libgcov-interface-objects) $(libgcov-driver-objects)
+
+$(libgcov-merge-objects): %$(objext): $(srcdir)/libgcov-merge.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-merge.c
+$(libgcov-profiler-objects): %$(objext): $(srcdir)/libgcov-profiler.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-profiler.c
+$(libgcov-interface-objects): %$(objext): $(srcdir)/libgcov-interface.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-interface.c
+$(libgcov-driver-objects): %$(objext): $(srcdir)/libgcov-driver.c \
+ $(srcdir)/libgcov-driver-system.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-driver.c
# Static libraries.
diff --git a/libgcc/config.host b/libgcc/config.host
index 325ed84ad90..8feb8f2bd04 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -333,7 +333,7 @@ arc*-*-linux-uclibc*)
extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o libgmon.a crtg.o crtgend.o"
;;
arm-wrs-vxworks)
- tmake_file="$tmake_file arm/t-arm arm/t-vxworks t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
+ 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*-*-netbsdelf*)
diff --git a/libgcc/config/arm/t-vxworks b/libgcc/config/arm/t-vxworks
deleted file mode 100644
index 9db1f1602bc..00000000000
--- a/libgcc/config/arm/t-vxworks
+++ /dev/null
@@ -1 +0,0 @@
-LIB1ASMFUNCS += _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX _clzsi2 _clzdi2 _ctzsi2
diff --git a/libgcc/config/i386/cygming-crtbegin.c b/libgcc/config/i386/cygming-crtbegin.c
index c34178787c8..53909d2dc14 100644
--- a/libgcc/config/i386/cygming-crtbegin.c
+++ b/libgcc/config/i386/cygming-crtbegin.c
@@ -91,6 +91,9 @@ static EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
= { };
static struct object obj;
+
+/* Handle of libgcc's DLL reference. */
+HANDLE hmod_libgcc;
#endif
#if TARGET_USE_JCR_SECTION
@@ -115,9 +118,14 @@ __gcc_register_frame (void)
void (*register_frame_fn) (const void *, struct object *);
HANDLE h = GetModuleHandle (LIBGCC_SONAME);
+
if (h)
- register_frame_fn = (void (*) (const void *, struct object *))
- GetProcAddress (h, "__register_frame_info");
+ {
+ /* Increasing the load-count of LIBGCC_SONAME DLL. */
+ hmod_libgcc = LoadLibrary (LIBGCC_SONAME);
+ register_frame_fn = (void (*) (const void *, struct object *))
+ GetProcAddress (h, "__register_frame_info");
+ }
else
register_frame_fn = __register_frame_info;
if (register_frame_fn)
@@ -154,5 +162,7 @@ __gcc_deregister_frame (void)
deregister_frame_fn = __deregister_frame_info;
if (deregister_frame_fn)
deregister_frame_fn (__EH_FRAME_BEGIN__);
+ if (hmod_libgcc)
+ FreeLibrary (hmod_libgcc);
#endif
}
diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
index c9273c404e2..a421b158216 100644
--- a/libgcc/config/rs6000/linux-unwind.h
+++ b/libgcc/config/rs6000/linux-unwind.h
@@ -24,9 +24,19 @@
#define R_LR 65
#define R_CR2 70
+#define R_CR3 71
+#define R_CR4 72
#define R_VR0 77
#define R_VRSAVE 109
+#ifdef __powerpc64__
+#if _CALL_ELF == 2
+#define TOC_SAVE_SLOT 24
+#else
+#define TOC_SAVE_SLOT 40
+#endif
+#endif
+
struct gcc_vregs
{
__attribute__ ((vector_size (16))) int vr[32];
@@ -107,6 +117,8 @@ get_regs (struct _Unwind_Context *context)
}
else if (pc[1] == 0x380000AC)
{
+#if _CALL_ELF != 2
+ /* These old kernel versions never supported ELFv2. */
/* This works for 2.4 kernels, but not for 2.6 kernels with vdso
because pc isn't pointing into the stack. Can be removed when
no one is running 2.4.19 or 2.4.20, the first two ppc64
@@ -121,6 +133,7 @@ get_regs (struct _Unwind_Context *context)
if ((long) frame24->puc != -21 * 8)
return frame24->puc->regs;
else
+#endif
{
/* This works for 2.4.21 and later kernels. */
struct rt_sigframe {
@@ -185,6 +198,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
{
struct gcc_regs *regs = get_regs (context);
struct gcc_vregs *vregs;
+ long cr_offset;
long new_cfa;
int i;
@@ -206,11 +220,21 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[i].loc.offset = (long) &regs->gpr[i] - new_cfa;
}
+ /* The CR is saved in the low 32 bits of regs->ccr. */
+ cr_offset = (long) &regs->ccr - new_cfa;
+#ifndef __LITTLE_ENDIAN__
+ cr_offset += sizeof (long) - 4;
+#endif
+ /* In the ELFv1 ABI, CR2 stands in for the whole CR. */
fs->regs.reg[R_CR2].how = REG_SAVED_OFFSET;
- /* CR? regs are always 32-bit and PPC is big-endian, so in 64-bit
- libgcc loc.offset needs to point to the low 32 bits of regs->ccr. */
- fs->regs.reg[R_CR2].loc.offset = (long) &regs->ccr - new_cfa
- + sizeof (long) - 4;
+ fs->regs.reg[R_CR2].loc.offset = cr_offset;
+#if _CALL_ELF == 2
+ /* In the ELFv2 ABI, every CR field has a separate CFI entry. */
+ fs->regs.reg[R_CR3].how = REG_SAVED_OFFSET;
+ fs->regs.reg[R_CR3].loc.offset = cr_offset;
+ fs->regs.reg[R_CR4].how = REG_SAVED_OFFSET;
+ fs->regs.reg[R_CR4].loc.offset = cr_offset;
+#endif
fs->regs.reg[R_LR].how = REG_SAVED_OFFSET;
fs->regs.reg[R_LR].loc.offset = (long) &regs->link - new_cfa;
@@ -294,9 +318,13 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
- if (pc[0] == 0xF8410028
+ if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
+#if _CALL_ELF != 2
+ /* The ELFv2 linker never generates the old PLT stub form. */
|| ((pc[0] & 0xFFFF0000) == 0x3D820000
- && pc[1] == 0xF8410028))
+ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
+#endif
+ )
{
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
@@ -305,18 +333,21 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
- if (insn && *insn == 0xE8410028)
- _Unwind_SetGRPtr (context, 2, context->cfa + 40);
+ if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
+ _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
+#if _CALL_ELF != 2
+ /* ELFv2 does not use this function pointer call sequence. */
else if (pc[0] == 0x4E800421
- && pc[1] == 0xE8410028)
+ && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
{
/* We are at the bctrl instruction in a call via function
pointer. gcc always emits the load of the new R2 just
before the bctrl so this is the first and only place
we need to use the stored R2. */
_Unwind_Word sp = _Unwind_GetGR (context, 1);
- _Unwind_SetGRPtr (context, 2, (void *)(sp + 40));
+ _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
}
+#endif
}
}
#endif
diff --git a/libgcc/config/rs6000/tramp.S b/libgcc/config/rs6000/tramp.S
index 14cb18de2fe..fe2a4543b67 100644
--- a/libgcc/config/rs6000/tramp.S
+++ b/libgcc/config/rs6000/tramp.S
@@ -116,4 +116,70 @@ FUNC_END(__trampoline_setup)
#endif
+#elif _CALL_ELF == 2
+ .type trampoline_initial,@object
+ .align 3
+trampoline_initial:
+ ld r11,.Lchain(r12)
+ ld r12,.Lfunc(r12)
+ mtctr r12
+ bctr
+.Lfunc = .-trampoline_initial
+ .quad 0 /* will be replaced with function address */
+.Lchain = .-trampoline_initial
+ .quad 0 /* will be replaced with static chain */
+
+trampoline_size = .-trampoline_initial
+ .size trampoline_initial,trampoline_size
+
+
+/* R3 = stack address to store trampoline */
+/* R4 = length of trampoline area */
+/* R5 = function address */
+/* R6 = static chain */
+
+ .pushsection ".toc","aw"
+.LC0:
+ .quad trampoline_initial-8
+ .popsection
+
+FUNC_START(__trampoline_setup)
+ addis 7,2,.LC0@toc@ha
+ ld 7,.LC0@toc@l(7) /* trampoline address -8 */
+
+ li r8,trampoline_size /* verify that the trampoline is big enough */
+ cmpw cr1,r8,r4
+ srwi r4,r4,3 /* # doublewords to move */
+ addi r9,r3,-8 /* adjust pointer for stdu */
+ mtctr r4
+ blt cr1,.Labort
+
+ /* Copy the instructions to the stack */
+.Lmove:
+ ldu r10,8(r7)
+ stdu r10,8(r9)
+ bdnz .Lmove
+
+ /* Store correct function and static chain */
+ std r5,.Lfunc(r3)
+ std r6,.Lchain(r3)
+
+ /* Now flush both caches */
+ mtctr r4
+.Lcache:
+ icbi 0,r3
+ dcbf 0,r3
+ addi r3,r3,8
+ bdnz .Lcache
+
+ /* Finally synchronize things & return */
+ sync
+ isync
+ blr
+
+.Labort:
+ bl JUMP_TARGET(abort)
+ nop
+FUNC_END(__trampoline_setup)
+
#endif
diff --git a/libgcc/configure b/libgcc/configure
index 2bb1fb2d94f..7e177edb288 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -2277,9 +2277,6 @@ case "${host}" in
i[34567]86-*-* | x86_64-*-*)
PICFLAG=-fpic
;;
- m68k-*-*)
- PICFLAG=-fpic
- ;;
# FIXME: Override -fPIC default in libgcc only?
sh-*-linux* | sh[2346lbe]*-*-linux*)
PICFLAG=-fpic
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
new file mode 100644
index 00000000000..5605d057475
--- /dev/null
+++ b/libgcc/libgcov-driver-system.c
@@ -0,0 +1,203 @@
+/* Routines required for instrumenting a program. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* A utility function for outputing errors. */
+
+static int __attribute__((format(printf, 1, 2)))
+gcov_error (const char *fmt, ...)
+{
+ int ret;
+ va_list argp;
+ va_start (argp, fmt);
+ ret = vfprintf (stderr, fmt, argp);
+ va_end (argp);
+ return ret;
+}
+
+/* Make sure path component of the given FILENAME exists, create
+ missing directories. FILENAME must be writable.
+ Returns zero on success, or -1 if an error occurred. */
+
+static int
+create_file_directory (char *filename)
+{
+#if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
+ (void) filename;
+ return -1;
+#else
+ char *s;
+
+ s = filename;
+
+ if (HAS_DRIVE_SPEC(s))
+ s += 2;
+ if (IS_DIR_SEPARATOR(*s))
+ ++s;
+ for (; *s != '\0'; s++)
+ if (IS_DIR_SEPARATOR(*s))
+ {
+ char sep = *s;
+ *s = '\0';
+
+ /* Try to make directory if it doesn't already exist. */
+ if (access (filename, F_OK) == -1
+#ifdef TARGET_POSIX_IO
+ && mkdir (filename, 0755) == -1
+#else
+ && mkdir (filename) == -1
+#endif
+ /* The directory might have been made by another process. */
+ && errno != EEXIST)
+ {
+ gcov_error ("profiling:%s:Cannot create directory\n", filename);
+ *s = sep;
+ return -1;
+ };
+
+ *s = sep;
+ };
+ return 0;
+#endif
+}
+
+static void
+allocate_filename_struct (struct gcov_filename_aux *gf)
+{
+ const char *gcov_prefix;
+ int gcov_prefix_strip = 0;
+ size_t prefix_length;
+ char *gi_filename_up;
+
+ gcc_assert (gf);
+ {
+ /* Check if the level of dirs to strip off specified. */
+ char *tmp = getenv("GCOV_PREFIX_STRIP");
+ if (tmp)
+ {
+ gcov_prefix_strip = atoi (tmp);
+ /* Do not consider negative values. */
+ if (gcov_prefix_strip < 0)
+ gcov_prefix_strip = 0;
+ }
+ }
+
+ /* Get file name relocation prefix. Non-absolute values are ignored. */
+ gcov_prefix = getenv("GCOV_PREFIX");
+ if (gcov_prefix)
+ {
+ prefix_length = strlen(gcov_prefix);
+
+ /* Remove an unnecessary trailing '/' */
+ if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
+ prefix_length--;
+ }
+ else
+ prefix_length = 0;
+
+ /* If no prefix was specified and a prefix stip, then we assume
+ relative. */
+ if (gcov_prefix_strip != 0 && prefix_length == 0)
+ {
+ gcov_prefix = ".";
+ prefix_length = 1;
+ }
+ /* Allocate and initialize the filename scratch space plus one. */
+ gi_filename = (char *) malloc (prefix_length + gcov_max_filename + 2);
+ if (prefix_length)
+ memcpy (gi_filename, gcov_prefix, prefix_length);
+ gi_filename_up = gi_filename + prefix_length;
+
+ gf->gi_filename_up = gi_filename_up;
+ gf->prefix_length = prefix_length;
+ gf->gcov_prefix_strip = gcov_prefix_strip;
+}
+
+/* Open a gcda file specified by GI_FILENAME.
+ Return -1 on error. Return 0 on success. */
+
+static int
+gcov_exit_open_gcda_file (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf)
+{
+ int gcov_prefix_strip;
+ size_t prefix_length;
+ char *gi_filename_up;
+ const char *fname, *s;
+
+ gcov_prefix_strip = gf->gcov_prefix_strip;
+ gi_filename_up = gf->gi_filename_up;
+ prefix_length = gf->prefix_length;
+ fname = gi_ptr->filename;
+
+ /* Avoid to add multiple drive letters into combined path. */
+ if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
+ fname += 2;
+
+ /* Build relocated filename, stripping off leading
+ directories from the initial filename if requested. */
+ if (gcov_prefix_strip > 0)
+ {
+ int level = 0;
+
+ s = fname;
+ if (IS_DIR_SEPARATOR(*s))
+ ++s;
+
+ /* Skip selected directory levels. */
+ for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
+ if (IS_DIR_SEPARATOR(*s))
+ {
+ fname = s;
+ level++;
+ }
+ }
+
+ /* Update complete filename with stripped original. */
+ if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
+ {
+ /* If prefix is given, add directory separator. */
+ strcpy (gi_filename_up, "/");
+ strcpy (gi_filename_up + 1, fname);
+ }
+ else
+ strcpy (gi_filename_up, fname);
+
+ if (!gcov_open (gi_filename))
+ {
+ /* Open failed likely due to missed directory.
+ Create directory and retry to open file. */
+ if (create_file_directory (gi_filename))
+ {
+ fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
+ return -1;
+ }
+ if (!gcov_open (gi_filename))
+ {
+ fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
new file mode 100644
index 00000000000..93bf2fb7ace
--- /dev/null
+++ b/libgcc/libgcov-driver.c
@@ -0,0 +1,872 @@
+/* Routines required for instrumenting a program. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+
+#if defined(inhibit_libc)
+#define IN_LIBGCOV (-1)
+#else
+#define IN_LIBGCOV 1
+#if defined(L_gcov)
+#define GCOV_LINKAGE /* nothing */
+#endif
+#endif
+#include "gcov-io.h"
+
+#if defined(inhibit_libc)
+/* If libc and its header files are not available, provide dummy functions. */
+
+#if defined(L_gcov)
+void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
+#endif
+
+#else /* inhibit_libc */
+
+#include <string.h>
+#if GCOV_LOCKED
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#endif
+
+#ifdef L_gcov
+#include "gcov-io.c"
+
+/* The following functions can be called from outside of this file. */
+extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
+extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
+extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
+extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
+extern int get_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
+extern void set_gcov_list (struct gcov_info *) ATTRIBUTE_HIDDEN;
+
+struct gcov_fn_buffer
+{
+ struct gcov_fn_buffer *next;
+ unsigned fn_ix;
+ struct gcov_fn_info info;
+ /* note gcov_fn_info ends in a trailing array. */
+};
+
+struct gcov_summary_buffer
+{
+ struct gcov_summary_buffer *next;
+ struct gcov_summary summary;
+};
+
+/* Chain of per-object gcov structures. */
+static struct gcov_info *gcov_list;
+
+/* Set the head of gcov_list. */
+void
+set_gcov_list (struct gcov_info *head)
+{
+ gcov_list = head;
+}
+
+/* Size of the longest file name. */
+static size_t gcov_max_filename = 0;
+
+/* Flag when the profile has already been dumped via __gcov_dump(). */
+static int gcov_dump_complete;
+
+/* A global functino that get the vaule of gcov_dump_complete. */
+
+int
+get_gcov_dump_complete (void)
+{
+ return gcov_dump_complete;
+}
+
+/* A global functino that set the vaule of gcov_dump_complete. Will
+ be used in __gcov_dump() in libgcov-interface.c. */
+
+void
+set_gcov_dump_complete (void)
+{
+ gcov_dump_complete = 1;
+}
+
+/* A global functino that set the vaule of gcov_dump_complete. Will
+ be used in __gcov_reset() in libgcov-interface.c. */
+
+void
+reset_gcov_dump_complete (void)
+{
+ gcov_dump_complete = 0;
+}
+
+/* A utility function for outputing errors. */
+static int gcov_error (const char *, ...);
+
+static struct gcov_fn_buffer *
+free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
+ unsigned limit)
+{
+ struct gcov_fn_buffer *next;
+ unsigned ix, n_ctr = 0;
+
+ if (!buffer)
+ return 0;
+ next = buffer->next;
+
+ for (ix = 0; ix != limit; ix++)
+ if (gi_ptr->merge[ix])
+ free (buffer->info.ctrs[n_ctr++].values);
+ free (buffer);
+ return next;
+}
+
+static struct gcov_fn_buffer **
+buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
+ struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
+{
+ unsigned n_ctrs = 0, ix = 0;
+ struct gcov_fn_buffer *fn_buffer;
+ unsigned len;
+
+ for (ix = GCOV_COUNTERS; ix--;)
+ if (gi_ptr->merge[ix])
+ n_ctrs++;
+
+ len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
+ fn_buffer = (struct gcov_fn_buffer *)malloc (len);
+
+ if (!fn_buffer)
+ goto fail;
+
+ fn_buffer->next = 0;
+ fn_buffer->fn_ix = fn_ix;
+ fn_buffer->info.ident = gcov_read_unsigned ();
+ fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
+ fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
+
+ for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
+ {
+ gcov_unsigned_t length;
+ gcov_type *values;
+
+ if (!gi_ptr->merge[ix])
+ continue;
+
+ if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
+ {
+ len = 0;
+ goto fail;
+ }
+
+ length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
+ len = length * sizeof (gcov_type);
+ values = (gcov_type *)malloc (len);
+ if (!values)
+ goto fail;
+
+ fn_buffer->info.ctrs[n_ctrs].num = length;
+ fn_buffer->info.ctrs[n_ctrs].values = values;
+
+ while (length--)
+ *values++ = gcov_read_counter ();
+ n_ctrs++;
+ }
+
+ *end_ptr = fn_buffer;
+ return &fn_buffer->next;
+
+fail:
+ gcov_error ("profiling:%s:Function %u %s %u \n", filename, fn_ix,
+ len ? "cannot allocate" : "counter mismatch", len ? len : ix);
+
+ return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
+}
+
+/* Add an unsigned value to the current crc */
+
+static gcov_unsigned_t
+crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
+{
+ unsigned ix;
+
+ for (ix = 32; ix--; value <<= 1)
+ {
+ unsigned feedback;
+
+ feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
+ crc32 <<= 1;
+ crc32 ^= feedback;
+ }
+
+ return crc32;
+}
+
+/* Check if VERSION of the info block PTR matches libgcov one.
+ Return 1 on success, or zero in case of versions mismatch.
+ If FILENAME is not NULL, its value used for reporting purposes
+ instead of value from the info block. */
+
+static int
+gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
+ const char *filename)
+{
+ if (version != GCOV_VERSION)
+ {
+ char v[4], e[4];
+
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+
+ gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
+ filename? filename : ptr->filename, e, v);
+ return 0;
+ }
+ return 1;
+}
+
+/* Insert counter VALUE into HISTOGRAM. */
+
+static void
+gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
+{
+ unsigned i;
+
+ i = gcov_histo_index(value);
+ histogram[i].num_counters++;
+ histogram[i].cum_value += value;
+ if (value < histogram[i].min_value)
+ histogram[i].min_value = value;
+}
+
+/* Computes a histogram of the arc counters to place in the summary SUM. */
+
+static void
+gcov_compute_histogram (struct gcov_summary *sum)
+{
+ struct gcov_info *gi_ptr;
+ const struct gcov_fn_info *gfi_ptr;
+ const struct gcov_ctr_info *ci_ptr;
+ struct gcov_ctr_summary *cs_ptr;
+ unsigned t_ix, f_ix, ctr_info_ix, ix;
+ int h_ix;
+
+ /* This currently only applies to arc counters. */
+ t_ix = GCOV_COUNTER_ARCS;
+
+ /* First check if there are any counts recorded for this counter. */
+ cs_ptr = &(sum->ctrs[t_ix]);
+ if (!cs_ptr->num)
+ return;
+
+ for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
+ {
+ cs_ptr->histogram[h_ix].num_counters = 0;
+ cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
+ cs_ptr->histogram[h_ix].cum_value = 0;
+ }
+
+ /* Walk through all the per-object structures and record each of
+ the count values in histogram. */
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ if (!gi_ptr->merge[t_ix])
+ continue;
+
+ /* Find the appropriate index into the gcov_ctr_info array
+ for the counter we are currently working on based on the
+ existence of the merge function pointer for this object. */
+ for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
+ {
+ if (gi_ptr->merge[ix])
+ ctr_info_ix++;
+ }
+ for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
+ {
+ gfi_ptr = gi_ptr->functions[f_ix];
+
+ if (!gfi_ptr || gfi_ptr->key != gi_ptr)
+ continue;
+
+ ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
+ for (ix = 0; ix < ci_ptr->num; ix++)
+ gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
+ }
+ }
+}
+
+/* summary for program. */
+static struct gcov_summary this_prg;
+#if !GCOV_LOCKED
+/* summary for all instances of program. */
+static struct gcov_summary all_prg;
+#endif
+/* crc32 for this program. */
+static gcov_unsigned_t crc32;
+/* gcda filename. */
+static char *gi_filename;
+/* buffer for the fn_data from another program. */
+static struct gcov_fn_buffer *fn_buffer;
+/* buffer for summary from other programs to be written out. */
+static struct gcov_summary_buffer *sum_buffer;
+
+/* This funtions computes the program level summary and the histo-gram.
+ It initializes ALL_PRG, computes CRC32, and stores the summary in
+ THIS_PRG. All these three variables are file statics. */
+
+static void
+gcov_exit_compute_summary (void)
+{
+ struct gcov_info *gi_ptr;
+ const struct gcov_fn_info *gfi_ptr;
+ struct gcov_ctr_summary *cs_ptr;
+ const struct gcov_ctr_info *ci_ptr;
+ int f_ix;
+ unsigned t_ix;
+ gcov_unsigned_t c_num;
+
+#if !GCOV_LOCKED
+ memset (&all_prg, 0, sizeof (all_prg));
+#endif
+ /* Find the totals for this execution. */
+ memset (&this_prg, 0, sizeof (this_prg));
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
+ crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
+
+ for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
+ {
+ gfi_ptr = gi_ptr->functions[f_ix];
+
+ if (gfi_ptr && gfi_ptr->key != gi_ptr)
+ gfi_ptr = 0;
+
+ crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
+ crc32 = crc32_unsigned (crc32,
+ gfi_ptr ? gfi_ptr->lineno_checksum : 0);
+ if (!gfi_ptr)
+ continue;
+
+ ci_ptr = gfi_ptr->ctrs;
+ for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
+ {
+ if (!gi_ptr->merge[t_ix])
+ continue;
+
+ cs_ptr = &this_prg.ctrs[t_ix];
+ cs_ptr->num += ci_ptr->num;
+ crc32 = crc32_unsigned (crc32, ci_ptr->num);
+
+ for (c_num = 0; c_num < ci_ptr->num; c_num++)
+ {
+ cs_ptr->sum_all += ci_ptr->values[c_num];
+ if (cs_ptr->run_max < ci_ptr->values[c_num])
+ cs_ptr->run_max = ci_ptr->values[c_num];
+ }
+ ci_ptr++;
+ }
+ }
+ }
+ gcov_compute_histogram (&this_prg);
+}
+
+/* A struct that bundles all the related information about the
+ gcda filename. */
+struct gcov_filename_aux{
+ char *gi_filename_up;
+ int gcov_prefix_strip;
+ size_t prefix_length;
+};
+
+/* Including system dependent components. */
+#include "libgcov-driver-system.c"
+
+/* This function merges counters in GI_PTR to an existing gcda file.
+ Return 0 on success.
+ Return -1 on error. In this case, caller will goto read_fatal. */
+
+static int
+gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
+ struct gcov_summary *prg_p,
+ gcov_position_t *summary_pos_p,
+ gcov_position_t *eof_pos_p)
+{
+ gcov_unsigned_t tag, length;
+ unsigned t_ix;
+ int f_ix;
+ int error = 0;
+ struct gcov_fn_buffer **fn_tail = &fn_buffer;
+ struct gcov_summary_buffer **sum_tail = &sum_buffer;
+
+ length = gcov_read_unsigned ();
+ if (!gcov_version (gi_ptr, length, gi_filename))
+ return -1;
+
+ length = gcov_read_unsigned ();
+ if (length != gi_ptr->stamp)
+ /* Read from a different compilation. Overwrite the file. */
+ return 0;
+
+ /* Look for program summary. */
+ for (f_ix = 0;;)
+ {
+ struct gcov_summary tmp;
+
+ *eof_pos_p = gcov_position ();
+ tag = gcov_read_unsigned ();
+ if (tag != GCOV_TAG_PROGRAM_SUMMARY)
+ break;
+
+ f_ix--;
+ length = gcov_read_unsigned ();
+ gcov_read_summary (&tmp);
+ if ((error = gcov_is_error ()))
+ goto read_error;
+ if (*summary_pos_p)
+ {
+ /* Save all summaries after the one that will be
+ merged into below. These will need to be rewritten
+ as histogram merging may change the number of non-zero
+ histogram entries that will be emitted, and thus the
+ size of the merged summary. */
+ (*sum_tail) = (struct gcov_summary_buffer *)
+ malloc (sizeof(struct gcov_summary_buffer));
+ (*sum_tail)->summary = tmp;
+ (*sum_tail)->next = 0;
+ sum_tail = &((*sum_tail)->next);
+ goto next_summary;
+ }
+ if (tmp.checksum != crc32)
+ goto next_summary;
+
+ for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
+ if (tmp.ctrs[t_ix].num != this_prg.ctrs[t_ix].num)
+ goto next_summary;
+ *prg_p = tmp;
+ *summary_pos_p = *eof_pos_p;
+
+ next_summary:;
+ }
+
+ /* Merge execution counts for each function. */
+ for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
+ f_ix++, tag = gcov_read_unsigned ())
+ {
+ const struct gcov_ctr_info *ci_ptr;
+ const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
+
+ if (tag != GCOV_TAG_FUNCTION)
+ goto read_mismatch;
+
+ length = gcov_read_unsigned ();
+ if (!length)
+ /* This function did not appear in the other program.
+ We have nothing to merge. */
+ continue;
+
+ if (length != GCOV_TAG_FUNCTION_LENGTH)
+ goto read_mismatch;
+
+ if (!gfi_ptr || gfi_ptr->key != gi_ptr)
+ {
+ /* This function appears in the other program. We
+ need to buffer the information in order to write
+ it back out -- we'll be inserting data before
+ this point, so cannot simply keep the data in the
+ file. */
+ fn_tail = buffer_fn_data (gi_filename,
+ gi_ptr, fn_tail, f_ix);
+ if (!fn_tail)
+ goto read_mismatch;
+ continue;
+ }
+
+ length = gcov_read_unsigned ();
+ if (length != gfi_ptr->ident)
+ goto read_mismatch;
+
+ length = gcov_read_unsigned ();
+ if (length != gfi_ptr->lineno_checksum)
+ goto read_mismatch;
+
+ length = gcov_read_unsigned ();
+ if (length != gfi_ptr->cfg_checksum)
+ goto read_mismatch;
+
+ ci_ptr = gfi_ptr->ctrs;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ {
+ gcov_merge_fn merge = gi_ptr->merge[t_ix];
+
+ if (!merge)
+ continue;
+
+ tag = gcov_read_unsigned ();
+ length = gcov_read_unsigned ();
+ if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
+ || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
+ goto read_mismatch;
+ (*merge) (ci_ptr->values, ci_ptr->num);
+ ci_ptr++;
+ }
+ if ((error = gcov_is_error ()))
+ goto read_error;
+ }
+
+ if (tag)
+ {
+ read_mismatch:;
+ gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
+ gi_filename, f_ix >= 0 ? "function" : "summary",
+ f_ix < 0 ? -1 - f_ix : f_ix);
+ return -1;
+ }
+ return 0;
+
+read_error:
+ gcov_error ("profiling:%s:%s merging\n", gi_filename,
+ error < 0 ? "Overflow": "Error");
+ return -1;
+}
+
+/* Write counters in GI_PTR and the summary in PRG to a gcda file. In
+ the case of appending to an existing file, SUMMARY_POS will be non-zero.
+ We will write the file starting from SUMMAY_POS. */
+
+static void
+gcov_exit_write_gcda (const struct gcov_info *gi_ptr,
+ const struct gcov_summary *prg_p,
+ const gcov_position_t eof_pos,
+ const gcov_position_t summary_pos)
+{
+ unsigned f_ix;
+ struct gcov_summary_buffer *next_sum_buffer;
+
+ /* Write out the data. */
+ if (!eof_pos)
+ {
+ gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
+ gcov_write_unsigned (gi_ptr->stamp);
+ }
+
+ if (summary_pos)
+ gcov_seek (summary_pos);
+
+ /* Generate whole program statistics. */
+ gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, prg_p);
+
+ /* Rewrite all the summaries that were after the summary we merged
+ into. This is necessary as the merged summary may have a different
+ size due to the number of non-zero histogram entries changing after
+ merging. */
+
+ while (sum_buffer)
+ {
+ gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
+ next_sum_buffer = sum_buffer->next;
+ free (sum_buffer);
+ sum_buffer = next_sum_buffer;
+ }
+
+ /* Write execution counts for each function. */
+ for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
+ {
+ unsigned buffered = 0;
+ const struct gcov_fn_info *gfi_ptr;
+ const struct gcov_ctr_info *ci_ptr;
+ gcov_unsigned_t length;
+ unsigned t_ix;
+
+ if (fn_buffer && fn_buffer->fn_ix == f_ix)
+ {
+ /* Buffered data from another program. */
+ buffered = 1;
+ gfi_ptr = &fn_buffer->info;
+ length = GCOV_TAG_FUNCTION_LENGTH;
+ }
+ else
+ {
+ gfi_ptr = gi_ptr->functions[f_ix];
+ if (gfi_ptr && gfi_ptr->key == gi_ptr)
+ length = GCOV_TAG_FUNCTION_LENGTH;
+ else
+ length = 0;
+ }
+
+ gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
+ if (!length)
+ continue;
+
+ gcov_write_unsigned (gfi_ptr->ident);
+ gcov_write_unsigned (gfi_ptr->lineno_checksum);
+ gcov_write_unsigned (gfi_ptr->cfg_checksum);
+
+ ci_ptr = gfi_ptr->ctrs;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ {
+ gcov_unsigned_t n_counts;
+ gcov_type *c_ptr;
+
+ if (!gi_ptr->merge[t_ix])
+ continue;
+
+ n_counts = ci_ptr->num;
+ gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
+ GCOV_TAG_COUNTER_LENGTH (n_counts));
+ c_ptr = ci_ptr->values;
+ while (n_counts--)
+ gcov_write_counter (*c_ptr++);
+ ci_ptr++;
+ }
+ if (buffered)
+ fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
+ }
+
+ gcov_write_unsigned (0);
+}
+
+/* Helper function for merging summary.
+ Return -1 on error. Return 0 on success. */
+
+static int
+gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *prg)
+{
+ struct gcov_ctr_summary *cs_prg, *cs_tprg;
+#if !GCOV_LOCKED
+ struct gcov_ctr_summary *cs_all;
+#endif
+ unsigned t_ix;
+
+ /* Merge the summaries. */
+ for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
+ {
+ cs_prg = &(prg->ctrs[t_ix]);
+ cs_tprg = &this_prg.ctrs[t_ix];
+
+ if (gi_ptr->merge[t_ix])
+ {
+ if (!cs_prg->runs++)
+ cs_prg->num = cs_tprg->num;
+ cs_prg->sum_all += cs_tprg->sum_all;
+ if (cs_prg->run_max < cs_tprg->run_max)
+ cs_prg->run_max = cs_tprg->run_max;
+ cs_prg->sum_max += cs_tprg->run_max;
+ if (cs_prg->runs == 1)
+ memcpy (cs_prg->histogram, cs_tprg->histogram,
+ sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
+ else
+ gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
+ }
+ else if (cs_prg->runs)
+ {
+ gcov_error ("profiling:%s:Merge mismatch for summary.\n",
+ gi_filename);
+ return -1;
+ }
+
+#if !GCOV_LOCKED
+ cs_all = &all_prg.ctrs[t_ix];
+ if (!cs_all->runs && cs_prg->runs)
+ {
+ cs_all->num = cs_prg->num;
+ cs_all->runs = cs_prg->runs;
+ cs_all->sum_all = cs_prg->sum_all;
+ cs_all->run_max = cs_prg->run_max;
+ cs_all->sum_max = cs_prg->sum_max;
+ }
+ else if (!all_prg.checksum
+ /* Don't compare the histograms, which may have slight
+ variations depending on the order they were updated
+ due to the truncating integer divides used in the
+ merge. */
+ && (cs_all->num != cs_prg->num
+ || cs_all->runs != cs_prg->runs
+ || cs_all->sum_all != cs_prg->sum_all
+ || cs_all->run_max != cs_prg->run_max
+ || cs_all->sum_max != cs_prg->sum_max))
+ {
+ gcov_error ("profiling:%s:Data file mismatch - some "
+ "data files may have been concurrently "
+ "updated without locking support\n", gi_filename);
+ all_prg.checksum = ~0u;
+ }
+#endif
+ }
+
+ prg->checksum = crc32;
+
+ return 0;
+}
+
+/* Dump the coverage counts for one gcov_info object. We merge with existing
+ counts when possible, to avoid growing the .da files ad infinitum. We use
+ this program's checksum to make sure we only accumulate whole program
+ statistics to the correct summary. An object file might be embedded
+ in two separate programs, and we must keep the two program
+ summaries separate. */
+
+static void
+gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf)
+{
+ struct gcov_summary prg; /* summary for this object over all program. */
+ int error;
+ gcov_unsigned_t tag;
+ gcov_position_t summary_pos = 0;
+ gcov_position_t eof_pos = 0;
+
+ fn_buffer = 0;
+ sum_buffer = 0;
+
+ error = gcov_exit_open_gcda_file (gi_ptr, gf);
+ if (error == -1)
+ return;
+
+ tag = gcov_read_unsigned ();
+ if (tag)
+ {
+ /* Merge data from file. */
+ if (tag != GCOV_DATA_MAGIC)
+ {
+ gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
+ goto read_fatal;
+ }
+ error = gcov_exit_merge_gcda (gi_ptr, &prg, &summary_pos, &eof_pos);
+ if (error == -1)
+ goto read_fatal;
+ }
+
+ gcov_rewrite ();
+
+ if (!summary_pos)
+ {
+ memset (&prg, 0, sizeof (prg));
+ summary_pos = eof_pos;
+ }
+
+ error = gcov_exit_merge_summary (gi_ptr, &prg);
+ if (error == -1)
+ goto read_fatal;
+
+ gcov_exit_write_gcda (gi_ptr, &prg, eof_pos, summary_pos);
+ /* fall through */
+
+read_fatal:;
+ while (fn_buffer)
+ fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
+
+ if ((error = gcov_close ()))
+ gcov_error (error < 0 ?
+ "profiling:%s:Overflow writing\n" :
+ "profiling:%s:Error writing\n",
+ gi_filename);
+}
+
+
+/* Dump all the coverage counts for the program. It first computes program
+ summary and then traverses gcov_list list and dumps the gcov_info
+ objects one by one. */
+
+void
+gcov_exit (void)
+{
+ struct gcov_info *gi_ptr;
+ struct gcov_filename_aux gf;
+
+ /* Prevent the counters from being dumped a second time on exit when the
+ application already wrote out the profile using __gcov_dump(). */
+ if (gcov_dump_complete)
+ return;
+
+ gcov_exit_compute_summary ();
+
+ allocate_filename_struct (&gf);
+
+ /* Now merge each file. */
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ gcov_exit_dump_gcov (gi_ptr, &gf);
+
+ if (gi_filename)
+ free (gi_filename);
+}
+
+/* Reset all counters to zero. */
+
+void
+gcov_clear (void)
+{
+ const struct gcov_info *gi_ptr;
+
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ unsigned f_ix;
+
+ for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
+ {
+ unsigned t_ix;
+ const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
+
+ if (!gfi_ptr || gfi_ptr->key != gi_ptr)
+ continue;
+ const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
+ for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
+ {
+ if (!gi_ptr->merge[t_ix])
+ continue;
+
+ memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
+ ci_ptr++;
+ }
+ }
+ }
+}
+
+/* Add a new object file onto the bb chain. Invoked automatically
+ when running an object file's global ctors. */
+
+void
+__gcov_init (struct gcov_info *info)
+{
+ if (!info->version || !info->n_functions)
+ return;
+ if (gcov_version (info, info->version, 0))
+ {
+ size_t filename_length = strlen(info->filename);
+
+ /* Refresh the longest file name information */
+ if (filename_length > gcov_max_filename)
+ gcov_max_filename = filename_length;
+
+ if (!gcov_list)
+ atexit (gcov_exit);
+
+ info->next = gcov_list;
+ gcov_list = info;
+ }
+ info->version = 0;
+}
+
+#endif /* L_gcov */
+#endif /* inhibit_libc */
diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c
new file mode 100644
index 00000000000..5e23178b87e
--- /dev/null
+++ b/libgcc/libgcov-interface.c
@@ -0,0 +1,279 @@
+/* Routines required for instrumenting a program. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+#include "gthr.h"
+
+#if defined(inhibit_libc)
+#define IN_LIBGCOV (-1)
+#else
+#define IN_LIBGCOV 1
+#endif
+#include "gcov-io.h"
+
+#if defined(inhibit_libc)
+
+#ifdef L_gcov_flush
+void __gcov_flush (void) {}
+#endif
+
+#ifdef L_gcov_reset
+void __gcov_reset (void) {}
+#endif
+
+#ifdef L_gcov_dump
+void __gcov_dump (void) {}
+#endif
+
+#else
+
+extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
+extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
+extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
+extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
+
+#ifdef L_gcov_flush
+
+#ifdef __GTHREAD_MUTEX_INIT
+ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
+#define init_mx_once()
+#else
+__gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
+
+static void
+init_mx (void)
+{
+ __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
+}
+static void
+init_mx_once (void)
+{
+ static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+ __gthread_once (&once, init_mx);
+}
+#endif
+
+/* Called before fork or exec - write out profile information gathered so
+ far and reset it to zero. This avoids duplication or loss of the
+ profile information gathered so far. */
+
+void
+__gcov_flush (void)
+{
+ init_mx_once ();
+ __gthread_mutex_lock (&__gcov_flush_mx);
+
+ gcov_exit ();
+ gcov_clear ();
+
+ __gthread_mutex_unlock (&__gcov_flush_mx);
+}
+
+#endif /* L_gcov_flush */
+
+#ifdef L_gcov_reset
+
+/* Function that can be called from application to reset counters to zero,
+ in order to collect profile in region of interest. */
+
+void
+__gcov_reset (void)
+{
+ gcov_clear ();
+ /* Re-enable dumping to support collecting profile in multiple regions
+ of interest. */
+ reset_gcov_dump_complete ();
+}
+
+#endif /* L_gcov_reset */
+
+#ifdef L_gcov_dump
+
+/* Function that can be called from application to write profile collected
+ so far, in order to collect profile in region of interest. */
+
+void
+__gcov_dump (void)
+{
+ gcov_exit ();
+ /* Prevent profile from being dumped a second time on application exit. */
+ set_gcov_dump_complete ();
+}
+
+#endif /* L_gcov_dump */
+
+
+#ifdef L_gcov_fork
+/* A wrapper for the fork function. Flushes the accumulated profiling data, so
+ that they are not counted twice. */
+
+pid_t
+__gcov_fork (void)
+{
+ pid_t pid;
+ extern __gthread_mutex_t __gcov_flush_mx;
+ __gcov_flush ();
+ pid = fork ();
+ if (pid == 0)
+ __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
+ return pid;
+}
+#endif
+
+#ifdef L_gcov_execl
+/* A wrapper for the execl function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execl (const char *path, char *arg, ...)
+{
+ va_list ap, aq;
+ unsigned i, length;
+ char **args;
+
+ __gcov_flush ();
+
+ va_start (ap, arg);
+ va_copy (aq, ap);
+
+ length = 2;
+ while (va_arg (ap, char *))
+ length++;
+ va_end (ap);
+
+ args = (char **) alloca (length * sizeof (void *));
+ args[0] = arg;
+ for (i = 1; i < length; i++)
+ args[i] = va_arg (aq, char *);
+ va_end (aq);
+
+ return execv (path, args);
+}
+#endif
+
+#ifdef L_gcov_execlp
+/* A wrapper for the execlp function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execlp (const char *path, char *arg, ...)
+{
+ va_list ap, aq;
+ unsigned i, length;
+ char **args;
+
+ __gcov_flush ();
+
+ va_start (ap, arg);
+ va_copy (aq, ap);
+
+ length = 2;
+ while (va_arg (ap, char *))
+ length++;
+ va_end (ap);
+
+ args = (char **) alloca (length * sizeof (void *));
+ args[0] = arg;
+ for (i = 1; i < length; i++)
+ args[i] = va_arg (aq, char *);
+ va_end (aq);
+
+ return execvp (path, args);
+}
+#endif
+
+#ifdef L_gcov_execle
+/* A wrapper for the execle function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execle (const char *path, char *arg, ...)
+{
+ va_list ap, aq;
+ unsigned i, length;
+ char **args;
+ char **envp;
+
+ __gcov_flush ();
+
+ va_start (ap, arg);
+ va_copy (aq, ap);
+
+ length = 2;
+ while (va_arg (ap, char *))
+ length++;
+ va_end (ap);
+
+ args = (char **) alloca (length * sizeof (void *));
+ args[0] = arg;
+ for (i = 1; i < length; i++)
+ args[i] = va_arg (aq, char *);
+ envp = va_arg (aq, char **);
+ va_end (aq);
+
+ return execve (path, args, envp);
+}
+#endif
+
+#ifdef L_gcov_execv
+/* A wrapper for the execv function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execv (const char *path, char *const argv[])
+{
+ __gcov_flush ();
+ return execv (path, argv);
+}
+#endif
+
+#ifdef L_gcov_execvp
+/* A wrapper for the execvp function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execvp (const char *path, char *const argv[])
+{
+ __gcov_flush ();
+ return execvp (path, argv);
+}
+#endif
+
+#ifdef L_gcov_execve
+/* A wrapper for the execve function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execve (const char *path, char *const argv[], char *const envp[])
+{
+ __gcov_flush ();
+ return execve (path, argv, envp);
+}
+#endif
+#endif /* inhibit_libc */
diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c
new file mode 100644
index 00000000000..45cd48cc4c4
--- /dev/null
+++ b/libgcc/libgcov-merge.c
@@ -0,0 +1,181 @@
+/* Routines required for instrumenting a program. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+
+#if defined(inhibit_libc)
+#define IN_LIBGCOV (-1)
+#else
+#define IN_LIBGCOV 1
+#endif
+
+#include "gcov-io.h"
+
+#if defined(inhibit_libc)
+/* If libc and its header files are not available, provide dummy functions. */
+
+#ifdef L_gcov_merge_add
+void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#ifdef L_gcov_merge_single
+void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#ifdef L_gcov_merge_delta
+void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#else
+
+#ifdef L_gcov_merge_add
+/* The profile merging function that just adds the counters. It is given
+ an array COUNTERS of N_COUNTERS old counters and it reads the same number
+ of counters from the gcov file. */
+void
+__gcov_merge_add (gcov_type *counters, unsigned n_counters)
+{
+ for (; n_counters; counters++, n_counters--)
+ *counters += gcov_read_counter ();
+}
+#endif /* L_gcov_merge_add */
+
+#ifdef L_gcov_merge_ior
+/* The profile merging function that just adds the counters. It is given
+ an array COUNTERS of N_COUNTERS old counters and it reads the same number
+ of counters from the gcov file. */
+void
+__gcov_merge_ior (gcov_type *counters, unsigned n_counters)
+{
+ for (; n_counters; counters++, n_counters--)
+ *counters |= gcov_read_counter ();
+}
+#endif
+
+#ifdef L_gcov_merge_time_profile
+/* Time profiles are merged so that minimum from all valid (greater than zero)
+ is stored. There could be a fork that creates new counters. To have
+ the profile stable, we chosen to pick the smallest function visit time. */
+void
+__gcov_merge_time_profile (gcov_type *counters, unsigned n_counters)
+{
+ unsigned int i;
+ gcov_type value;
+
+ for (i = 0; i < n_counters; i++)
+ {
+ value = gcov_read_counter ();
+
+ if (value && (!counters[i] || value < counters[i]))
+ counters[i] = value;
+ }
+}
+#endif /* L_gcov_merge_time_profile */
+
+#ifdef L_gcov_merge_single
+/* The profile merging function for choosing the most common value.
+ It is given an array COUNTERS of N_COUNTERS old counters and it
+ reads the same number of counters from the gcov file. The counters
+ are split into 3-tuples where the members of the tuple have
+ meanings:
+
+ -- the stored candidate on the most common value of the measured entity
+ -- counter
+ -- total number of evaluations of the value */
+void
+__gcov_merge_single (gcov_type *counters, unsigned n_counters)
+{
+ unsigned i, n_measures;
+ gcov_type value, counter, all;
+
+ gcc_assert (!(n_counters % 3));
+ n_measures = n_counters / 3;
+ for (i = 0; i < n_measures; i++, counters += 3)
+ {
+ value = gcov_read_counter ();
+ counter = gcov_read_counter ();
+ all = gcov_read_counter ();
+
+ if (counters[0] == value)
+ counters[1] += counter;
+ else if (counter > counters[1])
+ {
+ counters[0] = value;
+ counters[1] = counter - counters[1];
+ }
+ else
+ counters[1] -= counter;
+ counters[2] += all;
+ }
+}
+#endif /* L_gcov_merge_single */
+
+#ifdef L_gcov_merge_delta
+/* The profile merging function for choosing the most common
+ difference between two consecutive evaluations of the value. It is
+ given an array COUNTERS of N_COUNTERS old counters and it reads the
+ same number of counters from the gcov file. The counters are split
+ into 4-tuples where the members of the tuple have meanings:
+
+ -- the last value of the measured entity
+ -- the stored candidate on the most common difference
+ -- counter
+ -- total number of evaluations of the value */
+void
+__gcov_merge_delta (gcov_type *counters, unsigned n_counters)
+{
+ unsigned i, n_measures;
+ gcov_type value, counter, all;
+
+ gcc_assert (!(n_counters % 4));
+ n_measures = n_counters / 4;
+ for (i = 0; i < n_measures; i++, counters += 4)
+ {
+ /* last = */ gcov_read_counter ();
+ value = gcov_read_counter ();
+ counter = gcov_read_counter ();
+ all = gcov_read_counter ();
+
+ if (counters[1] == value)
+ counters[2] += counter;
+ else if (counter > counters[2])
+ {
+ counters[1] = value;
+ counters[2] = counter - counters[2];
+ }
+ else
+ counters[2] -= counter;
+ counters[3] += all;
+ }
+}
+#endif /* L_gcov_merge_delta */
+#endif /* inhibit_libc */
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
new file mode 100644
index 00000000000..6ba1bcf365c
--- /dev/null
+++ b/libgcc/libgcov-profiler.c
@@ -0,0 +1,223 @@
+/* Routines required for instrumenting a program. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+
+#if !defined(inhibit_libc)
+#define IN_LIBGCOV 1
+#include "gcov-io.h"
+
+#ifdef L_gcov_interval_profiler
+/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
+ corresponding counter in COUNTERS. If the VALUE is above or below
+ the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
+ instead. */
+
+void
+__gcov_interval_profiler (gcov_type *counters, gcov_type value,
+ int start, unsigned steps)
+{
+ gcov_type delta = value - start;
+ if (delta < 0)
+ counters[steps + 1]++;
+ else if (delta >= steps)
+ counters[steps]++;
+ else
+ counters[delta]++;
+}
+#endif
+
+#ifdef L_gcov_pow2_profiler
+/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
+ COUNTERS[0] is incremented. */
+
+void
+__gcov_pow2_profiler (gcov_type *counters, gcov_type value)
+{
+ if (value & (value - 1))
+ counters[0]++;
+ else
+ counters[1]++;
+}
+#endif
+
+/* Tries to determine the most common value among its inputs. Checks if the
+ value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
+ is incremented. If this is not the case and COUNTERS[1] is not zero,
+ COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
+ VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
+ function is called more than 50% of the time with one value, this value
+ will be in COUNTERS[0] in the end.
+
+ In any case, COUNTERS[2] is incremented. */
+
+static inline void
+__gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
+{
+ if (value == counters[0])
+ counters[1]++;
+ else if (counters[1] == 0)
+ {
+ counters[1] = 1;
+ counters[0] = value;
+ }
+ else
+ counters[1]--;
+ counters[2]++;
+}
+
+#ifdef L_gcov_one_value_profiler
+void
+__gcov_one_value_profiler (gcov_type *counters, gcov_type value)
+{
+ __gcov_one_value_profiler_body (counters, value);
+}
+#endif
+
+#ifdef L_gcov_indirect_call_profiler
+/* This function exist only for workaround of binutils bug 14342.
+ Once this compatibility hack is obsolette, it can be removed. */
+
+/* By default, the C++ compiler will use function addresses in the
+ vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
+ tells the compiler to use function descriptors instead. The value
+ of this macro says how many words wide the descriptor is (normally 2),
+ but it may be dependent on target flags. Since we do not have access
+ to the target flags here we just check to see if it is set and use
+ that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
+
+ It is assumed that the address of a function descriptor may be treated
+ as a pointer to a function. */
+
+#ifdef TARGET_VTABLE_USES_DESCRIPTORS
+#define VTABLE_USES_DESCRIPTORS 1
+#else
+#define VTABLE_USES_DESCRIPTORS 0
+#endif
+
+/* Tries to determine the most common value among its inputs. */
+void
+__gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
+ void* cur_func, void* callee_func)
+{
+ /* If the C++ virtual tables contain function descriptors then one
+ function may have multiple descriptors and we need to dereference
+ the descriptors to see if they point to the same function. */
+ if (cur_func == callee_func
+ || (VTABLE_USES_DESCRIPTORS && callee_func
+ && *(void **) cur_func == *(void **) callee_func))
+ __gcov_one_value_profiler_body (counter, value);
+}
+
+#endif
+#ifdef L_gcov_indirect_call_profiler_v2
+
+/* These two variables are used to actually track caller and callee. Keep
+ them in TLS memory so races are not common (they are written to often).
+ The variables are set directly by GCC instrumented code, so declaration
+ here must match one in tree-profile.c */
+
+#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
+__thread
+#endif
+void * __gcov_indirect_call_callee;
+#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
+__thread
+#endif
+gcov_type * __gcov_indirect_call_counters;
+
+/* By default, the C++ compiler will use function addresses in the
+ vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
+ tells the compiler to use function descriptors instead. The value
+ of this macro says how many words wide the descriptor is (normally 2),
+ but it may be dependent on target flags. Since we do not have access
+ to the target flags here we just check to see if it is set and use
+ that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
+
+ It is assumed that the address of a function descriptor may be treated
+ as a pointer to a function. */
+
+#ifdef TARGET_VTABLE_USES_DESCRIPTORS
+#define VTABLE_USES_DESCRIPTORS 1
+#else
+#define VTABLE_USES_DESCRIPTORS 0
+#endif
+
+/* Tries to determine the most common value among its inputs. */
+void
+__gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
+{
+ /* If the C++ virtual tables contain function descriptors then one
+ function may have multiple descriptors and we need to dereference
+ the descriptors to see if they point to the same function. */
+ if (cur_func == __gcov_indirect_call_callee
+ || (VTABLE_USES_DESCRIPTORS && __gcov_indirect_call_callee
+ && *(void **) cur_func == *(void **) __gcov_indirect_call_callee))
+ __gcov_one_value_profiler_body (__gcov_indirect_call_counters, value);
+}
+#endif
+
+#ifdef L_gcov_time_profiler
+
+/* Counter for first visit of each function. */
+static gcov_type function_counter;
+
+/* Sets corresponding COUNTERS if there is no value. */
+
+void
+__gcov_time_profiler (gcov_type* counters)
+{
+ if (!counters[0])
+ counters[0] = ++function_counter;
+}
+#endif
+
+#ifdef L_gcov_average_profiler
+/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
+ to saturate up. */
+
+void
+__gcov_average_profiler (gcov_type *counters, gcov_type value)
+{
+ counters[0] += value;
+ counters[1] ++;
+}
+#endif
+
+#ifdef L_gcov_ior_profiler
+/* Bitwise-OR VALUE into COUNTER. */
+
+void
+__gcov_ior_profiler (gcov_type *counters, gcov_type value)
+{
+ *counters |= value;
+}
+#endif
+
+#endif /* inhibit_libc */
diff --git a/libgcc/libgcov.c b/libgcc/libgcov.c
deleted file mode 100644
index 3c39331e6ba..00000000000
--- a/libgcc/libgcov.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/* Routines required for instrumenting a program. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989-2013 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-Under Section 7 of GPL version 3, you are granted additional
-permissions described in the GCC Runtime Library Exception, version
-3.1, as published by the Free Software Foundation.
-
-You should have received a copy of the GNU General Public License and
-a copy of the GCC Runtime Library Exception along with this program;
-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-<http://www.gnu.org/licenses/>. */
-
-#include "tconfig.h"
-#include "tsystem.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "libgcc_tm.h"
-#include "gthr.h"
-
-#if defined(inhibit_libc)
-#define IN_LIBGCOV (-1)
-#else
-#define IN_LIBGCOV 1
-#if defined(L_gcov)
-#define GCOV_LINKAGE /* nothing */
-#endif
-#endif
-#include "gcov-io.h"
-
-#if defined(inhibit_libc)
-/* If libc and its header files are not available, provide dummy functions. */
-
-#ifdef L_gcov
-void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
-void __gcov_flush (void) {}
-#endif
-
-#ifdef L_gcov_reset
-void __gcov_reset (void) {}
-#endif
-
-#ifdef L_gcov_dump
-void __gcov_dump (void) {}
-#endif
-
-#ifdef L_gcov_merge_add
-void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
- unsigned n_counters __attribute__ ((unused))) {}
-#endif
-
-#ifdef L_gcov_merge_single
-void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
- unsigned n_counters __attribute__ ((unused))) {}
-#endif
-
-#ifdef L_gcov_merge_delta
-void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
- unsigned n_counters __attribute__ ((unused))) {}
-#endif
-
-#else
-
-#include <string.h>
-#if GCOV_LOCKED
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#endif
-
-extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
-extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
-extern int gcov_dump_complete ATTRIBUTE_HIDDEN;
-
-#ifdef L_gcov
-#include "gcov-io.c"
-
-struct gcov_fn_buffer
-{
- struct gcov_fn_buffer *next;
- unsigned fn_ix;
- struct gcov_fn_info info;
- /* note gcov_fn_info ends in a trailing array. */
-};
-
-struct gcov_summary_buffer
-{
- struct gcov_summary_buffer *next;
- struct gcov_summary summary;
-};
-
-/* Chain of per-object gcov structures. */
-static struct gcov_info *gcov_list;
-
-/* Size of the longest file name. */
-static size_t gcov_max_filename = 0;
-
-/* Flag when the profile has already been dumped via __gcov_dump(). */
-int gcov_dump_complete = 0;
-
-/* Make sure path component of the given FILENAME exists, create
- missing directories. FILENAME must be writable.
- Returns zero on success, or -1 if an error occurred. */
-
-static int
-create_file_directory (char *filename)
-{
-#if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
- (void) filename;
- return -1;
-#else
- char *s;
-
- s = filename;
-
- if (HAS_DRIVE_SPEC(s))
- s += 2;
- if (IS_DIR_SEPARATOR(*s))
- ++s;
- for (; *s != '\0'; s++)
- if (IS_DIR_SEPARATOR(*s))
- {
- char sep = *s;
- *s = '\0';
-
- /* Try to make directory if it doesn't already exist. */
- if (access (filename, F_OK) == -1
-#ifdef TARGET_POSIX_IO
- && mkdir (filename, 0755) == -1
-#else
- && mkdir (filename) == -1
-#endif
- /* The directory might have been made by another process. */
- && errno != EEXIST)
- {
- fprintf (stderr, "profiling:%s:Cannot create directory\n",
- filename);
- *s = sep;
- return -1;
- };
-
- *s = sep;
- };
- return 0;
-#endif
-}
-
-static struct gcov_fn_buffer *
-free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
- unsigned limit)
-{
- struct gcov_fn_buffer *next;
- unsigned ix, n_ctr = 0;
-
- if (!buffer)
- return 0;
- next = buffer->next;
-
- for (ix = 0; ix != limit; ix++)
- if (gi_ptr->merge[ix])
- free (buffer->info.ctrs[n_ctr++].values);
- free (buffer);
- return next;
-}
-
-static struct gcov_fn_buffer **
-buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
- struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
-{
- unsigned n_ctrs = 0, ix = 0;
- struct gcov_fn_buffer *fn_buffer;
- unsigned len;
-
- for (ix = GCOV_COUNTERS; ix--;)
- if (gi_ptr->merge[ix])
- n_ctrs++;
-
- len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
- fn_buffer = (struct gcov_fn_buffer *)malloc (len);
-
- if (!fn_buffer)
- goto fail;
-
- fn_buffer->next = 0;
- fn_buffer->fn_ix = fn_ix;
- fn_buffer->info.ident = gcov_read_unsigned ();
- fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
- fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
-
- for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
- {
- gcov_unsigned_t length;
- gcov_type *values;
-
- if (!gi_ptr->merge[ix])
- continue;
-
- if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
- {
- len = 0;
- goto fail;
- }
-
- length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
- len = length * sizeof (gcov_type);
- values = (gcov_type *)malloc (len);
- if (!values)
- goto fail;
-
- fn_buffer->info.ctrs[n_ctrs].num = length;
- fn_buffer->info.ctrs[n_ctrs].values = values;
-
- while (length--)
- *values++ = gcov_read_counter ();
- n_ctrs++;
- }
-
- *end_ptr = fn_buffer;
- return &fn_buffer->next;
-
- fail:
- fprintf (stderr, "profiling:%s:Function %u %s %u \n", filename, fn_ix,
- len ? "cannot allocate" : "counter mismatch", len ? len : ix);
-
- return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
-}
-
-/* Add an unsigned value to the current crc */
-
-static gcov_unsigned_t
-crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
-{
- unsigned ix;
-
- for (ix = 32; ix--; value <<= 1)
- {
- unsigned feedback;
-
- feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
- crc32 <<= 1;
- crc32 ^= feedback;
- }
-
- return crc32;
-}
-
-/* Check if VERSION of the info block PTR matches libgcov one.
- Return 1 on success, or zero in case of versions mismatch.
- If FILENAME is not NULL, its value used for reporting purposes
- instead of value from the info block. */
-
-static int
-gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
- const char *filename)
-{
- if (version != GCOV_VERSION)
- {
- char v[4], e[4];
-
- GCOV_UNSIGNED2STRING (v, version);
- GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
-
- fprintf (stderr,
- "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
- filename? filename : ptr->filename, e, v);
- return 0;
- }
- return 1;
-}
-
-/* Insert counter VALUE into HISTOGRAM. */
-
-static void
-gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
-{
- unsigned i;
-
- i = gcov_histo_index(value);
- histogram[i].num_counters++;
- histogram[i].cum_value += value;
- if (value < histogram[i].min_value)
- histogram[i].min_value = value;
-}
-
-/* Computes a histogram of the arc counters to place in the summary SUM. */
-
-static void
-gcov_compute_histogram (struct gcov_summary *sum)
-{
- struct gcov_info *gi_ptr;
- const struct gcov_fn_info *gfi_ptr;
- const struct gcov_ctr_info *ci_ptr;
- struct gcov_ctr_summary *cs_ptr;
- unsigned t_ix, f_ix, ctr_info_ix, ix;
- int h_ix;
-
- /* This currently only applies to arc counters. */
- t_ix = GCOV_COUNTER_ARCS;
-
- /* First check if there are any counts recorded for this counter. */
- cs_ptr = &(sum->ctrs[t_ix]);
- if (!cs_ptr->num)
- return;
-
- for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
- {
- cs_ptr->histogram[h_ix].num_counters = 0;
- cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
- cs_ptr->histogram[h_ix].cum_value = 0;
- }
-
- /* Walk through all the per-object structures and record each of
- the count values in histogram. */
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
- {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- /* Find the appropriate index into the gcov_ctr_info array
- for the counter we are currently working on based on the
- existence of the merge function pointer for this object. */
- for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
- {
- if (gi_ptr->merge[ix])
- ctr_info_ix++;
- }
- for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
- {
- gfi_ptr = gi_ptr->functions[f_ix];
-
- if (!gfi_ptr || gfi_ptr->key != gi_ptr)
- continue;
-
- ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
- for (ix = 0; ix < ci_ptr->num; ix++)
- gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
- }
- }
-}
-
-/* Dump the coverage counts. We merge with existing counts when
- possible, to avoid growing the .da files ad infinitum. We use this
- program's checksum to make sure we only accumulate whole program
- statistics to the correct summary. An object file might be embedded
- in two separate programs, and we must keep the two program
- summaries separate. */
-
-void
-gcov_exit (void)
-{
- struct gcov_info *gi_ptr;
- const struct gcov_fn_info *gfi_ptr;
- struct gcov_summary this_prg; /* summary for program. */
-#if !GCOV_LOCKED
- struct gcov_summary all_prg; /* summary for all instances of program. */
-#endif
- struct gcov_ctr_summary *cs_ptr;
- const struct gcov_ctr_info *ci_ptr;
- unsigned t_ix;
- int f_ix;
- gcov_unsigned_t c_num;
- const char *gcov_prefix;
- int gcov_prefix_strip = 0;
- size_t prefix_length;
- char *gi_filename, *gi_filename_up;
- gcov_unsigned_t crc32 = 0;
-
- /* Prevent the counters from being dumped a second time on exit when the
- application already wrote out the profile using __gcov_dump(). */
- if (gcov_dump_complete)
- return;
-
-#if !GCOV_LOCKED
- memset (&all_prg, 0, sizeof (all_prg));
-#endif
- /* Find the totals for this execution. */
- memset (&this_prg, 0, sizeof (this_prg));
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
- {
- crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
- crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
-
- for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
- {
- gfi_ptr = gi_ptr->functions[f_ix];
-
- if (gfi_ptr && gfi_ptr->key != gi_ptr)
- gfi_ptr = 0;
-
- crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
- crc32 = crc32_unsigned (crc32,
- gfi_ptr ? gfi_ptr->lineno_checksum : 0);
- if (!gfi_ptr)
- continue;
-
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- cs_ptr = &this_prg.ctrs[t_ix];
- cs_ptr->num += ci_ptr->num;
- crc32 = crc32_unsigned (crc32, ci_ptr->num);
-
- for (c_num = 0; c_num < ci_ptr->num; c_num++)
- {
- cs_ptr->sum_all += ci_ptr->values[c_num];
- if (cs_ptr->run_max < ci_ptr->values[c_num])
- cs_ptr->run_max = ci_ptr->values[c_num];
- }
- ci_ptr++;
- }
- }
- }
- gcov_compute_histogram (&this_prg);
-
- {
- /* Check if the level of dirs to strip off specified. */
- char *tmp = getenv("GCOV_PREFIX_STRIP");
- if (tmp)
- {
- gcov_prefix_strip = atoi (tmp);
- /* Do not consider negative values. */
- if (gcov_prefix_strip < 0)
- gcov_prefix_strip = 0;
- }
- }
-
- /* Get file name relocation prefix. Non-absolute values are ignored. */
- gcov_prefix = getenv("GCOV_PREFIX");
- if (gcov_prefix)
- {
- prefix_length = strlen(gcov_prefix);
-
- /* Remove an unnecessary trailing '/' */
- if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
- prefix_length--;
- }
- else
- prefix_length = 0;
-
- /* If no prefix was specified and a prefix stip, then we assume
- relative. */
- if (gcov_prefix_strip != 0 && prefix_length == 0)
- {
- gcov_prefix = ".";
- prefix_length = 1;
- }
- /* Allocate and initialize the filename scratch space plus one. */
- gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 2);
- if (prefix_length)
- memcpy (gi_filename, gcov_prefix, prefix_length);
- gi_filename_up = gi_filename + prefix_length;
-
- /* Now merge each file. */
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
- {
- unsigned n_counts;
- struct gcov_summary prg; /* summary for this object over all
- program. */
- struct gcov_ctr_summary *cs_prg, *cs_tprg;
-#if !GCOV_LOCKED
- struct gcov_ctr_summary *cs_all;
-#endif
- int error = 0;
- gcov_unsigned_t tag, length;
- gcov_position_t summary_pos = 0;
- gcov_position_t eof_pos = 0;
- const char *fname, *s;
- struct gcov_fn_buffer *fn_buffer = 0;
- struct gcov_fn_buffer **fn_tail = &fn_buffer;
- struct gcov_summary_buffer *next_sum_buffer, *sum_buffer = 0;
- struct gcov_summary_buffer **sum_tail = &sum_buffer;
-
- fname = gi_ptr->filename;
-
- /* Avoid to add multiple drive letters into combined path. */
- if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
- fname += 2;
-
- /* Build relocated filename, stripping off leading
- directories from the initial filename if requested. */
- if (gcov_prefix_strip > 0)
- {
- int level = 0;
- s = fname;
- if (IS_DIR_SEPARATOR(*s))
- ++s;
-
- /* Skip selected directory levels. */
- for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
- if (IS_DIR_SEPARATOR(*s))
- {
- fname = s;
- level++;
- }
- }
-
- /* Update complete filename with stripped original. */
- if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
- {
- /* If prefix is given, add directory separator. */
- strcpy (gi_filename_up, "/");
- strcpy (gi_filename_up + 1, fname);
- }
- else
- strcpy (gi_filename_up, fname);
-
- if (!gcov_open (gi_filename))
- {
- /* Open failed likely due to missed directory.
- Create directory and retry to open file. */
- if (create_file_directory (gi_filename))
- {
- fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
- continue;
- }
- if (!gcov_open (gi_filename))
- {
- fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
- continue;
- }
- }
-
- tag = gcov_read_unsigned ();
- if (tag)
- {
- /* Merge data from file. */
- if (tag != GCOV_DATA_MAGIC)
- {
- fprintf (stderr, "profiling:%s:Not a gcov data file\n",
- gi_filename);
- goto read_fatal;
- }
- length = gcov_read_unsigned ();
- if (!gcov_version (gi_ptr, length, gi_filename))
- goto read_fatal;
-
- length = gcov_read_unsigned ();
- if (length != gi_ptr->stamp)
- /* Read from a different compilation. Overwrite the file. */
- goto rewrite;
-
- /* Look for program summary. */
- for (f_ix = 0;;)
- {
- struct gcov_summary tmp;
-
- eof_pos = gcov_position ();
- tag = gcov_read_unsigned ();
- if (tag != GCOV_TAG_PROGRAM_SUMMARY)
- break;
-
- f_ix--;
- length = gcov_read_unsigned ();
- gcov_read_summary (&tmp);
- if ((error = gcov_is_error ()))
- goto read_error;
- if (summary_pos)
- {
- /* Save all summaries after the one that will be
- merged into below. These will need to be rewritten
- as histogram merging may change the number of non-zero
- histogram entries that will be emitted, and thus the
- size of the merged summary. */
- (*sum_tail) = (struct gcov_summary_buffer *)
- malloc (sizeof(struct gcov_summary_buffer));
- (*sum_tail)->summary = tmp;
- (*sum_tail)->next = 0;
- sum_tail = &((*sum_tail)->next);
- goto next_summary;
- }
- if (tmp.checksum != crc32)
- goto next_summary;
-
- for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
- if (tmp.ctrs[t_ix].num != this_prg.ctrs[t_ix].num)
- goto next_summary;
- prg = tmp;
- summary_pos = eof_pos;
-
- next_summary:;
- }
-
- /* Merge execution counts for each function. */
- for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
- f_ix++, tag = gcov_read_unsigned ())
- {
- gfi_ptr = gi_ptr->functions[f_ix];
-
- if (tag != GCOV_TAG_FUNCTION)
- goto read_mismatch;
-
- length = gcov_read_unsigned ();
- if (!length)
- /* This function did not appear in the other program.
- We have nothing to merge. */
- continue;
-
- if (length != GCOV_TAG_FUNCTION_LENGTH)
- goto read_mismatch;
-
- if (!gfi_ptr || gfi_ptr->key != gi_ptr)
- {
- /* This function appears in the other program. We
- need to buffer the information in order to write
- it back out -- we'll be inserting data before
- this point, so cannot simply keep the data in the
- file. */
- fn_tail = buffer_fn_data (gi_filename,
- gi_ptr, fn_tail, f_ix);
- if (!fn_tail)
- goto read_mismatch;
- continue;
- }
-
- length = gcov_read_unsigned ();
- if (length != gfi_ptr->ident)
- goto read_mismatch;
-
- length = gcov_read_unsigned ();
- if (length != gfi_ptr->lineno_checksum)
- goto read_mismatch;
-
- length = gcov_read_unsigned ();
- if (length != gfi_ptr->cfg_checksum)
- goto read_mismatch;
-
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
- {
- gcov_merge_fn merge = gi_ptr->merge[t_ix];
-
- if (!merge)
- continue;
-
- tag = gcov_read_unsigned ();
- length = gcov_read_unsigned ();
- if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
- || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
- goto read_mismatch;
- (*merge) (ci_ptr->values, ci_ptr->num);
- ci_ptr++;
- }
- if ((error = gcov_is_error ()))
- goto read_error;
- }
-
- if (tag)
- {
- read_mismatch:;
- fprintf (stderr, "profiling:%s:Merge mismatch for %s %u\n",
- gi_filename, f_ix >= 0 ? "function" : "summary",
- f_ix < 0 ? -1 - f_ix : f_ix);
- goto read_fatal;
- }
- }
- goto rewrite;
-
- read_error:;
- fprintf (stderr, "profiling:%s:%s merging\n", gi_filename,
- error < 0 ? "Overflow": "Error");
-
- goto read_fatal;
-
- rewrite:;
- gcov_rewrite ();
- if (!summary_pos)
- {
- memset (&prg, 0, sizeof (prg));
- summary_pos = eof_pos;
- }
-
- /* Merge the summaries. */
- for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- cs_prg = &prg.ctrs[t_ix];
- cs_tprg = &this_prg.ctrs[t_ix];
-
- if (gi_ptr->merge[t_ix])
- {
- if (!cs_prg->runs++)
- cs_prg->num = cs_tprg->num;
- cs_prg->sum_all += cs_tprg->sum_all;
- if (cs_prg->run_max < cs_tprg->run_max)
- cs_prg->run_max = cs_tprg->run_max;
- cs_prg->sum_max += cs_tprg->run_max;
- if (cs_prg->runs == 1)
- memcpy (cs_prg->histogram, cs_tprg->histogram,
- sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
- else
- gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
- }
- else if (cs_prg->runs)
- goto read_mismatch;
-
-#if !GCOV_LOCKED
- cs_all = &all_prg.ctrs[t_ix];
- if (!cs_all->runs && cs_prg->runs)
- {
- cs_all->num = cs_prg->num;
- cs_all->runs = cs_prg->runs;
- cs_all->sum_all = cs_prg->sum_all;
- cs_all->run_max = cs_prg->run_max;
- cs_all->sum_max = cs_prg->sum_max;
- }
- else if (!all_prg.checksum
- /* Don't compare the histograms, which may have slight
- variations depending on the order they were updated
- due to the truncating integer divides used in the
- merge. */
- && (cs_all->num != cs_prg->num
- || cs_all->runs != cs_prg->runs
- || cs_all->sum_all != cs_prg->sum_all
- || cs_all->run_max != cs_prg->run_max
- || cs_all->sum_max != cs_prg->sum_max))
- {
- fprintf (stderr,
- "profiling:%s:Data file mismatch - some data files may "
- "have been concurrently updated without locking support\n",
- gi_filename);
- all_prg.checksum = ~0u;
- }
-#endif
- }
-
- prg.checksum = crc32;
-
- /* Write out the data. */
- if (!eof_pos)
- {
- gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
- gcov_write_unsigned (gi_ptr->stamp);
- }
-
- if (summary_pos)
- gcov_seek (summary_pos);
-
- /* Generate whole program statistics. */
- gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &prg);
-
- /* Rewrite all the summaries that were after the summary we merged
- into. This is necessary as the merged summary may have a different
- size due to the number of non-zero histogram entries changing after
- merging. */
-
- while (sum_buffer)
- {
- gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
- next_sum_buffer = sum_buffer->next;
- free (sum_buffer);
- sum_buffer = next_sum_buffer;
- }
-
- /* Write execution counts for each function. */
- for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
- {
- unsigned buffered = 0;
-
- if (fn_buffer && fn_buffer->fn_ix == (unsigned)f_ix)
- {
- /* Buffered data from another program. */
- buffered = 1;
- gfi_ptr = &fn_buffer->info;
- length = GCOV_TAG_FUNCTION_LENGTH;
- }
- else
- {
- gfi_ptr = gi_ptr->functions[f_ix];
- if (gfi_ptr && gfi_ptr->key == gi_ptr)
- length = GCOV_TAG_FUNCTION_LENGTH;
- else
- length = 0;
- }
-
- gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
- if (!length)
- continue;
-
- gcov_write_unsigned (gfi_ptr->ident);
- gcov_write_unsigned (gfi_ptr->lineno_checksum);
- gcov_write_unsigned (gfi_ptr->cfg_checksum);
-
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
- {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- n_counts = ci_ptr->num;
- gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
- GCOV_TAG_COUNTER_LENGTH (n_counts));
- gcov_type *c_ptr = ci_ptr->values;
- while (n_counts--)
- gcov_write_counter (*c_ptr++);
- ci_ptr++;
- }
- if (buffered)
- fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
- }
-
- gcov_write_unsigned (0);
-
- read_fatal:;
- while (fn_buffer)
- fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
-
- if ((error = gcov_close ()))
- fprintf (stderr, error < 0 ?
- "profiling:%s:Overflow writing\n" :
- "profiling:%s:Error writing\n",
- gi_filename);
- }
-}
-
-/* Reset all counters to zero. */
-
-void
-gcov_clear (void)
-{
- const struct gcov_info *gi_ptr;
-
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
- {
- unsigned f_ix;
-
- for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
- {
- unsigned t_ix;
- const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
-
- if (!gfi_ptr || gfi_ptr->key != gi_ptr)
- continue;
- const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
- {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
- ci_ptr++;
- }
- }
- }
-}
-
-/* Add a new object file onto the bb chain. Invoked automatically
- when running an object file's global ctors. */
-
-void
-__gcov_init (struct gcov_info *info)
-{
- if (!info->version || !info->n_functions)
- return;
- if (gcov_version (info, info->version, 0))
- {
- size_t filename_length = strlen(info->filename);
-
- /* Refresh the longest file name information */
- if (filename_length > gcov_max_filename)
- gcov_max_filename = filename_length;
-
- if (!gcov_list)
- atexit (gcov_exit);
-
- info->next = gcov_list;
- gcov_list = info;
- }
- info->version = 0;
-}
-
-#ifdef __GTHREAD_MUTEX_INIT
-ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
-#define init_mx_once()
-#else
-__gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
-
-static void
-init_mx (void)
-{
- __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
-}
-static void
-init_mx_once (void)
-{
- static __gthread_once_t once = __GTHREAD_ONCE_INIT;
- __gthread_once (&once, init_mx);
-}
-#endif
-
-/* Called before fork or exec - write out profile information gathered so
- far and reset it to zero. This avoids duplication or loss of the
- profile information gathered so far. */
-
-void
-__gcov_flush (void)
-{
- init_mx_once ();
- __gthread_mutex_lock (&__gcov_flush_mx);
-
- gcov_exit ();
- gcov_clear ();
-
- __gthread_mutex_unlock (&__gcov_flush_mx);
-}
-
-#endif /* L_gcov */
-
-#ifdef L_gcov_reset
-
-/* Function that can be called from application to reset counters to zero,
- in order to collect profile in region of interest. */
-
-void
-__gcov_reset (void)
-{
- gcov_clear ();
- /* Re-enable dumping to support collecting profile in multiple regions
- of interest. */
- gcov_dump_complete = 0;
-}
-
-#endif /* L_gcov_reset */
-
-#ifdef L_gcov_dump
-
-/* Function that can be called from application to write profile collected
- so far, in order to collect profile in region of interest. */
-
-void
-__gcov_dump (void)
-{
- gcov_exit ();
- /* Prevent profile from being dumped a second time on application exit. */
- gcov_dump_complete = 1;
-}
-
-#endif /* L_gcov_dump */
-
-#ifdef L_gcov_merge_add
-/* The profile merging function that just adds the counters. It is given
- an array COUNTERS of N_COUNTERS old counters and it reads the same number
- of counters from the gcov file. */
-void
-__gcov_merge_add (gcov_type *counters, unsigned n_counters)
-{
- for (; n_counters; counters++, n_counters--)
- *counters += gcov_read_counter ();
-}
-#endif /* L_gcov_merge_add */
-
-#ifdef L_gcov_merge_ior
-/* The profile merging function that just adds the counters. It is given
- an array COUNTERS of N_COUNTERS old counters and it reads the same number
- of counters from the gcov file. */
-void
-__gcov_merge_ior (gcov_type *counters, unsigned n_counters)
-{
- for (; n_counters; counters++, n_counters--)
- *counters |= gcov_read_counter ();
-}
-#endif
-
-#ifdef L_gcov_merge_single
-/* The profile merging function for choosing the most common value.
- It is given an array COUNTERS of N_COUNTERS old counters and it
- reads the same number of counters from the gcov file. The counters
- are split into 3-tuples where the members of the tuple have
- meanings:
-
- -- the stored candidate on the most common value of the measured entity
- -- counter
- -- total number of evaluations of the value */
-void
-__gcov_merge_single (gcov_type *counters, unsigned n_counters)
-{
- unsigned i, n_measures;
- gcov_type value, counter, all;
-
- gcc_assert (!(n_counters % 3));
- n_measures = n_counters / 3;
- for (i = 0; i < n_measures; i++, counters += 3)
- {
- value = gcov_read_counter ();
- counter = gcov_read_counter ();
- all = gcov_read_counter ();
-
- if (counters[0] == value)
- counters[1] += counter;
- else if (counter > counters[1])
- {
- counters[0] = value;
- counters[1] = counter - counters[1];
- }
- else
- counters[1] -= counter;
- counters[2] += all;
- }
-}
-#endif /* L_gcov_merge_single */
-
-#ifdef L_gcov_merge_delta
-/* The profile merging function for choosing the most common
- difference between two consecutive evaluations of the value. It is
- given an array COUNTERS of N_COUNTERS old counters and it reads the
- same number of counters from the gcov file. The counters are split
- into 4-tuples where the members of the tuple have meanings:
-
- -- the last value of the measured entity
- -- the stored candidate on the most common difference
- -- counter
- -- total number of evaluations of the value */
-void
-__gcov_merge_delta (gcov_type *counters, unsigned n_counters)
-{
- unsigned i, n_measures;
- gcov_type value, counter, all;
-
- gcc_assert (!(n_counters % 4));
- n_measures = n_counters / 4;
- for (i = 0; i < n_measures; i++, counters += 4)
- {
- /* last = */ gcov_read_counter ();
- value = gcov_read_counter ();
- counter = gcov_read_counter ();
- all = gcov_read_counter ();
-
- if (counters[1] == value)
- counters[2] += counter;
- else if (counter > counters[2])
- {
- counters[1] = value;
- counters[2] = counter - counters[2];
- }
- else
- counters[2] -= counter;
- counters[3] += all;
- }
-}
-#endif /* L_gcov_merge_delta */
-
-#ifdef L_gcov_interval_profiler
-/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
- corresponding counter in COUNTERS. If the VALUE is above or below
- the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
- instead. */
-
-void
-__gcov_interval_profiler (gcov_type *counters, gcov_type value,
- int start, unsigned steps)
-{
- gcov_type delta = value - start;
- if (delta < 0)
- counters[steps + 1]++;
- else if (delta >= steps)
- counters[steps]++;
- else
- counters[delta]++;
-}
-#endif
-
-#ifdef L_gcov_pow2_profiler
-/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
- COUNTERS[0] is incremented. */
-
-void
-__gcov_pow2_profiler (gcov_type *counters, gcov_type value)
-{
- if (value & (value - 1))
- counters[0]++;
- else
- counters[1]++;
-}
-#endif
-
-/* Tries to determine the most common value among its inputs. Checks if the
- value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
- is incremented. If this is not the case and COUNTERS[1] is not zero,
- COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
- VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
- function is called more than 50% of the time with one value, this value
- will be in COUNTERS[0] in the end.
-
- In any case, COUNTERS[2] is incremented. */
-
-static inline void
-__gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
-{
- if (value == counters[0])
- counters[1]++;
- else if (counters[1] == 0)
- {
- counters[1] = 1;
- counters[0] = value;
- }
- else
- counters[1]--;
- counters[2]++;
-}
-
-#ifdef L_gcov_one_value_profiler
-void
-__gcov_one_value_profiler (gcov_type *counters, gcov_type value)
-{
- __gcov_one_value_profiler_body (counters, value);
-}
-#endif
-
-#ifdef L_gcov_indirect_call_profiler
-/* This function exist only for workaround of binutils bug 14342.
- Once this compatibility hack is obsolette, it can be removed. */
-
-/* By default, the C++ compiler will use function addresses in the
- vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
- tells the compiler to use function descriptors instead. The value
- of this macro says how many words wide the descriptor is (normally 2),
- but it may be dependent on target flags. Since we do not have access
- to the target flags here we just check to see if it is set and use
- that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
-
- It is assumed that the address of a function descriptor may be treated
- as a pointer to a function. */
-
-#ifdef TARGET_VTABLE_USES_DESCRIPTORS
-#define VTABLE_USES_DESCRIPTORS 1
-#else
-#define VTABLE_USES_DESCRIPTORS 0
-#endif
-
-/* Tries to determine the most common value among its inputs. */
-void
-__gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
- void* cur_func, void* callee_func)
-{
- /* If the C++ virtual tables contain function descriptors then one
- function may have multiple descriptors and we need to dereference
- the descriptors to see if they point to the same function. */
- if (cur_func == callee_func
- || (VTABLE_USES_DESCRIPTORS && callee_func
- && *(void **) cur_func == *(void **) callee_func))
- __gcov_one_value_profiler_body (counter, value);
-}
-
-#endif
-#ifdef L_gcov_indirect_call_profiler_v2
-
-/* These two variables are used to actually track caller and callee. Keep
- them in TLS memory so races are not common (they are written to often).
- The variables are set directly by GCC instrumented code, so declaration
- here must match one in tree-profile.c */
-
-#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
-__thread
-#endif
-void * __gcov_indirect_call_callee;
-#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
-__thread
-#endif
-gcov_type * __gcov_indirect_call_counters;
-
-/* By default, the C++ compiler will use function addresses in the
- vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
- tells the compiler to use function descriptors instead. The value
- of this macro says how many words wide the descriptor is (normally 2),
- but it may be dependent on target flags. Since we do not have access
- to the target flags here we just check to see if it is set and use
- that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
-
- It is assumed that the address of a function descriptor may be treated
- as a pointer to a function. */
-
-#ifdef TARGET_VTABLE_USES_DESCRIPTORS
-#define VTABLE_USES_DESCRIPTORS 1
-#else
-#define VTABLE_USES_DESCRIPTORS 0
-#endif
-
-/* Tries to determine the most common value among its inputs. */
-void
-__gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
-{
- /* If the C++ virtual tables contain function descriptors then one
- function may have multiple descriptors and we need to dereference
- the descriptors to see if they point to the same function. */
- if (cur_func == __gcov_indirect_call_callee
- || (VTABLE_USES_DESCRIPTORS && __gcov_indirect_call_callee
- && *(void **) cur_func == *(void **) __gcov_indirect_call_callee))
- __gcov_one_value_profiler_body (__gcov_indirect_call_counters, value);
-}
-#endif
-
-#ifdef L_gcov_average_profiler
-/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
- to saturate up. */
-
-void
-__gcov_average_profiler (gcov_type *counters, gcov_type value)
-{
- counters[0] += value;
- counters[1] ++;
-}
-#endif
-
-#ifdef L_gcov_ior_profiler
-/* Bitwise-OR VALUE into COUNTER. */
-
-void
-__gcov_ior_profiler (gcov_type *counters, gcov_type value)
-{
- *counters |= value;
-}
-#endif
-
-#ifdef L_gcov_fork
-/* A wrapper for the fork function. Flushes the accumulated profiling data, so
- that they are not counted twice. */
-
-pid_t
-__gcov_fork (void)
-{
- pid_t pid;
- extern __gthread_mutex_t __gcov_flush_mx;
- __gcov_flush ();
- pid = fork ();
- if (pid == 0)
- __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
- return pid;
-}
-#endif
-
-#ifdef L_gcov_execl
-/* A wrapper for the execl function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execl (const char *path, char *arg, ...)
-{
- va_list ap, aq;
- unsigned i, length;
- char **args;
-
- __gcov_flush ();
-
- va_start (ap, arg);
- va_copy (aq, ap);
-
- length = 2;
- while (va_arg (ap, char *))
- length++;
- va_end (ap);
-
- args = (char **) alloca (length * sizeof (void *));
- args[0] = arg;
- for (i = 1; i < length; i++)
- args[i] = va_arg (aq, char *);
- va_end (aq);
-
- return execv (path, args);
-}
-#endif
-
-#ifdef L_gcov_execlp
-/* A wrapper for the execlp function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execlp (const char *path, char *arg, ...)
-{
- va_list ap, aq;
- unsigned i, length;
- char **args;
-
- __gcov_flush ();
-
- va_start (ap, arg);
- va_copy (aq, ap);
-
- length = 2;
- while (va_arg (ap, char *))
- length++;
- va_end (ap);
-
- args = (char **) alloca (length * sizeof (void *));
- args[0] = arg;
- for (i = 1; i < length; i++)
- args[i] = va_arg (aq, char *);
- va_end (aq);
-
- return execvp (path, args);
-}
-#endif
-
-#ifdef L_gcov_execle
-/* A wrapper for the execle function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execle (const char *path, char *arg, ...)
-{
- va_list ap, aq;
- unsigned i, length;
- char **args;
- char **envp;
-
- __gcov_flush ();
-
- va_start (ap, arg);
- va_copy (aq, ap);
-
- length = 2;
- while (va_arg (ap, char *))
- length++;
- va_end (ap);
-
- args = (char **) alloca (length * sizeof (void *));
- args[0] = arg;
- for (i = 1; i < length; i++)
- args[i] = va_arg (aq, char *);
- envp = va_arg (aq, char **);
- va_end (aq);
-
- return execve (path, args, envp);
-}
-#endif
-
-#ifdef L_gcov_execv
-/* A wrapper for the execv function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execv (const char *path, char *const argv[])
-{
- __gcov_flush ();
- return execv (path, argv);
-}
-#endif
-
-#ifdef L_gcov_execvp
-/* A wrapper for the execvp function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execvp (const char *path, char *const argv[])
-{
- __gcov_flush ();
- return execvp (path, argv);
-}
-#endif
-
-#ifdef L_gcov_execve
-/* A wrapper for the execve function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execve (const char *path, char *const argv[], char *const envp[])
-{
- __gcov_flush ();
- return execve (path, argv, envp);
-}
-#endif
-#endif /* inhibit_libc */
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index ef76f9194ea..c18391f106f 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,30 @@
+2013-11-15 Janne Blomqvist <jb@gcc.gnu.org>
+ Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/59108
+ * io/unix.c (regular_file): Don't set O_CREAT when opening a file
+ read-only with unknown status. Mask out O_CREAT when falling back
+ to opening read-only if ACTION= is not set and read-write fails.
+
+2013-11-15 Steve Ellcey <sellcey@mips.com>
+
+ * configure.ac: Do not define HAVE_STRTOLD.
+ * configure: Regenerate.
+
+2013-11-10 Janne Blomqvist <jb@gcc.gnu.org>
+
+ * configure.ac: Check presence of mkostemp.
+ * io/unix.c (set_close_on_exec): New function.
+ (tempfile_open): Use mkostemp and O_CLOEXEC if available, fallback
+ to calling set_close_on_exec.
+ (regular_file): Add O_CLOEXEC to flags if defined.
+ (open_external): Call set_close_on_exec if O_CLOEXEC is not
+ defined.
+ * config.h.in: Regenerated.
+ * configure: Regenerated.
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Regenerated.
+
2013-10-01 Tobias Burnus <burnus@net-b.de>
PR fortran/55469
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index aa23e85e37b..62b9f7abffa 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -87,6 +87,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
am__installdirs = "$(DESTDIR)$(cafexeclibdir)" \
"$(DESTDIR)$(myexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" \
"$(DESTDIR)$(toolexeclibdir)"
@@ -1276,7 +1282,7 @@ all: $(BUILT_SOURCES) config.h
.SUFFIXES:
.SUFFIXES: .F90 .c .f90 .lo .o .obj
-am--refresh:
+am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
@@ -1312,10 +1318,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
- else :; fi
+ @if test ! -f $@; then rm -f stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
@@ -1422,11 +1426,11 @@ clean-toolexeclibLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES)
+libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES) $(EXTRA_libcaf_single_la_DEPENDENCIES)
$(libcaf_single_la_LINK) -rpath $(cafexeclibdir) $(libcaf_single_la_OBJECTS) $(libcaf_single_la_LIBADD) $(LIBS)
-libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES)
+libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES) $(EXTRA_libgfortran_la_DEPENDENCIES)
$(libgfortran_la_LINK) -rpath $(toolexeclibdir) $(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD) $(LIBS)
-libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES)
+libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES) $(EXTRA_libgfortranbegin_la_DEPENDENCIES)
$(libgfortranbegin_la_LINK) -rpath $(myexeclibdir) $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_LIBADD) $(LIBS)
mostlyclean-compile:
@@ -5686,9 +5690,7 @@ uninstall-toolexeclibDATA:
@$(NORMAL_UNINSTALL)
@list='$(toolexeclib_DATA)'; test -n "$(toolexeclibdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- test -n "$$files" || exit 0; \
- echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
+ dir='$(DESTDIR)$(toolexeclibdir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -5760,10 +5762,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
diff --git a/libgfortran/aclocal.m4 b/libgfortran/aclocal.m4
index 8673daa1a9d..351be9d255a 100644
--- a/libgfortran/aclocal.m4
+++ b/libgfortran/aclocal.m4
@@ -1,7 +1,8 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -19,12 +20,15 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
@@ -34,7 +38,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.11.3], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -50,19 +54,21 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.11.3])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
@@ -144,14 +150,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+# 2010, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 10
+# serial 12
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
@@ -191,6 +197,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -255,7 +262,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
break
fi
;;
- msvisualcpp | msvcmsys)
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@@ -320,10 +327,13 @@ AC_DEFUN([AM_DEP_TRACK],
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
+ am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
@@ -545,12 +555,15 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
@@ -569,8 +582,8 @@ AC_SUBST(install_sh)])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -590,7 +603,7 @@ AC_DEFUN([AM_MAINTAINER_MODE],
[disable], [m4_define([am_maintainer_other], [enable])],
[m4_define([am_maintainer_other], [enable])
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
AC_ARG_ENABLE([maintainer-mode],
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
@@ -736,12 +749,15 @@ else
fi
])
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
@@ -764,13 +780,14 @@ esac
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 4
+# serial 5
# _AM_MANGLE_OPTION(NAME)
# -----------------------
@@ -778,13 +795,13 @@ AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
-# ------------------------------
+# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
+# ------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@@ -860,12 +877,14 @@ Check your system clock])
fi
AC_MSG_RESULT(yes)])
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
@@ -888,13 +907,13 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
+# serial 3
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
@@ -903,13 +922,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
+# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -931,10 +950,11 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index d7c5ceb864e..74cf35c1e40 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -606,6 +606,9 @@
/* Define if you have __mingw_snprintf. */
#undef HAVE_MINGW_SNPRINTF
+/* Define to 1 if you have the `mkostemp' function. */
+#undef HAVE_MKOSTEMP
+
/* Define to 1 if you have the `mkstemp' function. */
#undef HAVE_MKSTEMP
diff --git a/libgfortran/configure b/libgfortran/configure
index a54d6ac8d24..bfb2408ffb8 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -654,6 +654,7 @@ CPP
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
+am__nodep
AMDEPBACKSLASH
AMDEP_FALSE
AMDEP_TRUE
@@ -2596,6 +2597,7 @@ as_fn_append ac_func_list " umask"
as_fn_append ac_func_list " getegid"
as_fn_append ac_func_list " secure_getenv"
as_fn_append ac_func_list " __secure_getenv"
+as_fn_append ac_func_list " mkostemp"
as_fn_append ac_header_list " math.h"
# Check that the precious variables saved in the cache have kept the same
# value.
@@ -3386,11 +3388,11 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
-# Always define AMTAR for backward compatibility.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
@@ -3523,6 +3525,7 @@ fi
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
+ am__nodep='_no'
fi
if test "x$enable_dependency_tracking" != xno; then
AMDEP_TRUE=
@@ -4340,6 +4343,7 @@ else
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -4399,7 +4403,7 @@ else
break
fi
;;
- msvisualcpp | msvcmsys)
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@@ -5515,6 +5519,7 @@ else
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -5574,7 +5579,7 @@ else
break
fi
;;
- msvisualcpp | msvcmsys)
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@@ -12337,7 +12342,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12340 "configure"
+#line 12345 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12443,7 +12448,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12446 "configure"
+#line 12451 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -16452,9 +16457,6 @@ $as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h
$as_echo "#define HAVE_STRTOF 1" >>confdefs.h
-$as_echo "#define HAVE_STRTOLD 1" >>confdefs.h
-
-
$as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h
@@ -16469,6 +16471,15 @@ $as_echo "#define HAVE_LOCALTIME_R 1" >>confdefs.h
$as_echo "#define HAVE_GMTIME_R 1" >>confdefs.h
+
+ # At some point, we should differentiate between architectures
+ # like x86, which have long double versions, and alpha/powerpc/etc.,
+ # which don't. For the time being, punt.
+ if test x"long_double_math_on_this_cpu" = x"yes"; then
+
+$as_echo "#define HAVE_STRTOLD 1" >>confdefs.h
+
+ fi
else
@@ -16589,6 +16600,8 @@ done
+
+
fi
# Check strerror_r, cannot be above as versions with two and three arguments exist
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 4609eba8aa1..6acc0f29429 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -267,12 +267,18 @@ if test "x${with_newlib}" = "xyes"; then
# link executables.
AC_DEFINE(HAVE_MKSTEMP, 1, [Define if you have mkstemp.])
AC_DEFINE(HAVE_STRTOF, 1, [Define if you have strtof.])
- AC_DEFINE(HAVE_STRTOLD, 1, [Define if you have strtold.])
AC_DEFINE(HAVE_SNPRINTF, 1, [Define if you have snprintf.])
AC_DEFINE(HAVE_STRCASESTR, 1, [Define if you have strcasestr.])
AC_DEFINE(HAVE_VSNPRINTF, 1, [Define if you have vsnprintf.])
AC_DEFINE(HAVE_LOCALTIME_R, 1, [Define if you have localtime_r.])
AC_DEFINE(HAVE_GMTIME_R, 1, [Define if you have gmtime_r.])
+
+ # At some point, we should differentiate between architectures
+ # like x86, which have long double versions, and alpha/powerpc/etc.,
+ # which don't. For the time being, punt.
+ if test x"long_double_math_on_this_cpu" = x"yes"; then
+ AC_DEFINE(HAVE_STRTOLD, 1, [Define if you have strtold.])
+ fi
else
AC_CHECK_FUNCS_ONCE(getrusage times mkstemp strtof strtold snprintf \
ftruncate chsize chdir getlogin gethostname kill link symlink sleep ttyname \
@@ -280,7 +286,7 @@ else
strcasestr getrlimit gettimeofday stat fstat lstat getpwuid vsnprintf dup \
getcwd localtime_r gmtime_r getpwuid_r ttyname_r clock_gettime \
readlink getgid getpid getppid getuid geteuid umask getegid \
- secure_getenv __secure_getenv)
+ secure_getenv __secure_getenv mkostemp)
fi
# Check strerror_r, cannot be above as versions with two and three arguments exist
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index dd2715b6b6d..c2bc28aed15 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1070,6 +1070,20 @@ unpack_filename (char *cstring, const char *fstring, int len)
}
+/* Set the close-on-exec flag for an existing fd, if the system
+ supports such. */
+
+static void __attribute__ ((unused))
+set_close_on_exec (int fd __attribute__ ((unused)))
+{
+ /* Mingw does not define F_SETFD. */
+#if defined(F_SETFD) && defined(FD_CLOEXEC)
+ if (fd >= 0)
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+}
+
+
/* Helper function for tempfile(). Tries to open a temporary file in
the directory specified by tempdir. If successful, the file name is
stored in fname and the descriptor returned. Returns -1 on
@@ -1109,7 +1123,12 @@ tempfile_open (const char *tempdir, char **fname)
mode_mask = umask (S_IXUSR | S_IRWXG | S_IRWXO);
#endif
+#if defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC)
+ fd = mkostemp (template, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC);
+#else
fd = mkstemp (template);
+ set_close_on_exec (fd);
+#endif
#ifdef HAVE_UMASK
(void) umask (mode_mask);
@@ -1119,6 +1138,13 @@ tempfile_open (const char *tempdir, char **fname)
fd = -1;
int count = 0;
size_t slashlen = strlen (slash);
+ int flags = O_RDWR | O_CREAT | O_EXCL;
+#if defined(HAVE_CRLF) && defined(O_BINARY)
+ flags |= O_BINARY;
+#endif
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
do
{
snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX",
@@ -1142,14 +1168,12 @@ tempfile_open (const char *tempdir, char **fname)
continue;
}
-#if defined(HAVE_CRLF) && defined(O_BINARY)
- fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
- S_IRUSR | S_IWUSR);
-#else
- fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
-#endif
+ fd = open (template, flags, S_IRUSR | S_IWUSR);
}
while (fd == -1 && errno == EEXIST);
+#ifndef O_CLOEXEC
+ set_close_on_exec (fd);
+#endif
#endif /* HAVE_MKSTEMP */
*fname = template;
@@ -1221,7 +1245,7 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
char path[min(PATH_MAX, opp->file_len + 1)];
int mode;
int rwflag;
- int crflag;
+ int crflag, crflag2;
int fd;
int err;
@@ -1273,8 +1297,6 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
}
#endif
- rwflag = 0;
-
switch (flags->action)
{
case ACTION_READ:
@@ -1305,8 +1327,10 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
break;
case STATUS_UNKNOWN:
- case STATUS_SCRATCH:
- crflag = O_CREAT;
+ if (rwflag == O_RDONLY)
+ crflag = 0;
+ else
+ crflag = O_CREAT;
break;
case STATUS_REPLACE:
@@ -1314,6 +1338,8 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
break;
default:
+ /* Note: STATUS_SCRATCH is handled by tempfile () and should
+ never be seen here. */
internal_error (&opp->common, "regular_file(): Bad status");
}
@@ -1323,6 +1349,10 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
crflag |= O_BINARY;
#endif
+#ifdef O_CLOEXEC
+ crflag |= O_CLOEXEC;
+#endif
+
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
fd = open (path, rwflag | crflag, mode);
if (flags->action != ACTION_UNSPECIFIED)
@@ -1338,14 +1368,18 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
/* retry for read-only access */
rwflag = O_RDONLY;
- fd = open (path, rwflag | crflag, mode);
+ if (flags->status == STATUS_UNKNOWN)
+ crflag2 = crflag & ~(O_CREAT);
+ else
+ crflag2 = crflag;
+ fd = open (path, rwflag | crflag2, mode);
if (fd >=0)
{
flags->action = ACTION_READ;
return fd; /* success */
}
- if (errno != EACCES)
+ if (errno != EACCES && errno != ENOENT)
return fd; /* failure */
/* retry for write-only access */
@@ -1386,6 +1420,9 @@ open_external (st_parameter_open *opp, unit_flags *flags)
/* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
* if it succeeds */
fd = regular_file (opp, flags);
+#ifndef O_CLOEXEC
+ set_close_on_exec (fd);
+#endif
}
if (fd < 0)
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 9a8a1b45530..92fe175cd78 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -413,12 +413,12 @@ endif
endif
if LIBGO_IS_LINUX
-runtime_netpoll_files = netpoll.c runtime/netpoll_epoll.c
+runtime_netpoll_files = runtime/netpoll_epoll.c
else
-if LIBGO_IS_DARWIN
-runtime_netpoll_files = netpoll.c runtime/netpoll_kqueue.c
+if LIBGO_IS_SOLARIS
+runtime_netpoll_files = runtime/netpoll_select.c
else
-runtime_netpoll_files = runtime/netpoll_stub.c
+runtime_netpoll_files = runtime/netpoll_kqueue.c
endif
endif
@@ -515,6 +515,7 @@ runtime_files = \
malloc.c \
map.c \
mprof.c \
+ netpoll.c \
reflect.c \
runtime1.c \
sema.c \
@@ -670,26 +671,6 @@ go_mime_files = \
go/mime/type.go \
go/mime/type_unix.go
-if LIBGO_IS_RTEMS
-go_net_fd_os_file = go/net/fd_select.go
-go_net_newpollserver_file = go/net/newpollserver_rtems.go
-else # !LIBGO_IS_RTEMS
-if LIBGO_IS_LINUX
-go_net_fd_os_file =
-go_net_newpollserver_file =
-else # !LIBGO_IS_LINUX && !LIBGO_IS_RTEMS
-if LIBGO_IS_NETBSD
-go_net_fd_os_file =
-go_net_newpollserver_file =
-else # !LIBGO_IS_NETBSD && !LIBGO_IS_LINUX && !LIBGO_IS_RTEMS
-# By default use select with pipes. Most systems should have
-# something better.
-go_net_fd_os_file = go/net/fd_select.go
-go_net_newpollserver_file =
-endif # !LIBGO_IS_NETBSD
-endif # !LIBGO_IS_LINUX
-endif # !LIBGO_IS_RTEMS
-
if LIBGO_IS_LINUX
go_net_cgo_file = go/net/cgo_linux.go
go_net_sock_file = go/net/sock_linux.go
@@ -770,9 +751,13 @@ else
if LIBGO_IS_DARWIN
go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
else
+if LIBGO_IS_SOLARIS
+go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
+else
go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
endif
endif
+endif
go_net_files = \
go/net/cgo_unix.go \
@@ -783,10 +768,8 @@ go_net_files = \
go/net/dnsclient_unix.go \
go/net/dnsconfig_unix.go \
go/net/dnsmsg.go \
- $(go_net_newpollserver_file) \
go/net/fd_mutex.go \
go/net/fd_unix.go \
- $(go_net_fd_os_file) \
go/net/file_unix.go \
go/net/hosts.go \
go/net/interface.go \
@@ -1296,7 +1279,7 @@ go_go_build_files = \
go/go/build/build.go \
go/go/build/doc.go \
go/go/build/read.go \
- syslist.go
+ go/go/build/syslist.go
go_go_doc_files = \
go/go/doc/comment.go \
go/go/doc/doc.go \
@@ -2773,15 +2756,6 @@ go/build/check: $(CHECK_DEPS)
@$(CHECK)
.PHONY: go/build/check
-syslist.go: s-syslist; @true
-s-syslist: Makefile
- echo '// Generated automatically by make.' >syslist.go.tmp
- echo 'package build' >>syslist.go.tmp
- echo 'const goosList = "$(GOOS)"' >>syslist.go.tmp
- echo 'const goarchList = "$(GOARCH)"' >>syslist.go.tmp
- $(SHELL) $(srcdir)/../move-if-change syslist.go.tmp syslist.go
- $(STAMP) $@
-
@go_include@ go/doc.lo.dep
go/doc.lo.dep: $(go_go_doc_files)
$(BUILDDEPS)
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 63e78b4e77a..edbc2e1ff8a 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -179,12 +179,9 @@ libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \
@LIBGO_IS_LINUX_TRUE@am__objects_1 = lock_futex.lo thread-linux.lo
@HAVE_SYS_MMAN_H_FALSE@am__objects_2 = mem_posix_memalign.lo
@HAVE_SYS_MMAN_H_TRUE@am__objects_2 = mem.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_LINUX_FALSE@am__objects_3 = \
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_LINUX_FALSE@ netpoll_stub.lo
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_3 = \
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@ netpoll.lo \
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@ netpoll_kqueue.lo
-@LIBGO_IS_LINUX_TRUE@am__objects_3 = netpoll.lo netpoll_epoll.lo
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_3 = netpoll_kqueue.lo
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_3 = netpoll_select.lo
+@LIBGO_IS_LINUX_TRUE@am__objects_3 = netpoll_epoll.lo
@LIBGO_IS_RTEMS_TRUE@am__objects_4 = rtems-task-variable-add.lo
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-none.lo
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-bsd.lo
@@ -220,8 +217,9 @@ am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \
mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo \
$(am__objects_3) panic.lo parfor.lo print.lo proc.lo \
runtime.lo signal_unix.lo thread.lo yield.lo $(am__objects_4) \
- iface.lo malloc.lo map.lo mprof.lo reflect.lo runtime1.lo \
- sema.lo sigqueue.lo string.lo time.lo $(am__objects_5)
+ iface.lo malloc.lo map.lo mprof.lo netpoll.lo reflect.lo \
+ runtime1.lo sema.lo sigqueue.lo string.lo time.lo \
+ $(am__objects_5)
am_libgo_la_OBJECTS = $(am__objects_6)
libgo_la_OBJECTS = $(am_libgo_la_OBJECTS)
libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -752,9 +750,9 @@ toolexeclibgounicode_DATA = \
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-irix.c
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-bsd.c
@LIBGO_IS_LINUX_TRUE@runtime_getncpu_file = runtime/getncpu-linux.c
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_LINUX_FALSE@runtime_netpoll_files = runtime/netpoll_stub.c
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_netpoll_files = netpoll.c runtime/netpoll_kqueue.c
-@LIBGO_IS_LINUX_TRUE@runtime_netpoll_files = netpoll.c runtime/netpoll_epoll.c
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_netpoll_files = runtime/netpoll_kqueue.c
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@runtime_netpoll_files = runtime/netpoll_select.c
+@LIBGO_IS_LINUX_TRUE@runtime_netpoll_files = runtime/netpoll_epoll.c
runtime_files = \
runtime/go-append.c \
runtime/go-assert.c \
@@ -848,6 +846,7 @@ runtime_files = \
malloc.c \
map.c \
mprof.c \
+ netpoll.c \
reflect.c \
runtime1.c \
sema.c \
@@ -962,16 +961,6 @@ go_mime_files = \
go/mime/type.go \
go/mime/type_unix.go
-# By default use select with pipes. Most systems should have
-# something better.
-@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = go/net/fd_select.go
-@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file =
-@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file =
-@LIBGO_IS_RTEMS_TRUE@go_net_fd_os_file = go/net/fd_select.go
-@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file =
-@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file =
-@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file =
-@LIBGO_IS_RTEMS_TRUE@go_net_newpollserver_file = go/net/newpollserver_rtems.go
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_netbsd.go
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go
@@ -1006,7 +995,8 @@ go_mime_files = \
@LIBGO_IS_LINUX_TRUE@go_net_interface_file = go/net/interface_linux.go
@LIBGO_IS_LINUX_FALSE@go_net_cloexec_file = go/net/sys_cloexec.go
@LIBGO_IS_LINUX_TRUE@go_net_cloexec_file = go/net/sock_cloexec.go
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
@LIBGO_IS_OPENBSD_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_openbsd.go
go_net_files = \
@@ -1018,10 +1008,8 @@ go_net_files = \
go/net/dnsclient_unix.go \
go/net/dnsconfig_unix.go \
go/net/dnsmsg.go \
- $(go_net_newpollserver_file) \
go/net/fd_mutex.go \
go/net/fd_unix.go \
- $(go_net_fd_os_file) \
go/net/file_unix.go \
go/net/hosts.go \
go/net/interface.go \
@@ -1476,7 +1464,7 @@ go_go_build_files = \
go/go/build/build.go \
go/go/build/doc.go \
go/go/build/read.go \
- syslist.go
+ go/go/build/syslist.go
go_go_doc_files = \
go/go/doc/comment.go \
@@ -2482,7 +2470,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_epoll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_kqueue.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_stub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_select.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/panic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parfor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@
@@ -3110,13 +3098,6 @@ msize.lo: runtime/msize.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o msize.lo `test -f 'runtime/msize.c' || echo '$(srcdir)/'`runtime/msize.c
-netpoll_stub.lo: runtime/netpoll_stub.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_stub.lo -MD -MP -MF $(DEPDIR)/netpoll_stub.Tpo -c -o netpoll_stub.lo `test -f 'runtime/netpoll_stub.c' || echo '$(srcdir)/'`runtime/netpoll_stub.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_stub.Tpo $(DEPDIR)/netpoll_stub.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/netpoll_stub.c' object='netpoll_stub.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netpoll_stub.lo `test -f 'runtime/netpoll_stub.c' || echo '$(srcdir)/'`runtime/netpoll_stub.c
-
netpoll_kqueue.lo: runtime/netpoll_kqueue.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_kqueue.lo -MD -MP -MF $(DEPDIR)/netpoll_kqueue.Tpo -c -o netpoll_kqueue.lo `test -f 'runtime/netpoll_kqueue.c' || echo '$(srcdir)/'`runtime/netpoll_kqueue.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_kqueue.Tpo $(DEPDIR)/netpoll_kqueue.Plo
@@ -3124,6 +3105,13 @@ netpoll_kqueue.lo: runtime/netpoll_kqueue.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netpoll_kqueue.lo `test -f 'runtime/netpoll_kqueue.c' || echo '$(srcdir)/'`runtime/netpoll_kqueue.c
+netpoll_select.lo: runtime/netpoll_select.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_select.lo -MD -MP -MF $(DEPDIR)/netpoll_select.Tpo -c -o netpoll_select.lo `test -f 'runtime/netpoll_select.c' || echo '$(srcdir)/'`runtime/netpoll_select.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_select.Tpo $(DEPDIR)/netpoll_select.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/netpoll_select.c' object='netpoll_select.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netpoll_select.lo `test -f 'runtime/netpoll_select.c' || echo '$(srcdir)/'`runtime/netpoll_select.c
+
netpoll_epoll.lo: runtime/netpoll_epoll.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_epoll.lo -MD -MP -MF $(DEPDIR)/netpoll_epoll.Tpo -c -o netpoll_epoll.lo `test -f 'runtime/netpoll_epoll.c' || echo '$(srcdir)/'`runtime/netpoll_epoll.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_epoll.Tpo $(DEPDIR)/netpoll_epoll.Plo
@@ -5143,15 +5131,6 @@ go/build/check: $(CHECK_DEPS)
@$(CHECK)
.PHONY: go/build/check
-syslist.go: s-syslist; @true
-s-syslist: Makefile
- echo '// Generated automatically by make.' >syslist.go.tmp
- echo 'package build' >>syslist.go.tmp
- echo 'const goosList = "$(GOOS)"' >>syslist.go.tmp
- echo 'const goarchList = "$(GOARCH)"' >>syslist.go.tmp
- $(SHELL) $(srcdir)/../move-if-change syslist.go.tmp syslist.go
- $(STAMP) $@
-
@go_include@ go/doc.lo.dep
go/doc.lo.dep: $(go_go_doc_files)
$(BUILDDEPS)
diff --git a/libgo/go/go/build/syslist.go b/libgo/go/go/build/syslist.go
new file mode 100644
index 00000000000..a322c88c427
--- /dev/null
+++ b/libgo/go/go/build/syslist.go
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package build
+
+const goosList = "darwin dragonfly freebsd linux netbsd openbsd plan9 windows solaris "
+const goarchList = "386 amd64 arm alpha m68k mipso32 mipsn32 mipsn64 mipso64 ppc ppc64 sparc sparc64 "
diff --git a/libgo/go/net/fd_unix.go b/libgo/go/net/fd_unix.go
index 9ed4f753649..4911ab0abe3 100644
--- a/libgo/go/net/fd_unix.go
+++ b/libgo/go/net/fd_unix.go
@@ -410,7 +410,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
var tryDupCloexec = int32(1)
func dupCloseOnExec(fd int) (newfd int, err error) {
- if atomic.LoadInt32(&tryDupCloexec) == 1 {
+ if atomic.LoadInt32(&tryDupCloexec) == 1 && syscall.F_DUPFD_CLOEXEC != 0 {
r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
// On OS X 10.6 and below (but we only support
diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go
index 972df364ae7..882e3da1517 100644
--- a/libgo/go/os/os_test.go
+++ b/libgo/go/os/os_test.go
@@ -1142,6 +1142,7 @@ func TestReadAtEOF(t *testing.T) {
}
func testKillProcess(t *testing.T, processKiller func(p *Process)) {
+ t.Skip("gccgo does not have a go command")
dir, err := ioutil.TempDir("", "go-build")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index a1713df9b57..025729ccad1 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -220,6 +220,11 @@ if ! grep '^const O_CLOEXEC' ${OUT} >/dev/null 2>&1; then
echo "const O_CLOEXEC = 0" >> ${OUT}
fi
+# The os package requires F_DUPFD_CLOEXEC to be defined.
+if ! grep '^const F_DUPFD_CLOEXEC' ${OUT} >/dev/null 2>&1; then
+ echo "const F_DUPFD_CLOEXEC = 0" >> ${OUT}
+fi
+
# These flags can be lost on i386 GNU/Linux when using
# -D_FILE_OFFSET_BITS=64, because we see "#define F_SETLK F_SETLK64"
# before we see the definition of F_SETLK64.
diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c
index 8ca3c7efcd7..c49704df416 100644
--- a/libgo/runtime/go-caller.c
+++ b/libgo/runtime/go-caller.c
@@ -101,6 +101,13 @@ __go_get_backtrace_state ()
const char *filename;
filename = (const char *) runtime_progname ();
+
+ /* If there is no '/' in FILENAME, it was found on PATH, and
+ might not be the same as the file with the same name in the
+ current directory. */
+ if (__builtin_strchr (filename, '/') == NULL)
+ filename = NULL;
+
back_state = backtrace_create_state (filename, 1, error_callback, NULL);
}
runtime_unlock (&back_state_lock);
diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc
index d349f4749fa..b8b4a2dc373 100644
--- a/libgo/runtime/malloc.goc
+++ b/libgo/runtime/malloc.goc
@@ -75,10 +75,10 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
runtime_exitsyscall();
m = runtime_m();
incallback = true;
- flag |= FlagNoGC;
+ flag |= FlagNoInvokeGC;
}
- if(runtime_gcwaiting() && g != m->g0 && m->locks == 0 && !(flag & FlagNoGC)) {
+ if(runtime_gcwaiting() && g != m->g0 && m->locks == 0 && !(flag & FlagNoInvokeGC)) {
runtime_gosched();
m = runtime_m();
}
diff --git a/libgo/runtime/malloc.h b/libgo/runtime/malloc.h
index 45c4c09c147..e1a5be99919 100644
--- a/libgo/runtime/malloc.h
+++ b/libgo/runtime/malloc.h
@@ -515,3 +515,4 @@ void runtime_memorydump(void);
void runtime_proc_scan(void (*)(Obj));
void runtime_time_scan(void (*)(Obj));
+void runtime_netpoll_scan(void (*)(Obj));
diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c
index 3edcee9c397..865f1930489 100644
--- a/libgo/runtime/mgc0.c
+++ b/libgo/runtime/mgc0.c
@@ -1491,6 +1491,7 @@ addroots(void)
runtime_proc_scan(addroot);
runtime_MProf_Mark(addroot);
runtime_time_scan(addroot);
+ runtime_netpoll_scan(addroot);
// MSpan.types
allspans = runtime_mheap.allspans;
diff --git a/libgo/runtime/netpoll_epoll.c b/libgo/runtime/netpoll_epoll.c
index b98aa818c89..2acbca32322 100644
--- a/libgo/runtime/netpoll_epoll.c
+++ b/libgo/runtime/netpoll_epoll.c
@@ -11,6 +11,7 @@
#include "runtime.h"
#include "defs.h"
+#include "malloc.h"
#ifndef EPOLLRDHUP
#define EPOLLRDHUP 0x2000
@@ -156,3 +157,9 @@ retry:
goto retry;
return gp;
}
+
+void
+runtime_netpoll_scan(void (*addroot)(Obj))
+{
+ USED(addroot);
+}
diff --git a/libgo/runtime/netpoll_kqueue.c b/libgo/runtime/netpoll_kqueue.c
index 78901611884..5d3f85617b6 100644
--- a/libgo/runtime/netpoll_kqueue.c
+++ b/libgo/runtime/netpoll_kqueue.c
@@ -5,8 +5,8 @@
// +build darwin dragonfly freebsd netbsd openbsd
#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
+#include "defs.h"
+#include "malloc.h"
// Integrated network poller (kqueue-based implementation).
@@ -102,3 +102,9 @@ retry:
goto retry;
return gp;
}
+
+void
+runtime_netpoll_scan(void (*addroot)(Obj))
+{
+ USED(addroot);
+}
diff --git a/libgo/runtime/netpoll_select.c b/libgo/runtime/netpoll_select.c
new file mode 100644
index 00000000000..c330f28418f
--- /dev/null
+++ b/libgo/runtime/netpoll_select.c
@@ -0,0 +1,223 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build solaris
+
+#include "config.h"
+
+#include <errno.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "runtime.h"
+#include "malloc.h"
+
+static Lock selectlock;
+static int rdwake;
+static int wrwake;
+static fd_set fds;
+static PollDesc **data;
+static int allocated;
+
+void
+runtime_netpollinit(void)
+{
+ int p[2];
+ int fl;
+
+ FD_ZERO(&fds);
+ allocated = 128;
+ data = runtime_mallocgc(allocated * sizeof(PollDesc *), 0,
+ FlagNoScan|FlagNoProfiling|FlagNoInvokeGC);
+
+ if(pipe(p) < 0)
+ runtime_throw("netpollinit: failed to create pipe");
+ rdwake = p[0];
+ wrwake = p[1];
+
+ fl = fcntl(rdwake, F_GETFL);
+ if(fl < 0)
+ runtime_throw("netpollinit: fcntl failed");
+ fl |= O_NONBLOCK;
+ if(fcntl(rdwake, F_SETFL, fl))
+ runtime_throw("netpollinit: fcntl failed");
+ fcntl(rdwake, F_SETFD, FD_CLOEXEC);
+
+ fl = fcntl(wrwake, F_GETFL);
+ if(fl < 0)
+ runtime_throw("netpollinit: fcntl failed");
+ fl |= O_NONBLOCK;
+ if(fcntl(wrwake, F_SETFL, fl))
+ runtime_throw("netpollinit: fcntl failed");
+ fcntl(wrwake, F_SETFD, FD_CLOEXEC);
+
+ FD_SET(rdwake, &fds);
+}
+
+int32
+runtime_netpollopen(uintptr fd, PollDesc *pd)
+{
+ byte b;
+
+ runtime_lock(&selectlock);
+
+ if((int)fd >= allocated) {
+ int c;
+ PollDesc **n;
+
+ c = allocated;
+
+ runtime_unlock(&selectlock);
+
+ while((int)fd >= c)
+ c *= 2;
+ n = runtime_mallocgc(c * sizeof(PollDesc *), 0,
+ FlagNoScan|FlagNoProfiling|FlagNoInvokeGC);
+
+ runtime_lock(&selectlock);
+
+ if(c > allocated) {
+ __builtin_memcpy(n, data, allocated * sizeof(PollDesc *));
+ allocated = c;
+ data = n;
+ }
+ }
+ FD_SET(fd, &fds);
+ data[fd] = pd;
+
+ runtime_unlock(&selectlock);
+
+ b = 0;
+ write(wrwake, &b, sizeof b);
+
+ return 0;
+}
+
+int32
+runtime_netpollclose(uintptr fd)
+{
+ byte b;
+
+ runtime_lock(&selectlock);
+
+ FD_CLR(fd, &fds);
+ data[fd] = nil;
+
+ runtime_unlock(&selectlock);
+
+ b = 0;
+ write(wrwake, &b, sizeof b);
+
+ return 0;
+}
+
+G*
+runtime_netpoll(bool block)
+{
+ fd_set rfds, wfds, efds, tfds;
+ struct timeval timeout;
+ struct timeval *pt;
+ int max, c, i;
+ G *gp;
+ int32 mode;
+ byte b;
+ struct stat st;
+
+ retry:
+ runtime_lock(&selectlock);
+
+ max = allocated;
+
+ if(max == 0) {
+ runtime_unlock(&selectlock);
+ return nil;
+ }
+
+ __builtin_memcpy(&rfds, &fds, sizeof fds);
+
+ runtime_unlock(&selectlock);
+
+ __builtin_memcpy(&wfds, &rfds, sizeof fds);
+ FD_CLR(rdwake, &wfds);
+ __builtin_memcpy(&efds, &wfds, sizeof fds);
+
+ __builtin_memcpy(&tfds, &wfds, sizeof fds);
+
+ __builtin_memset(&timeout, 0, sizeof timeout);
+ pt = &timeout;
+ if(block)
+ pt = nil;
+
+ c = select(max, &rfds, &wfds, &efds, pt);
+ if(c < 0) {
+ if(errno == EBADF) {
+ // Some file descriptor has been closed.
+ // Check each one, and treat each closed
+ // descriptor as ready for read/write.
+ c = 0;
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&efds);
+ for(i = 0; i < max; i++) {
+ if(FD_ISSET(i, &tfds)
+ && fstat(i, &st) < 0
+ && errno == EBADF) {
+ FD_SET(i, &rfds);
+ FD_SET(i, &wfds);
+ c += 2;
+ }
+ }
+ }
+ else {
+ if(errno != EINTR)
+ runtime_printf("runtime: select failed with %d\n", errno);
+ goto retry;
+ }
+ }
+ gp = nil;
+ for(i = 0; i < max && c > 0; i++) {
+ mode = 0;
+ if(FD_ISSET(i, &rfds)) {
+ mode += 'r';
+ --c;
+ }
+ if(FD_ISSET(i, &wfds)) {
+ mode += 'w';
+ --c;
+ }
+ if(FD_ISSET(i, &efds)) {
+ mode = 'r' + 'w';
+ --c;
+ }
+ if(i == rdwake) {
+ while(read(rdwake, &b, sizeof b) > 0)
+ ;
+ continue;
+ }
+ if(mode) {
+ PollDesc *pd;
+
+ runtime_lock(&selectlock);
+ pd = data[i];
+ runtime_unlock(&selectlock);
+ if(pd != nil)
+ runtime_netpollready(&gp, pd, mode);
+ }
+ }
+ if(block && gp == nil)
+ goto retry;
+ return gp;
+}
+
+void
+runtime_netpoll_scan(void (*addroot)(Obj))
+{
+ addroot((Obj){(byte*)&data, sizeof data, 0});
+}
diff --git a/libgo/runtime/netpoll_stub.c b/libgo/runtime/netpoll_stub.c
index 84eef754c8d..a88c9f5b9c2 100644
--- a/libgo/runtime/netpoll_stub.c
+++ b/libgo/runtime/netpoll_stub.c
@@ -5,6 +5,7 @@
// +build plan9
#include "runtime.h"
+#include "malloc.h"
// Polls for ready network connections.
// Returns list of goroutines that become runnable.
@@ -16,3 +17,9 @@ runtime_netpoll(bool block)
USED(block);
return nil;
}
+
+void
+runtime_netpoll_scan(void (*addroot)(Obj))
+{
+ USED(addroot);
+}
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 7011f14f8a5..de2a54bfa5e 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -1983,7 +1983,10 @@ runtime_exitsyscall(void)
#endif
gp->gcnext_sp = nil;
runtime_memclr(&gp->gcregs, sizeof gp->gcregs);
- m->p->syscalltick++;
+
+ // Don't refer to m again, we might be running on a different
+ // thread after returning from runtime_mcall.
+ runtime_m()->p->syscalltick++;
}
static bool
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index cda181e1066..5a0aba8f0b2 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,13 @@
+2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
+
+ * configure: Regenerate.
+
+2013-11-12 Uros Bizjak <ubizjak@gmail.com>
+
+ * cp-demangle.c (d_copy_templates): Cast result of malloc
+ to (struct d_print_template *).
+ (d_print_comp): Cast result of realloc to (struct d_saved scope *).
+
2013-10-29 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/58689
@@ -6,7 +16,7 @@
2013-10-27 Gerald Pfeifer <gerald@pfeifer.com>
* testsuite/test-demangle.c: Include unistd.h.
-
+
2013-10-25 Gary Benson <gbenson@redhat.com>
* cp-demangle.c (struct d_saved_scope): New structure.
@@ -18,10 +28,9 @@
(d_copy_templates): New function.
(d_print_comp): New variables saved_templates and
need_template_restore.
- [DEMANGLE_COMPONENT_REFERENCE,
- DEMANGLE_COMPONENT_RVALUE_REFERENCE]: Capture scope the first
- time the component is traversed, and use the captured scope for
- subsequent traversals.
+ [DEMANGLE_COMPONENT_REFERENCE, DEMANGLE_COMPONENT_RVALUE_REFERENCE]:
+ Capture scope the first time the component is traversed, and use the
+ captured scope for subsequent traversals.
* testsuite/demangle-expected: Add regression test.
2013-10-23 Gerald Pfeifer <gerald@pfeifer.com>
diff --git a/libiberty/configure b/libiberty/configure
index b71141a98b0..8ea54da6613 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -4927,9 +4927,6 @@ case "${host}" in
i[34567]86-*-* | x86_64-*-*)
PICFLAG=-fpic
;;
- m68k-*-*)
- PICFLAG=-fpic
- ;;
# FIXME: Override -fPIC default in libgcc only?
sh-*-linux* | sh[2346lbe]*-*-linux*)
PICFLAG=-fpic
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 7be98048565..cbe4d8c9f63 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -3968,7 +3968,7 @@ d_copy_templates (struct d_print_info *dpi)
for (src = dpi->templates; src != NULL; src = src->next)
{
struct d_print_template *dst =
- malloc (sizeof (struct d_print_template));
+ (struct d_print_template *) malloc (sizeof (struct d_print_template));
if (dst == NULL)
{
@@ -4381,14 +4381,16 @@ d_print_comp (struct d_print_info *dpi, int options,
if (scope == NULL)
{
+ size_t size;
+
/* This is the first time SUB has been traversed.
We need to capture the current templates so
they can be restored if SUB is reentered as a
substitution. */
++dpi->num_saved_scopes;
- scopes = realloc (dpi->saved_scopes,
- sizeof (struct d_saved_scope)
- * dpi->num_saved_scopes);
+ size = sizeof (struct d_saved_scope) * dpi->num_saved_scopes;
+ scopes = (struct d_saved_scope *) realloc (dpi->saved_scopes,
+ size);
if (scopes == NULL)
{
d_print_error (dpi);
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index 28f8a227f20..e6dc6468d19 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,13 @@
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/powerpc/sjlj.S [__powerpc64__ && _CALL_ELF == 2]:
+ (FUNC): Define ELFv2 variant.
+ (END): Likewise.
+ (HIDDEN): Likewise.
+ (CALL): Likewise.
+ (BASE): Likewise.
+ (LR_SAVE): Likewise.
+
2013-09-20 Alan Modra <amodra@gmail.com>
* configure: Regenerate.
diff --git a/libitm/config/powerpc/sjlj.S b/libitm/config/powerpc/sjlj.S
index 1f4a100f943..4a0b43dbbbd 100644
--- a/libitm/config/powerpc/sjlj.S
+++ b/libitm/config/powerpc/sjlj.S
@@ -26,7 +26,26 @@
#include "asmcfi.h"
-#if defined(__powerpc64__) && defined(__ELF__)
+#if defined(__powerpc64__) && _CALL_ELF == 2
+.macro FUNC name
+ .globl \name
+ .type \name, @function
+\name:
+0: addis 2,12,(.TOC.-0b)@ha
+ addi 2,2,(.TOC.-0b)@l
+ .localentry \name, . - \name
+.endm
+.macro END name
+ .size \name, . - \name
+.endm
+.macro HIDDEN name
+ .hidden \name
+.endm
+.macro CALL name
+ bl \name
+ nop
+.endm
+#elif defined(__powerpc64__) && defined(__ELF__)
.macro FUNC name
.globl \name, .\name
.section ".opd","aw"
@@ -117,6 +136,9 @@ _$0:
#if defined(_CALL_AIXDESC)
# define BASE 6*WS
# define LR_SAVE 2*WS
+#elif _CALL_ELF == 2
+# define BASE 6*WS
+# define LR_SAVE 2*WS
#elif defined(_CALL_SYSV)
# define BASE 2*WS
# define LR_SAVE 1*WS
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 3d790fe75d7..a0a8a8e6db0 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,23 @@
+2013-11-15 Kostya Serebryany <kcc@google.com>
+
+ PR sanitizer/58994
+ Backport from upstream revision 194573
+ * asan/asan_interceptors.cc (COMMON_INTERCEPTOR_ENTER): Fall
+ back to the original functions in the common libsanitizer
+ interceptors and the __cxa_atexit() interceptor on Darwin.
+
+2013-11-13 Peter Bergner <bergner@vnet.ibm.com>
+
+ PR sanitizer/59009
+ * sanitizer_common/sanitizer_platform_limits_posix.cc: Temporarily
+ ifdef out more source.
+
+2013-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ * sanitizer_common/sanitizer_platform_limits_linux.cc: Temporarily
+ ifdef out almost the whole source.
+ * sanitizer_common/sanitizer_common_syscalls.inc: Likewise.
+
2013-11-05 H.J. Lu <hongjiu.lu@intel.com>
PR sanitizer/59018
diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cc
index 6fa968da0a3..72f7aae814a 100644
--- a/libsanitizer/asan/asan_interceptors.cc
+++ b/libsanitizer/asan/asan_interceptors.cc
@@ -106,12 +106,13 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
ASAN_WRITE_RANGE(ptr, size)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size)
-#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
- do { \
- if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \
- ctx = 0; \
- (void) ctx; \
- ENSURE_ASAN_INITED(); \
+#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
+ do { \
+ if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \
+ ctx = 0; \
+ (void) ctx; \
+ if (SANITIZER_MAC && !asan_inited) return REAL(func)(__VA_ARGS__); \
+ ENSURE_ASAN_INITED(); \
} while (false)
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
do { \
@@ -634,6 +635,9 @@ static void AtCxaAtexit(void *unused) {
#if ASAN_INTERCEPT___CXA_ATEXIT
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
void *dso_handle) {
+#if SANITIZER_MAC
+ if (!asan_inited) return REAL(__cxa_atexit)(func, arg, dso_handle);
+#endif
ENSURE_ASAN_INITED();
int res = REAL(__cxa_atexit)(func, arg, dso_handle);
REAL(__cxa_atexit)(AtCxaAtexit, 0, 0);
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
index bc097c847d4..ae6a6304dba 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
@@ -58,6 +58,8 @@
# define COMMON_SYSCALL_POST_FORK(res)
#endif
+#ifdef SYSCALL_INTERCEPTION
+
// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
extern "C" {
@@ -2722,6 +2724,8 @@ POST_SYSCALL(vfork)(long res) {
}
} // extern "C"
+#endif
+
#undef PRE_SYSCALL
#undef PRE_READ
#undef PRE_WRITE
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
index 98702436c4f..a69b11f89fe 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
@@ -14,6 +14,7 @@
// userspace headers.
// Most "normal" includes go in sanitizer_platform_limits_posix.cc
+#ifdef SYSCALL_INTERCEPTION
#include "sanitizer_platform.h"
#if SANITIZER_LINUX
@@ -43,3 +44,4 @@ namespace __sanitizer {
} // namespace __sanitizer
#endif // SANITIZER_LINUX
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
index b771583d064..950ab58cca5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -855,6 +855,7 @@ CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags);
CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer);
#endif
+#ifdef SYSCALL_INTERCEPTION
#if SANITIZER_LINUX
CHECK_TYPE_SIZE(__sysctl_args);
CHECK_SIZE_AND_OFFSET(__sysctl_args, name);
@@ -872,6 +873,7 @@ CHECK_TYPE_SIZE(__kernel_off_t);
CHECK_TYPE_SIZE(__kernel_loff_t);
CHECK_TYPE_SIZE(__kernel_fd_set);
#endif
+#endif
#if !SANITIZER_ANDROID
CHECK_TYPE_SIZE(wordexp_t);
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 31bffa55022..923294cc03b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,156 @@
+2013-11-15 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/bits/stl_bvector.h (vector<bool>::emplace_back()): LWG 2187:
+ Define.
+ (vector<bool>::emplace()): Likewise.
+ * testsuite/23_containers/vector/bool/emplace.cc: New.
+
+2013-11-15 Ondřej Bílka <neleai@seznam.cz>
+ Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * doc/xml/manual/build_hacking.xml: Fix documentation typos.
+ * doc/xml/manual/configure.xml: Likewise.
+ * include/bits/atomic_base.h: Fix typos in comments.
+ * include/bits/random.h: Likewise.
+ * include/ext/cast.h: Likewise.
+ * libsupc++/cxxabi.h: Likewise.
+ * testsuite/ext/pb_ds/example/hash_illegal_resize.cc: Likewise.
+ * testsuite/tr1/5_numerical_facilities/special_functions/testcase.h:
+ Likewise.
+ * testsuite/util/exception/safety.h: Likewise.
+ * testsuite/util/testsuite_containers.h: Likewise.
+ * testsuite/util/testsuite_hooks.cc: Likewise.
+
+2013-11-15 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/bits/stl_map.h (map): Implement C++11 allocator-aware
+ container requirements.
+ * include/bits/stl_multimap.h (multimap): Likewise.
+ * include/bits/stl_multiset.h (multiset): Likewise.
+ * include/bits/stl_set.h (set): Likewise.
+ * include/bits/stl_tree.h (_Rb_tree_node): Use __aligned_buffer and
+ add accessors for value.
+ (_Rb_tree_iterator, _Rb_tree_const_iterator): Use _Rb_tree_node
+ accessors.
+ (_Rb_tree): Use allocator_traits and implement support for sets and
+ maps the be allocator-aware.
+ * include/bits/forward_list.h (_Fwd_list_base::_M_create_node): Do
+ not zero-initialize storage buffer.
+ * include/bits/hashtable_policy.h (_Hashtable_alloc::_M_allocate_node):
+ Likewise.
+ * include/bits/stl_vector.h (vector(vector&&, const allocator_type&)):
+ Add conditional noexcept specification.
+ * doc/xml/manual/status_cxx2011.xml: Update status of containers.
+ * testsuite/util/testsuite_allocator.h: Re-indent.
+ * testsuite/23_containers/forward_list/allocator/copy.cc: Test
+ allocator-extended copy constructor.
+ * testsuite/23_containers/unordered_map/allocator/copy.cc: Likewise.
+ * testsuite/23_containers/unordered_multimap/allocator/copy.cc:
+ Likewise.
+ * testsuite/23_containers/unordered_multiset/allocator/copy.cc:
+ Likewise.
+ * testsuite/23_containers/unordered_set/allocator/copy.cc: Likewise.
+ * testsuite/23_containers/vector/allocator/copy.cc: Likewise.
+ * testsuite/23_containers/forward_list/allocator/move.cc: New.
+ * testsuite/23_containers/unordered_map/allocator/move.cc: New.
+ * testsuite/23_containers/unordered_multimap/allocator/move.cc: New.
+ * testsuite/23_containers/unordered_multiset/allocator/move.cc: New.
+ * testsuite/23_containers/unordered_set/allocator/move.cc: New.
+ * testsuite/23_containers/vector/allocator/move.cc: New.
+ * testsuite/23_containers/map/allocator/copy.cc: New.
+ * testsuite/23_containers/map/allocator/copy_assign.cc: New.
+ * testsuite/23_containers/map/allocator/minimal.cc: New.
+ * testsuite/23_containers/map/allocator/move.cc: New.
+ * testsuite/23_containers/map/allocator/move_assign.cc: New.
+ * testsuite/23_containers/map/allocator/noexcept.cc: New.
+ * testsuite/23_containers/map/allocator/swap.cc: New.
+ * testsuite/23_containers/multimap/allocator/copy.cc: New.
+ * testsuite/23_containers/multimap/allocator/copy_assign.cc: New.
+ * testsuite/23_containers/multimap/allocator/minimal.cc: New.
+ * testsuite/23_containers/multimap/allocator/move.cc: New.
+ * testsuite/23_containers/multimap/allocator/move_assign.cc: New.
+ * testsuite/23_containers/multimap/allocator/noexcept.cc: New.
+ * testsuite/23_containers/multimap/allocator/swap.cc: New.
+ * testsuite/23_containers/multiset/allocator/copy.cc: New.
+ * testsuite/23_containers/multiset/allocator/copy_assign.cc: New.
+ * testsuite/23_containers/multiset/allocator/minimal.cc: New.
+ * testsuite/23_containers/multiset/allocator/move.cc: New.
+ * testsuite/23_containers/multiset/allocator/move_assign.cc: New.
+ * testsuite/23_containers/multiset/allocator/noexcept.cc: New.
+ * testsuite/23_containers/multiset/allocator/swap.cc: New.
+ * testsuite/23_containers/set/allocator/copy.cc: New.
+ * testsuite/23_containers/set/allocator/copy_assign.cc: New.
+ * testsuite/23_containers/set/allocator/minimal.cc: New.
+ * testsuite/23_containers/set/allocator/move.cc: New.
+ * testsuite/23_containers/set/allocator/move_assign.cc: New.
+ * testsuite/23_containers/set/allocator/noexcept.cc: New.
+ * testsuite/23_containers/set/allocator/swap.cc: New.
+ * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
+ Adjust dg-error line number.
+ * testsuite/23_containers/vector/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
+ Likewise.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * scripts/extract_symvers.in: Ignore <localentry: > fields
+ in readelf --symbols output.
+
+2013-11-14 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/bits/alloc_traits.h (__allow_copy_cons): Remove.
+ (__check_copy_constructible): Likewise.
+ * include/bits/unordered_map.h (unordered_map, unordered_multimap):
+ Do not derive from __check_copy_constructible.
+ * include/bits/unordered_set.h (unordered_set, unordered_multiset):
+ Likewise.
+ * testsuite/23_containers/unordered_map/55043.cc: It is no longer
+ necessary for is_copy_constructible to be correct to use nested
+ unordered containers.
+ * testsuite/23_containers/unordered_multimap/55043.cc: Likewise.
+ * testsuite/23_containers/unordered_set/55043.cc: Likewise.
+ * testsuite/23_containers/unordered_multiset/55043.cc: Likewise.
+
+2013-11-13 Marc Glisse <marc.glisse@inria.fr>
+
+ PR libstdc++/59087
+ * include/ext/pod_char_traits.h: Uglify V, I and S.
+
+2013-11-11 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR libstdc++/54562
+ * include/std/mutex (__timed_mutex_impl::__clock_t): Use
+ high_resolution_clock for absolute timeouts, because
+ pthread_mutex_timedlock uses CLOCK_REALTIME not CLOCK_MONOTONIC.
+ (__timed_mutex_impl::_M_try_lock_for): Use steady_clock for relative
+ timeouts as per [thread.req.timing].
+ (__timed_mutex_impl::_M_try_lock_until<Clock,Duration>): Convert to
+ __clock_t time point instead of using _M_try_lock_for.
+
+2013-11-09 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR libstdc++/58982
+ * include/bits/stl_algobase.h (__copy_move::__copy_m): Use assertion
+ to prevent using memmove() on non-assignable types.
+ (__copy_move_backward::__copy_move_b): Likewise.
+ * include/bits/stl_uninitialized.h (uninitialized_copy
+ uninitialized_copy_n, uninitialized_fill, uninitialized_fill_n,
+ __uninitialized_default, __uninitialized_default_n): Check for
+ assignable as well as trivial.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy/
+ 58982.cc: New.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy_n/
+ 58982.cc: New.
+ * testsuite/20_util/specialized_algorithms/uninitialized_fill/
+ 58982.cc: New.
+ * testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
+ 58982.cc: New.
+ * testsuite/25_algorithms/copy/58982.cc: New.
+ * testsuite/25_algorithms/copy_n/58982.cc: New.
+
2013-11-08 François Dumont <fdumont@gcc.gnu.org>
* include/debug/safe_iterator.h (_BeforeBeginHelper<>::_S_Is):
diff --git a/libstdc++-v3/doc/xml/manual/build_hacking.xml b/libstdc++-v3/doc/xml/manual/build_hacking.xml
index 917b4d258ff..912658bb2ce 100644
--- a/libstdc++-v3/doc/xml/manual/build_hacking.xml
+++ b/libstdc++-v3/doc/xml/manual/build_hacking.xml
@@ -142,13 +142,13 @@ in the build directory starts the build process. The <literal>all</literal> targ
<para>
Most comments should use {octothorpes, shibboleths, hash marks,
pound signs, whatever} rather than "dnl". Nearly all comments in
- configure.ac should. Comments inside macros written in ancilliary
+ configure.ac should. Comments inside macros written in ancillary
.m4 files should. About the only comments which should
<emphasis>not</emphasis> use #, but use dnl instead, are comments
- <emphasis>outside</emphasis> our own macros in the ancilliary
+ <emphasis>outside</emphasis> our own macros in the ancillary
files. The difference is that # comments show up in
<code>configure</code> (which is most helpful for debugging),
- while dnl'd lines just vanish. Since the macros in ancilliary
+ while dnl'd lines just vanish. Since the macros in ancillary
files generate code which appears in odd places, their "outside"
comments tend to not be useful while reading
<code>configure</code>.
@@ -419,7 +419,7 @@ in the build directory starts the build process. The <literal>all</literal> targ
</para>
<para>
Generates two convenience libraries, one for C++98 and one for
- C++11, various compability files for shared and static
+ C++11, various compatibility files for shared and static
libraries, and then collects all the generated bits and creates
the final libstdc++ libraries.
</para>
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml
index cf0989720fa..3246d85193e 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -376,7 +376,7 @@
to standard error for certain events such as calling a pure virtual
function or the invocation of the standard terminate handler. Those
messages cause the library to depend on the demangler and standard I/O
- facilites, which might be undesirable in a low-memory environment or
+ facilities, which might be undesirable in a low-memory environment or
when standard error is not available. This option disables those
messages. This option does not change the library ABI.
</para>
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
index e013c1f9eee..3c4ec69dcad 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
@@ -1371,7 +1371,7 @@ particular release.
<entry>23.2.1</entry>
<entry>General container requirements</entry>
<entry>Partial</entry>
- <entry>Only <code>vector</code> and <code>forward_list</code>
+ <entry><code>deque</code> and <code>list</code> do not
meet the requirements
relating to allocator use and propagation.</entry>
</row>
@@ -1416,8 +1416,7 @@ particular release.
<entry>23.3.3</entry>
<entry>Class template <code>deque</code></entry>
<entry>Partial</entry>
- <entry><code>insert</code> and <code>erase</code> members do not
- take <code>const_iterator</code> arguments (N2350).</entry>
+ <entry>Incomplete allocator support.</entry>
</row>
<row>
<entry>23.3.4</entry>
@@ -1430,24 +1429,19 @@ particular release.
<entry>23.3.5</entry>
<entry>Class template <code>list</code></entry>
<entry>Partial</entry>
- <entry><code>insert</code> and <code>erase</code> members do not
- take <code>const_iterator</code> arguments (N2350).</entry>
+ <entry>Incomplete allocator support.</entry>
</row>
<row>
- <?dbhtml bgcolor="#B0B0B0" ?>
<entry>23.3.6</entry>
<entry>Class template <code>vector</code></entry>
- <entry>Partial</entry>
- <entry><code>insert</code> and <code>erase</code> members do not
- take <code>const_iterator</code> arguments (N2350).</entry>
+ <entry>Y</entry>
+ <entry/>
</row>
<row>
- <?dbhtml bgcolor="#B0B0B0" ?>
<entry>23.3.7</entry>
<entry>Class <code>vector&lt;bool&gt;</code></entry>
- <entry>Partial</entry>
- <entry><code>insert</code> and <code>erase</code> members do not
- take <code>const_iterator</code> arguments (N2350).</entry>
+ <entry>Y</entry>
+ <entry/>
</row>
<row>
<entry>23.4</entry>
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index e68d3171095..815c4b8b998 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -541,24 +541,6 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
: is_copy_constructible<_Tp>
{ };
- // Used to allow copy construction of unordered containers
- template<bool> struct __allow_copy_cons { };
-
- // Used to delete copy constructor of unordered containers
- template<>
- struct __allow_copy_cons<false>
- {
- __allow_copy_cons() = default;
- __allow_copy_cons(const __allow_copy_cons&) = delete;
- __allow_copy_cons(__allow_copy_cons&&) = default;
- __allow_copy_cons& operator=(const __allow_copy_cons&) = default;
- __allow_copy_cons& operator=(__allow_copy_cons&&) = default;
- };
-
- template<typename _Alloc>
- using __check_copy_constructible
- = __allow_copy_cons<__is_copy_insertable<_Alloc>::value>;
-
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index d9d755abba9..54bf2133d0d 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -255,7 +255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Base type is POD with data, allowing atomic_flag to derive from
* it and meet the standard layout type requirement. In addition to
- * compatibilty with a C interface, this allows different
+ * compatibility with a C interface, this allows different
* implementations of atomic_flag to use the same atomic operation
* functions, via a standard conversion to the __atomic_flag_base
* argument.
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 9ac9d22523b..e469dbfd803 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -352,7 +352,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Tp_alloc_type __a(_M_get_Node_allocator());
typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
- ::new ((void*)__node) _Node();
+ ::new ((void*)__node) _Node;
_Alloc_traits::construct(__a, __node->_M_valptr(),
std::forward<_Args>(__args)...);
}
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index ed9e9dd870a..930a785d0a5 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -1862,7 +1862,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__try
{
__value_alloc_type __a(_M_node_allocator());
- ::new ((void*)__n) __node_type();
+ ::new ((void*)__n) __node_type;
__value_alloc_traits::construct(__a, __n->_M_valptr(),
std::forward<_Args>(__args)...);
return __n;
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index dde2dd45f9e..5613bdf5ec0 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -5685,11 +5685,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __d1._M_param == __d2._M_param; }
/**
- * @brief Inserts a %piecewise_constan_distribution random
+ * @brief Inserts a %piecewise_constant_distribution random
* number distribution @p __x into the output stream @p __os.
*
* @param __os An output stream.
- * @param __x A %piecewise_constan_distribution random number
+ * @param __x A %piecewise_constant_distribution random number
* distribution.
*
* @returns The output stream with the state of @p __x inserted or in
@@ -5701,11 +5701,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const std::piecewise_constant_distribution<_RealType1>& __x);
/**
- * @brief Extracts a %piecewise_constan_distribution random
+ * @brief Extracts a %piecewise_constant_distribution random
* number distribution @p __x from the input stream @p __is.
*
* @param __is An input stream.
- * @param __x A %piecewise_constan_distribution random number
+ * @param __x A %piecewise_constant_distribution random number
* generator engine.
*
* @returns The input stream with @p __x extracted or in an error
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index a7432da150c..5c7db5b8269 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -368,6 +368,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static _Tp*
__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
+#if __cplusplus >= 201103L
+ // trivial types can have deleted assignment
+ static_assert( is_copy_assignable<_Tp>::value,
+ "type is not assignable" );
+#endif
const ptrdiff_t _Num = __last - __first;
if (_Num)
__builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
@@ -563,6 +568,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static _Tp*
__copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
+#if __cplusplus >= 201103L
+ // trivial types can have deleted assignment
+ static_assert( is_copy_assignable<_Tp>::value,
+ "type is not assignable" );
+#endif
const ptrdiff_t _Num = __last - __first;
if (_Num)
__builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 8e4b0230614..3b5a0c2b63e 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -971,7 +971,18 @@ template<typename _Alloc>
clear() _GLIBCXX_NOEXCEPT
{ _M_erase_at_end(begin()); }
-
+#if __cplusplus >= 201103L
+ template<typename... _Args>
+ void
+ emplace_back(_Args&&... __args)
+ { push_back(bool(__args...)); }
+
+ template<typename... _Args>
+ iterator
+ emplace(const_iterator __pos, _Args&&... __args)
+ { return insert(__pos, bool(__args...)); }
+#endif
+
protected:
// Precondition: __first._M_offset == 0 && __result._M_offset == 0.
iterator
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index d05e4b9ab7d..5b73f19084e 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -128,8 +128,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
private:
/// This turns a red-black tree into a [multi]map.
- typedef typename _Alloc::template rebind<value_type>::other
- _Pair_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<value_type>::other _Pair_alloc_type;
typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
key_compare, _Pair_alloc_type> _Rep_type;
@@ -137,13 +137,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// The actual tree structure.
_Rep_type _M_t;
+ typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
+
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Pair_alloc_type::pointer pointer;
- typedef typename _Pair_alloc_type::const_pointer const_pointer;
- typedef typename _Pair_alloc_type::reference reference;
- typedef typename _Pair_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 typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
@@ -208,6 +210,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
{ _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ map(const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ map(const map& __m, const allocator_type& __a)
+ : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ map(map&& __m, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ map(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ map(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_unique(__first, __last); }
#endif
/**
@@ -276,12 +305,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @a __x is a valid, but unspecified %map.
*/
map&
- operator=(map&& __x)
+ operator=(map&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x.begin()),
+ std::__make_move_if_noexcept_iterator(__x.end()));
+ __x.clear();
+ }
return *this;
}
@@ -776,6 +810,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(map& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
/**
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 809ea540b8a..3f9690fb3e1 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -127,21 +127,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
private:
/// This turns a red-black tree into a [multi]map.
- typedef typename _Alloc::template rebind<value_type>::other
- _Pair_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<value_type>::other _Pair_alloc_type;
typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
key_compare, _Pair_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type _M_t;
+ typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
+
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Pair_alloc_type::pointer pointer;
- typedef typename _Pair_alloc_type::const_pointer const_pointer;
- typedef typename _Pair_alloc_type::reference reference;
- typedef typename _Pair_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 typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
@@ -204,6 +206,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Pair_alloc_type(__a))
{ _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ multimap(const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ multimap(const multimap& __m, const allocator_type& __a)
+ : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ multimap(multimap&& __m, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ multimap(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ multimap(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Pair_alloc_type(__a))
+ { _M_t._M_insert_equal(__first, __last); }
#endif
/**
@@ -270,12 +299,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @a __x is a valid, but unspecified multimap.
*/
multimap&
- operator=(multimap&& __x)
+ operator=(multimap&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x.begin()),
+ std::__make_move_if_noexcept_iterator(__x.end()));
+ __x.clear();
+ }
return *this;
}
@@ -685,6 +719,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(multimap& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
/**
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 8ceb02ac65f..5605801671c 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -108,18 +108,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
private:
/// This turns a red-black tree into a [multi]set.
- typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type _M_t;
+ typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
+
public:
- typedef typename _Key_alloc_type::pointer pointer;
- typedef typename _Key_alloc_type::const_pointer const_pointer;
- typedef typename _Key_alloc_type::reference reference;
- typedef typename _Key_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;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
@@ -216,6 +219,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ multiset(const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ multiset(const multiset& __m, const allocator_type& __a)
+ : _M_t(__m._M_t, _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ multiset(multiset&& __m, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ multiset(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ multiset(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_equal(__first, __last); }
#endif
/**
@@ -242,12 +272,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* %multiset.
*/
multiset&
- operator=(multiset&& __x)
+ operator=(multiset&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
+ std::__make_move_if_noexcept_iterator(__x._M_t.end()));
+ __x.clear();
+ }
return *this;
}
@@ -388,6 +423,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(multiset& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -747,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is a total ordering relation. It is linear in the size of the
- * maps. The elements must be comparable with @c <.
+ * sets. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 44eb5897f0e..b405c491e47 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -108,19 +108,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
//@}
private:
- typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
_Rep_type _M_t; // Red-black tree representing set.
+ typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
+
public:
//@{
/// Iterator-related typedefs.
- typedef typename _Key_alloc_type::pointer pointer;
- typedef typename _Key_alloc_type::const_pointer const_pointer;
- typedef typename _Key_alloc_type::reference reference;
- typedef typename _Key_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;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
@@ -220,6 +223,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const allocator_type& __a = allocator_type())
: _M_t(__comp, _Key_alloc_type(__a))
{ _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended default constructor.
+ explicit
+ set(const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended copy constructor.
+ set(const set& __x, const allocator_type& __a)
+ : _M_t(__x._M_t, _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended move constructor.
+ set(set&& __x, const allocator_type& __a)
+ noexcept(is_nothrow_copy_constructible<_Compare>::value
+ && _Alloc_traits::_S_always_equal())
+ : _M_t(std::move(__x._M_t), _Key_alloc_type(__a)) { }
+
+ /// Allocator-extended initialier-list constructor.
+ set(initializer_list<value_type> __l, const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+ /// Allocator-extended range constructor.
+ template<typename _InputIterator>
+ set(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a)
+ : _M_t(_Compare(), _Key_alloc_type(__a))
+ { _M_t._M_insert_unique(__first, __last); }
#endif
/**
@@ -245,12 +275,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @a __x is a valid, but unspecified %set.
*/
set&
- operator=(set&& __x)
+ operator=(set&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
+ if (!_M_t._M_move_assign(__x._M_t))
+ {
+ // The rvalue's allocator cannot be moved and is not equal,
+ // so we need to individually move each element.
+ clear();
+ insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
+ std::__make_move_if_noexcept_iterator(__x._M_t.end()));
+ __x.clear();
+ }
return *this;
}
@@ -391,6 +426,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(set& __x)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -762,7 +800,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @return True iff @a __x is lexicographically less than @a __y.
*
* This is a total ordering relation. It is linear in the size of the
- * maps. The elements must be comparable with @c <.
+ * sets. The elements must be comparable with @c <.
*
* See std::lexicographical_compare() for how the determination is made.
*/
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 5ed3760633e..778fe2592fa 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -62,8 +62,9 @@
#include <bits/allocator.h>
#include <bits/stl_function.h>
#include <bits/cpp_type_traits.h>
+#include <ext/alloc_traits.h>
#if __cplusplus >= 201103L
-#include <bits/alloc_traits.h>
+#include <ext/aligned_buffer.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@@ -131,13 +132,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct _Rb_tree_node : public _Rb_tree_node_base
{
typedef _Rb_tree_node<_Val>* _Link_type;
+
+#if __cplusplus < 201103L
_Val _M_value_field;
-#if __cplusplus >= 201103L
- template<typename... _Args>
- _Rb_tree_node(_Args&&... __args)
- : _Rb_tree_node_base(),
- _M_value_field(std::forward<_Args>(__args)...) { }
+ _Val*
+ _M_valptr()
+ { return std::__addressof(_M_value_field); }
+
+ const _Val*
+ _M_valptr() const
+ { return std::__addressof(_M_value_field); }
+#else
+ __gnu_cxx::__aligned_buffer<_Val> _M_storage;
+
+ _Val*
+ _M_valptr()
+ { return _M_storage._M_ptr(); }
+
+ const _Val*
+ _M_valptr() const
+ { return _M_storage._M_ptr(); }
#endif
};
@@ -176,12 +191,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reference
operator*() const _GLIBCXX_NOEXCEPT
- { return static_cast<_Link_type>(_M_node)->_M_value_field; }
+ { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
pointer
operator->() const _GLIBCXX_NOEXCEPT
- { return std::__addressof(static_cast<_Link_type>
- (_M_node)->_M_value_field); }
+ { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
_Self&
operator++() _GLIBCXX_NOEXCEPT
@@ -257,12 +271,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reference
operator*() const _GLIBCXX_NOEXCEPT
- { return static_cast<_Link_type>(_M_node)->_M_value_field; }
+ { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
pointer
operator->() const _GLIBCXX_NOEXCEPT
- { return std::__addressof(static_cast<_Link_type>
- (_M_node)->_M_value_field); }
+ { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
_Self&
operator++() _GLIBCXX_NOEXCEPT
@@ -332,8 +345,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare, typename _Alloc = allocator<_Val> >
class _Rb_tree
{
- typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
- _Node_allocator;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
+
+ typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
protected:
typedef _Rb_tree_node_base* _Base_ptr;
@@ -367,11 +382,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
protected:
_Link_type
_M_get_node()
- { return _M_impl._Node_allocator::allocate(1); }
+ { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
void
_M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
- { _M_impl._Node_allocator::deallocate(__p, 1); }
+ { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
#if __cplusplus < 201103L
_Link_type
@@ -379,8 +394,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_Link_type __tmp = _M_get_node();
__try
- { get_allocator().construct
- (std::__addressof(__tmp->_M_value_field), __x); }
+ { get_allocator().construct(__tmp->_M_valptr(), __x); }
__catch(...)
{
_M_put_node(__tmp);
@@ -392,7 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_destroy_node(_Link_type __p)
{
- get_allocator().destroy(std::__addressof(__p->_M_value_field));
+ get_allocator().destroy(__p->_M_valptr());
_M_put_node(__p);
}
#else
@@ -403,9 +417,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Link_type __tmp = _M_get_node();
__try
{
- allocator_traits<_Node_allocator>::
- construct(_M_get_Node_allocator(), __tmp,
- std::forward<_Args>(__args)...);
+ ::new(__tmp) _Rb_tree_node<_Val>;
+ _Alloc_traits::construct(_M_get_Node_allocator(),
+ __tmp->_M_valptr(),
+ std::forward<_Args>(__args)...);
}
__catch(...)
{
@@ -418,7 +433,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_destroy_node(_Link_type __p) noexcept
{
- _M_get_Node_allocator().destroy(__p);
+ _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
+ __p->~_Rb_tree_node<_Val>();
_M_put_node(__p);
}
#endif
@@ -426,7 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Link_type
_M_clone_node(_Const_Link_type __x)
{
- _Link_type __tmp = _M_create_node(__x->_M_value_field);
+ _Link_type __tmp = _M_create_node(*__x->_M_valptr());
__tmp->_M_color = __x->_M_color;
__tmp->_M_left = 0;
__tmp->_M_right = 0;
@@ -518,7 +534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static const_reference
_S_value(_Const_Link_type __x)
- { return __x->_M_value_field; }
+ { return *__x->_M_valptr(); }
static const _Key&
_S_key(_Const_Link_type __x)
@@ -542,7 +558,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static const_reference
_S_value(_Const_Base_ptr __x)
- { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
+ { return *static_cast<_Const_Link_type>(__x)->_M_valptr(); }
static const _Key&
_S_key(_Const_Base_ptr __x)
@@ -652,7 +668,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_impl(__comp, _Node_allocator(__a)) { }
_Rb_tree(const _Rb_tree& __x)
- : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
+ : _M_impl(__x._M_impl._M_key_compare,
+ _Alloc_traits::_S_select_on_copy(__x._M_get_Node_allocator()))
{
if (__x._M_root() != 0)
{
@@ -664,7 +681,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#if __cplusplus >= 201103L
- _Rb_tree(_Rb_tree&& __x);
+ _Rb_tree(const allocator_type& __a)
+ : _M_impl(_Compare(), _Node_allocator(__a))
+ { }
+
+ _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
+ : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
+ {
+ if (__x._M_root() != 0)
+ {
+ _M_root() = _M_copy(__x._M_begin(), _M_end());
+ _M_leftmost() = _S_minimum(_M_root());
+ _M_rightmost() = _S_maximum(_M_root());
+ _M_impl._M_node_count = __x._M_impl._M_node_count;
+ }
+ }
+
+ _Rb_tree(_Rb_tree&& __x)
+ : _Rb_tree(std::move(__x), std::move(__x._M_get_Node_allocator()))
+ { }
+
+ _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
+ : _Rb_tree(std::move(__x), _Node_allocator(__a))
+ { }
+
+ _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a);
#endif
~_Rb_tree() _GLIBCXX_NOEXCEPT
@@ -729,10 +770,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_type
max_size() const _GLIBCXX_NOEXCEPT
- { return _M_get_Node_allocator().max_size(); }
+ { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
void
- swap(_Rb_tree& __t);
+#if __cplusplus >= 201103L
+ swap(_Rb_tree& __t) noexcept(_Alloc_traits::_S_nothrow_swap());
+#else
+ swap(_Rb_tree& __t);
+#endif
// Insert/erase.
#if __cplusplus >= 201103L
@@ -899,6 +944,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Debugging.
bool
__rb_verify() const;
+
+#if __cplusplus >= 201103L
+ bool
+ _M_move_assign(_Rb_tree&);
+#endif
};
template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -960,24 +1010,67 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x)
- : _M_impl(__x._M_impl._M_key_compare,
- std::move(__x._M_get_Node_allocator()))
+ _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
+ : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
{
if (__x._M_root() != 0)
{
- _M_root() = __x._M_root();
- _M_leftmost() = __x._M_leftmost();
- _M_rightmost() = __x._M_rightmost();
- _M_root()->_M_parent = _M_end();
+ if (!_Alloc_traits::_S_always_equal()
+ && __x._M_get_Node_allocator() != __a)
+ {
+ _M_root() = _M_copy(__x._M_begin(), _M_end());
+ _M_leftmost() = _S_minimum(_M_root());
+ _M_rightmost() = _S_maximum(_M_root());
+ _M_impl._M_node_count = __x._M_impl._M_node_count;
+ }
+ else
+ {
+ _M_root() = __x._M_root();
+ _M_leftmost() = __x._M_leftmost();
+ _M_rightmost() = __x._M_rightmost();
+ _M_root()->_M_parent = _M_end();
+
+ __x._M_root() = 0;
+ __x._M_leftmost() = __x._M_end();
+ __x._M_rightmost() = __x._M_end();
+
+ this->_M_impl._M_node_count = __x._M_impl._M_node_count;
+ __x._M_impl._M_node_count = 0;
+ }
+ }
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ bool
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_move_assign(_Rb_tree& __x)
+ {
+ if (_Alloc_traits::_S_propagate_on_move_assign()
+ || _Alloc_traits::_S_always_equal()
+ || _M_get_Node_allocator() == __x._M_get_Node_allocator())
+ {
+ clear();
+ if (__x._M_root() != 0)
+ {
+ _M_root() = __x._M_root();
+ _M_leftmost() = __x._M_leftmost();
+ _M_rightmost() = __x._M_rightmost();
+ _M_root()->_M_parent = _M_end();
- __x._M_root() = 0;
- __x._M_leftmost() = __x._M_end();
- __x._M_rightmost() = __x._M_end();
+ __x._M_root() = 0;
+ __x._M_leftmost() = __x._M_end();
+ __x._M_rightmost() = __x._M_end();
- this->_M_impl._M_node_count = __x._M_impl._M_node_count;
- __x._M_impl._M_node_count = 0;
+ this->_M_impl._M_node_count = __x._M_impl._M_node_count;
+ __x._M_impl._M_node_count = 0;
+ }
+ if (_Alloc_traits::_S_propagate_on_move_assign())
+ std::__alloc_on_move(_M_get_Node_allocator(),
+ __x._M_get_Node_allocator());
+ return true;
}
+ return false;
}
#endif
@@ -985,12 +1078,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Compare, typename _Alloc>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
+ operator=(const _Rb_tree& __x)
{
if (this != &__x)
{
// Note that _Key may be a constant type.
clear();
+#if __cplusplus >= 201103L
+ if (_Alloc_traits::_S_propagate_on_copy_assign())
+ {
+ auto& __this_alloc = this->_M_get_Node_allocator();
+ auto& __that_alloc = __x._M_get_Node_allocator();
+ if (!_Alloc_traits::_S_always_equal()
+ && __this_alloc != __that_alloc)
+ {
+ std::__alloc_on_copy(__this_alloc, __that_alloc);
+ }
+ }
+#endif
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (__x._M_root() != 0)
{
@@ -1260,6 +1365,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
+#if __cplusplus >= 201103L
+ noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
{
if (_M_root() == 0)
{
@@ -1298,11 +1406,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// No need to swap header's color as it does not change.
std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 431. Swapping containers with unequal allocators.
- std::__alloc_swap<_Node_allocator>::
- _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
+
+ _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
+ __t._M_get_Node_allocator());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index 310b16202ec..e45046b4999 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -111,9 +111,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ValueType1;
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType2;
+#if __cplusplus < 201103L
+ const bool __assignable = true;
+#else
+ // trivial types can have deleted assignment
+ typedef typename iterator_traits<_InputIterator>::reference _RefType;
+ const bool __assignable = is_assignable<_ValueType1, _RefType>::value;
+#endif
- return std::__uninitialized_copy<(__is_trivial(_ValueType1)
- && __is_trivial(_ValueType2))>::
+ return std::__uninitialized_copy<__is_trivial(_ValueType1)
+ && __is_trivial(_ValueType2)
+ && __assignable>::
__uninit_copy(__first, __last, __result);
}
@@ -166,8 +174,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
+#if __cplusplus < 201103L
+ const bool __assignable = true;
+#else
+ // trivial types can have deleted assignment
+ const bool __assignable = is_copy_assignable<_ValueType>::value;
+#endif
- std::__uninitialized_fill<__is_trivial(_ValueType)>::
+ std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
__uninit_fill(__first, __last, __x);
}
@@ -219,8 +233,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
+#if __cplusplus < 201103L
+ const bool __assignable = true;
+#else
+ // trivial types can have deleted assignment
+ const bool __assignable = is_copy_assignable<_ValueType>::value;
+#endif
- std::__uninitialized_fill_n<__is_trivial(_ValueType)>::
+ std::__uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
__uninit_fill_n(__first, __n, __x);
}
@@ -526,8 +546,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
+ // trivial types can have deleted assignment
+ const bool __assignable = is_copy_assignable<_ValueType>::value;
- std::__uninitialized_default_1<__is_trivial(_ValueType)>::
+ std::__uninitialized_default_1<__is_trivial(_ValueType)
+ && __assignable>::
__uninit_default(__first, __last);
}
@@ -539,8 +562,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
+ // trivial types can have deleted assignment
+ const bool __assignable = is_copy_assignable<_ValueType>::value;
- std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
+ std::__uninitialized_default_n_1<__is_trivial(_ValueType)
+ && __assignable>::
__uninit_default_n(__first, __n);
}
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 376f39af216..5c8c16151e2 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -332,6 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/// Move constructor with alternative allocator
vector(vector&& __rv, const allocator_type& __m)
+ noexcept(_Alloc_traits::_S_always_equal())
: _Base(std::move(__rv), __m)
{
if (__rv.get_allocator() != __m)
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index 6d5b29e09d2..a1b99acd217 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -95,7 +95,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Key>,
class _Pred = std::equal_to<_Key>,
class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
- class unordered_map : __check_copy_constructible<_Alloc>
+ class unordered_map
{
typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
@@ -807,7 +807,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Key>,
class _Pred = std::equal_to<_Key>,
class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
- class unordered_multimap : __check_copy_constructible<_Alloc>
+ class unordered_multimap
{
typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index 89deb496f11..22bddecf083 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -90,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Value>,
class _Pred = std::equal_to<_Value>,
class _Alloc = std::allocator<_Value> >
- class unordered_set : __check_copy_constructible<_Alloc>
+ class unordered_set
{
typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
@@ -725,7 +725,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
class _Hash = hash<_Value>,
class _Pred = std::equal_to<_Value>,
class _Alloc = std::allocator<_Value> >
- class unordered_multiset : __check_copy_constructible<_Alloc>
+ class unordered_multiset
{
typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
diff --git a/libstdc++-v3/include/ext/cast.h b/libstdc++-v3/include/ext/cast.h
index 961a962558c..fb220f39f70 100644
--- a/libstdc++-v3/include/ext/cast.h
+++ b/libstdc++-v3/include/ext/cast.h
@@ -38,7 +38,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* These functions are here to allow containers to support non standard
* pointer types. For normal pointers, these resolve to the use of the
* standard cast operation. For other types the functions will perform
- * the apprpriate cast to/from the custom pointer class so long as that
+ * the appropriate cast to/from the custom pointer class so long as that
* class meets the following conditions:
* 1) has a typedef element_type which names tehe type it points to.
* 2) has a get() const method which returns element_type*.
diff --git a/libstdc++-v3/include/ext/pod_char_traits.h b/libstdc++-v3/include/ext/pod_char_traits.h
index dcd86ff9842..8e3ad9884d9 100644
--- a/libstdc++-v3/include/ext/pod_char_traits.h
+++ b/libstdc++-v3/include/ext/pod_char_traits.h
@@ -45,13 +45,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// int_type to properly hold the full range of char_type values as
// well as EOF.
/// @brief A POD class that serves as a character abstraction class.
- template<typename V, typename I, typename S = std::mbstate_t>
+ template<typename _Value, typename _Int, typename _St = std::mbstate_t>
struct character
{
- typedef V value_type;
- typedef I int_type;
- typedef S state_type;
- typedef character<V, I, S> char_type;
+ typedef _Value value_type;
+ typedef _Int int_type;
+ typedef _St state_type;
+ typedef character<_Value, _Int, _St> char_type;
value_type value;
@@ -73,14 +73,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
- template<typename V, typename I, typename S>
+ template<typename _Value, typename _Int, typename _St>
inline bool
- operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
+ operator==(const character<_Value, _Int, _St>& lhs,
+ const character<_Value, _Int, _St>& rhs)
{ return lhs.value == rhs.value; }
- template<typename V, typename I, typename S>
+ template<typename _Value, typename _Int, typename _St>
inline bool
- operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs)
+ operator<(const character<_Value, _Int, _St>& lhs,
+ const character<_Value, _Int, _St>& rhs)
{ return lhs.value < rhs.value; }
_GLIBCXX_END_NAMESPACE_VERSION
@@ -91,14 +93,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// char_traits<__gnu_cxx::character> specialization.
- template<typename V, typename I, typename S>
- struct char_traits<__gnu_cxx::character<V, I, S> >
+ template<typename _Value, typename _Int, typename _St>
+ struct char_traits<__gnu_cxx::character<_Value, _Int, _St> >
{
- typedef __gnu_cxx::character<V, I, S> char_type;
- typedef typename char_type::int_type int_type;
- typedef typename char_type::state_type state_type;
- typedef fpos<state_type> pos_type;
- typedef streamoff off_type;
+ typedef __gnu_cxx::character<_Value, _Int, _St> char_type;
+ typedef typename char_type::int_type int_type;
+ typedef typename char_type::state_type state_type;
+ typedef fpos<state_type> pos_type;
+ typedef streamoff off_type;
static void
assign(char_type& __c1, const char_type& __c2)
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index 40b2e31dc7f..da2ca0cfe94 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -203,21 +203,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class __timed_mutex_impl
{
protected:
-#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
- typedef chrono::steady_clock __clock_t;
-#else
typedef chrono::high_resolution_clock __clock_t;
-#endif
template<typename _Rep, typename _Period>
bool
_M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
{
- auto __rt = chrono::duration_cast<__clock_t::duration>(__rtime);
- if (ratio_greater<__clock_t::period, _Period>())
+ using chrono::steady_clock;
+ auto __rt = chrono::duration_cast<steady_clock::duration>(__rtime);
+ if (ratio_greater<steady_clock::period, _Period>())
++__rt;
-
- return _M_try_lock_until(__clock_t::now() + __rt);
+ return _M_try_lock_until(steady_clock::now() + __rt);
}
template<typename _Duration>
@@ -225,11 +221,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_try_lock_until(const chrono::time_point<__clock_t,
_Duration>& __atime)
{
- chrono::time_point<__clock_t, chrono::seconds> __s =
- chrono::time_point_cast<chrono::seconds>(__atime);
-
- chrono::nanoseconds __ns =
- chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
__gthread_time_t __ts = {
static_cast<std::time_t>(__s.time_since_epoch().count()),
@@ -243,7 +236,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Clock, typename _Duration>
bool
_M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
- { return _M_try_lock_for(__atime - _Clock::now()); }
+ {
+ auto __rtime = __atime - _Clock::now();
+ return _M_try_lock_until(__clock_t::now() + __rtime);
+ }
};
/// timed_mutex
diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h
index cf2c0602e5f..3e29fed57d2 100644
--- a/libstdc++-v3/libsupc++/cxxabi.h
+++ b/libstdc++-v3/libsupc++/cxxabi.h
@@ -144,7 +144,7 @@ namespace __cxxabiv1
void
__cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
- // Exception handling auxillary.
+ // Exception handling auxiliary.
void
__cxa_bad_cast() __attribute__((__noreturn__));
diff --git a/libstdc++-v3/scripts/extract_symvers.in b/libstdc++-v3/scripts/extract_symvers.in
index a262435de7a..c9cf7e5dbe1 100755
--- a/libstdc++-v3/scripts/extract_symvers.in
+++ b/libstdc++-v3/scripts/extract_symvers.in
@@ -53,6 +53,7 @@ SunOS)
# present on Solaris.
${readelf} ${lib} |\
sed -e 's/ \[<other>: [A-Fa-f0-9]*\] //' -e '/\.dynsym/,/^$/p;d' |\
+ sed -e 's/ \[<localentry>: [0-9]*\] //' |\
egrep -v ' (LOCAL|UND) ' |\
egrep -v ' (_DYNAMIC|_GLOBAL_OFFSET_TABLE_|_PROCEDURE_LINKAGE_TABLE_|_edata|_end|_etext)$' |\
sed -e 's/ <processor specific>: / <processor_specific>:_/g' |\
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc
new file mode 100644
index 00000000000..7e059a35b9b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2013 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/>.
+
+// 20.7.12 specialized algorithms
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <memory>
+
+// libstdc++/58982
+
+// trivial class that is not assignable
+struct T
+{
+ T() = default;
+ ~T() = default;
+
+ T& operator=(const T&) = delete;
+};
+
+void
+test01(T* result)
+{
+ T t[1];
+ std::uninitialized_copy(t, t+1, result);
+}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc
new file mode 100644
index 00000000000..e10b31a70f6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2013 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/>.
+
+// 20.7.12 specialized algorithms
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <memory>
+
+// libstdc++/58982
+
+// trivial class that is not assignable
+struct T
+{
+ T() = default;
+ ~T() = default;
+
+ T& operator=(const T&) = delete;
+};
+
+void
+test01(T* result)
+{
+ T t[1];
+ std::uninitialized_copy_n(t, 1, result);
+}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc
new file mode 100644
index 00000000000..012e2c6c88c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2013 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/>.
+
+// 20.7.12 specialized algorithms
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <memory>
+
+// libstdc++/58982
+
+// trivial class that is not assignable
+struct T
+{
+ T() = default;
+ ~T() = default;
+
+ T& operator=(const T&) = delete;
+};
+
+void
+test01(T* first, T* last)
+{
+ T t;
+ std::uninitialized_fill(first, last, t);
+}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc
new file mode 100644
index 00000000000..606c63266e3
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2013 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/>.
+
+// 20.7.12 specialized algorithms
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <memory>
+
+// libstdc++/58982
+
+// trivial class that is not assignable
+struct T
+{
+ T() = default;
+ ~T() = default;
+
+ T& operator=(const T&) = delete;
+};
+
+void
+test01(T* first)
+{
+ T t;
+ std::uninitialized_fill_n(first, 1, t);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
index f7e781ce9ec..c08e0e105a2 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
@@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }
#include <forward_list>
#include <testsuite_hooks.h>
@@ -49,9 +49,22 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality());
}
+void test03()
+{
+ 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));
+ v1.push_front(T());
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc
new file mode 100644
index 00000000000..04d660a7ceb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { T() };
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::forward_list<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { T() };
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc
new file mode 100644
index 00000000000..39907d186d9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc
new file mode 100644
index 00000000000..1c2c8220517
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc
@@ -0,0 +1,67 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_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/map/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
new file mode 100644
index 00000000000..4a04cfe4be1
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
@@ -0,0 +1,52 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::SimpleAllocator;
+
+template class std::map<T, U, Cmp, SimpleAllocator<std::pair<const T, U>>>;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef SimpleAllocator<std::pair<const T, U>> alloc_type;
+ typedef std::allocator_traits<alloc_type> traits_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v(alloc_type{});
+ v = { test_type::value_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/map/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc
new file mode 100644
index 00000000000..94354e690b6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc
new file mode 100644
index 00000000000..920a38ca38c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc
@@ -0,0 +1,67 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/map/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc
new file mode 100644
index 00000000000..832a28ab63a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc
@@ -0,0 +1,83 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+namespace __gnu_test
+{
+ inline void
+ swap(propagating_allocator<std::pair<const T, U>, true>& l,
+ propagating_allocator<std::pair<const T, U>, true>& r)
+ noexcept(false)
+ {
+ typedef uneq_allocator<std::pair<const T, U>> base_alloc;
+ swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+ }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ typedef std::allocator<std::pair<const T, U>> alloc_type;
+ typedef std::map<T, U, Cmp, 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<std::pair<const T, U>, false> alloc_type;
+ typedef std::map<T, U, Cmp, 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::map<T, U, Cmp, 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/map/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc
new file mode 100644
index 00000000000..81020fcf1e6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc
@@ -0,0 +1,86 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<std::pair<const T, U>, false>&,
+ const propagating_allocator<std::pair<const T, U>, false>&)
+{
+ return true;
+}
+
+bool
+operator!=(const propagating_allocator<std::pair<const T, U>, false>&,
+ const propagating_allocator<std::pair<const T, U>, false>&)
+{
+ return false;
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ std::swap(v1, v2);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+ // swap back so assertions in uneq_allocator::deallocate don't fail
+ std::swap(v1, v2);
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+ typedef std::map<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/multimap/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc
new file mode 100644
index 00000000000..fdf197d2970
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc
new file mode 100644
index 00000000000..3f67999559f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc
@@ -0,0 +1,67 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_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/multimap/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
new file mode 100644
index 00000000000..92ad4895e82
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
@@ -0,0 +1,52 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::SimpleAllocator;
+
+template class std::multimap<T, U, Cmp, SimpleAllocator<std::pair<const T, U>>>;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef SimpleAllocator<std::pair<const T, U>> alloc_type;
+ typedef std::allocator_traits<alloc_type> traits_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v(alloc_type{});
+ v = { test_type::value_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/multimap/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc
new file mode 100644
index 00000000000..7a80ce653fb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc
new file mode 100644
index 00000000000..70e2d488c92
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc
@@ -0,0 +1,67 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/multimap/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc
new file mode 100644
index 00000000000..aee4dc90029
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc
@@ -0,0 +1,83 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+namespace __gnu_test
+{
+ inline void
+ swap(propagating_allocator<std::pair<const T, U>, true>& l,
+ propagating_allocator<std::pair<const T, U>, true>& r)
+ noexcept(false)
+ {
+ typedef uneq_allocator<std::pair<const T, U>> base_alloc;
+ swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+ }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ typedef std::allocator<std::pair<const T, U>> alloc_type;
+ typedef std::multimap<T, U, Cmp, 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<std::pair<const T, U>, false> alloc_type;
+ typedef std::multimap<T, U, Cmp, 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<std::pair<const T, U>, true> alloc_type;
+ typedef std::multimap<T, U, Cmp, 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/multimap/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc
new file mode 100644
index 00000000000..57e460c32ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc
@@ -0,0 +1,86 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<std::pair<const T, U>, false>&,
+ const propagating_allocator<std::pair<const T, U>, false>&)
+{
+ return true;
+}
+
+bool
+operator!=(const propagating_allocator<std::pair<const T, U>, false>&,
+ const propagating_allocator<std::pair<const T, U>, false>&)
+{
+ return false;
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ std::swap(v1, v2);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+ // swap back so assertions in uneq_allocator::deallocate don't fail
+ std::swap(v1, v2);
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+ typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/multiset/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc
new file mode 100644
index 00000000000..cecde4f3e1c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc
@@ -0,0 +1,74 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ 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::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc
new file mode 100644
index 00000000000..6b47b099293
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc
@@ -0,0 +1,65 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_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/multiset/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
new file mode 100644
index 00000000000..8be5394a42b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::SimpleAllocator;
+
+template class std::multiset<T, Cmp, SimpleAllocator<T>>;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef SimpleAllocator<T> alloc_type;
+ typedef std::allocator_traits<alloc_type> traits_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v(alloc_type{});
+ v = { test_type::value_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/multiset/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc
new file mode 100644
index 00000000000..819d18d3fd4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc
@@ -0,0 +1,61 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc
new file mode 100644
index 00000000000..f553a95bf0d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc
@@ -0,0 +1,65 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/multiset/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc
new file mode 100644
index 00000000000..89b0053d4c2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+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::multiset<T, Cmp, 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::multiset<T, Cmp, 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::multiset<T, Cmp, 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/multiset/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc
new file mode 100644
index 00000000000..f92ff074d0f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc
@@ -0,0 +1,84 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return false;
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ std::swap(v1, v2);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+ // swap back so assertions in uneq_allocator::deallocate don't fail
+ std::swap(v1, v2);
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::multiset<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/set/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc
new file mode 100644
index 00000000000..ac717f0e6b6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc
@@ -0,0 +1,74 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ 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::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc
new file mode 100644
index 00000000000..5ac37c6d22c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc
@@ -0,0 +1,65 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_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/set/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
new file mode 100644
index 00000000000..dd4c3b94c18
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::SimpleAllocator;
+
+template class std::set<T, Cmp, SimpleAllocator<T>>;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef SimpleAllocator<T> alloc_type;
+ typedef std::allocator_traits<alloc_type> traits_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v(alloc_type{});
+ v = { test_type::value_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/set/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc
new file mode 100644
index 00000000000..0fdd9a0fe1a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc
new file mode 100644
index 00000000000..60ef2affb5e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc
@@ -0,0 +1,65 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/set/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc
new file mode 100644
index 00000000000..07adbc08013
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+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::set<T, Cmp, 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::set<T, Cmp, 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::set<T, Cmp, 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/set/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc
new file mode 100644
index 00000000000..d5bc122abb8
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc
@@ -0,0 +1,84 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return false;
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, false> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ std::swap(v1, v2);
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+ // swap back so assertions in uneq_allocator::deallocate don't fail
+ std::swap(v1, v2);
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::set<T, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { test_type::value_type{} };
+ test_type v2(alloc_type(2));
+ v2 = { test_type::value_type{} };
+ 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/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc
index 50e5437044c..baef785c6a2 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc
@@ -42,28 +42,3 @@ void test01()
v.emplace_back(uim());
}
-// Unordered containers don't use allocator_traits yet so need full
-// Allocator interface, derive from std::allocator to get it.
-template<typename T, bool R>
-struct Alloc : std::allocator<T>
-{
- template<typename U>
- struct rebind { typedef Alloc<U, R> other; };
-
- Alloc() = default;
-
- template<typename U>
- Alloc(const Alloc<U, R>&) { }
-
- typedef typename std::conditional<R, T&&, const T&>::type arg_type;
-
- void construct(T* p, arg_type) const
- { new((void*)p) T(); }
-};
-
-// verify is_copy_constructible depends on allocator
-typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
-
-typedef test_type<Alloc<MoveOnly, false>> uim_lval;
-static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
index 3b85f6fc249..faa3d127865 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
@@ -63,9 +63,23 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality());
}
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::unordered_map<T, T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.emplace(std::piecewise_construct,
+ std::make_tuple(T()), std::make_tuple(T()));
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc
new file mode 100644
index 00000000000..d2648026bbb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc
@@ -0,0 +1,71 @@
+// Copyright (C) 2013 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-options "-std=c++11" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+ std::size_t operator()(const T t) const noexcept
+ { return t.i; }
+};
+
+struct equal_to
+{
+ bool operator()(const T& lhs, const T& rhs) const noexcept
+ { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_map<T, T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.emplace(std::piecewise_construct,
+ std::make_tuple(T()), std::make_tuple(T()));
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_map<T, T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.emplace(std::piecewise_construct,
+ std::make_tuple(T()), std::make_tuple(T()));
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc
index afeecaad0ab..224e660d51a 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc
@@ -41,29 +41,3 @@ void test01()
std::vector<uim> v;
v.emplace_back(uim());
}
-
-// Unordered containers don't use allocator_traits yet so need full
-// Allocator interface, derive from std::allocator to get it.
-template<typename T, bool R>
-struct Alloc : std::allocator<T>
-{
- template<typename U>
- struct rebind { typedef Alloc<U, R> other; };
-
- Alloc() = default;
-
- template<typename U>
- Alloc(const Alloc<U, R>&) { }
-
- typedef typename std::conditional<R, T&&, const T&>::type arg_type;
-
- void construct(T* p, arg_type) const
- { new((void*)p) T(); }
-};
-
-// verify is_copy_constructible depends on allocator
-typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
-
-typedef test_type<Alloc<MoveOnly, false>> uim_lval;
-static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
index 74c8f19455d..1a6a0bb6b96 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
@@ -63,9 +63,23 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality());
}
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::unordered_multimap<T, T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.emplace(std::piecewise_construct,
+ std::make_tuple(T()), std::make_tuple(T()));
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc
new file mode 100644
index 00000000000..fba6abbb22a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc
@@ -0,0 +1,71 @@
+// Copyright (C) 2013 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-options "-std=c++11" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+ std::size_t operator()(const T t) const noexcept
+ { return t.i; }
+};
+
+struct equal_to
+{
+ bool operator()(const T& lhs, const T& rhs) const noexcept
+ { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_multimap<T, T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.emplace(std::piecewise_construct,
+ std::make_tuple(T()), std::make_tuple(T()));
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_multimap<T, T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.emplace(std::piecewise_construct,
+ std::make_tuple(T()), std::make_tuple(T()));
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
index c80ce55cb7c..ed9da396fb2 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
@@ -45,29 +45,3 @@ void test01()
std::vector<uim> v;
v.emplace_back(uim());
}
-
-// Unordered containers don't use allocator_traits yet so need full
-// Allocator interface, derive from std::allocator to get it.
-template<typename T, bool R>
-struct Alloc : std::allocator<T>
-{
- template<typename U>
- struct rebind { typedef Alloc<U, R> other; };
-
- Alloc() = default;
-
- template<typename U>
- Alloc(const Alloc<U, R>&) { }
-
- typedef typename std::conditional<R, T&&, const T&>::type arg_type;
-
- void construct(T* p, arg_type) const
- { new((void*)p) T(); }
-};
-
-// verify is_copy_constructible depends on allocator
-typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
-
-typedef test_type<Alloc<MoveOnly, false>> uim_lval;
-static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
index 94b032b80de..f5f01dc3140 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
@@ -61,9 +61,22 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality());
}
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.insert(T());
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc
new file mode 100644
index 00000000000..da1de2c861f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2013 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-options "-std=c++11" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+ std::size_t operator()(const T t) const noexcept
+ { return t.i; }
+};
+
+struct equal_to
+{
+ bool operator()(const T& lhs, const T& rhs) const noexcept
+ { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.insert(T());
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.insert(T());
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc
index 152489042f7..3a0222625ca 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc
@@ -45,29 +45,3 @@ void test01()
std::vector<uim> v;
v.emplace_back(uim());
}
-
-// Unordered containers don't use allocator_traits yet so need full
-// Allocator interface, derive from std::allocator to get it.
-template<typename T, bool R>
-struct Alloc : std::allocator<T>
-{
- template<typename U>
- struct rebind { typedef Alloc<U, R> other; };
-
- Alloc() = default;
-
- template<typename U>
- Alloc(const Alloc<U, R>&) { }
-
- typedef typename std::conditional<R, T&&, const T&>::type arg_type;
-
- void construct(T* p, arg_type) const
- { new((void*)p) T(); }
-};
-
-// verify is_copy_constructible depends on allocator
-typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
-
-typedef test_type<Alloc<MoveOnly, false>> uim_lval;
-static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
index 8f1b7ee638c..500d7c8081a 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
@@ -61,9 +61,22 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality());
}
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.insert(T());
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc
new file mode 100644
index 00000000000..865dcaeb7b5
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2013 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-options "-std=c++11" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+ std::size_t operator()(const T t) const noexcept
+ { return t.i; }
+};
+
+struct equal_to
+{
+ bool operator()(const T& lhs, const T& rhs) const noexcept
+ { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.insert(T());
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.insert(T());
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
index f95c345b853..1b528927bc0 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
@@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }
#include <vector>
#include <testsuite_hooks.h>
@@ -49,9 +49,22 @@ void test02()
VERIFY(1 == v2.get_allocator().get_personality());
}
+void test03()
+{
+ bool test __attribute__((unused)) = true;
+ typedef propagating_allocator<T, true> alloc_type;
+ typedef std::vector<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1.push_back(T());
+ test_type v2(v1, alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
int main()
{
test01();
test02();
+ test03();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc
new file mode 100644
index 00000000000..810e66df0c9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2013 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-options "-std=gnu++11" }
+
+#include <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::vector<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { T() };
+ test_type v2(std::move(v1));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ typedef uneq_allocator<T> alloc_type;
+ typedef std::vector<T, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ v1 = { T() };
+ test_type v2(std::move(v1), alloc_type(2));
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/emplace.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace.cc
new file mode 100644
index 00000000000..f44ea1f235c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace.cc
@@ -0,0 +1,51 @@
+// { dg-options " -std=gnu++11 " }
+
+// Copyright (C) 2013 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/>.
+
+// 23.3.8 class vector<bool>
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ std::vector<bool> v;
+ v.emplace_back();
+ VERIFY( v[0] == false );
+ v.emplace_back(1);
+ VERIFY( v[1] == true );
+ VERIFY( v.size() == 2 );
+}
+
+void test02()
+{
+ std::vector<bool> v;
+ auto it = v.emplace(v.cbegin());
+ VERIFY( it == v.begin() );
+ VERIFY( *it == false );
+ it = v.emplace(it, 1);
+ VERIFY( it == v.begin() );
+ VERIFY( *it == true );
+ VERIFY( v.size() == 2 );
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index b8a6621b339..35da91eb40d 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1305 }
+// { dg-error "no matching" "" { target *-*-* } 1306 }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index ec3aa5a62e8..9f025d17037 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1231 }
+// { dg-error "no matching" "" { target *-*-* } 1232 }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index 5c7d436ad34..cc178cb02d7 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1231 }
+// { dg-error "no matching" "" { target *-*-* } 1232 }
#include <vector>
#include <utility>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index 2daaf527197..ac48068929c 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1346 }
+// { dg-error "no matching" "" { target *-*-* } 1347 }
#include <vector>
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc b/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc
new file mode 100644
index 00000000000..58ece1b80f6
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2013 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/>.
+
+// 25.3.1 copy
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <algorithm>
+
+// libstdc++/58982
+
+// trivial class that is not assignable
+struct T
+{
+ T() = default;
+ ~T() = default;
+
+ T& operator=(const T&) = delete;
+};
+
+void
+test01(T* result)
+{
+ T t[1];
+ std::copy(t, t+1, result); // { dg-error "here" }
+}
+// { dg-prune-output "not assignable" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc
new file mode 100644
index 00000000000..f7dfa599388
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2013 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/>.
+
+// 25.3.1 copy
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <algorithm>
+
+// libstdc++/58982
+
+// trivial class that is not assignable
+struct T
+{
+ T() = default;
+ ~T() = default;
+
+ T& operator=(const T&) = delete;
+};
+
+void
+test01(T* result)
+{
+ T t[1];
+ std::copy_n(t, 1, result); // { dg-error "here" }
+}
+// { dg-prune-output "not assignable" }
diff --git a/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc b/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc
index 94ca7d91334..c2423bd74ca 100644
--- a/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc
+++ b/libstdc++-v3/testsuite/ext/pb_ds/example/hash_illegal_resize.cc
@@ -38,7 +38,7 @@
/**
* This example shows the case where a hash-based container object is
- * resized to a value which it cannot accomodate at runtime. Illegal
+ * resized to a value which it cannot accommodate at runtime. Illegal
* runtime resizes cause an exception.
*/
diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/testcase.h b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/testcase.h
index 6e390d23414..44e1a46bdbd 100644
--- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/testcase.h
+++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/special_functions/testcase.h
@@ -21,7 +21,7 @@
//
// These are little PODs for special function inputs and
-// expexted results for the testsuite.
+// expected results for the testsuite.
//
// 5.2.1.1 Associated Laguerre polynomials.
diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h
index ca311797bad..eaefc9394cb 100644
--- a/libstdc++-v3/testsuite/util/exception/safety.h
+++ b/libstdc++-v3/testsuite/util/exception/safety.h
@@ -1198,7 +1198,7 @@ namespace __gnu_test
try
{
// An exception while assigning might leave the container empty
- // making future attemps less relevant. So we copy it before to
+ // making future attempts less relevant. So we copy it before to
// always assign to a non empty container. It also check for copy
// constructor exception safety at the same time.
_Tp __clone(__container);
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index d569eb0712d..3dcd94e13c6 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -411,11 +411,11 @@ namespace __gnu_test
propagating_allocator&
operator=(const propagating_allocator& a) noexcept
- {
- static_assert(Propagate, "assigning propagating_allocator<T, true>");
- propagating_allocator(a).swap_base(*this);
- return *this;
- }
+ {
+ static_assert(Propagate, "assigning propagating_allocator<T, true>");
+ propagating_allocator(a).swap_base(*this);
+ return *this;
+ }
template<bool P2>
propagating_allocator&
diff --git a/libstdc++-v3/testsuite/util/testsuite_containers.h b/libstdc++-v3/testsuite/util/testsuite_containers.h
index 7e41d05ef43..e8f7e2d2d7e 100644
--- a/libstdc++-v3/testsuite/util/testsuite_containers.h
+++ b/libstdc++-v3/testsuite/util/testsuite_containers.h
@@ -255,7 +255,7 @@ template<typename _Tp>
void
linkage_check_cxx98_cxx11_erase(_Tp& container)
{
- // Crashing when exteral reference and internal reference symbols are
+ // Crashing when external reference and internal reference symbols are
// equivalently mangled but have different size return types in C++98
// and C++11 signatures.
erase_external(container); // C++98
@@ -266,7 +266,7 @@ template<typename _Tp>
void
linkage_check_cxx98_cxx11_erase_iterators(_Tp& container)
{
- // Crashing when exteral reference and internal reference symbols are
+ // Crashing when external reference and internal reference symbols are
// equivalently mangled but have different size return types in C++98
// and C++11 signatures.
erase_external_iterators(container);// C++98
diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.cc b/libstdc++-v3/testsuite/util/testsuite_hooks.cc
index 7f6a21e5203..20fedbc3fc9 100644
--- a/libstdc++-v3/testsuite/util/testsuite_hooks.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_hooks.cc
@@ -237,7 +237,7 @@ namespace __gnu_test
semaphore::semaphore()
{
#ifdef _GLIBCXX_SYSV_SEM
- // Remeber the PID for the process that created the semaphore set
+ // Remember the PID for the process that created the semaphore set
// so that only one process will destroy the set.
pid_ = getpid();